From f948a16ce22dea1b1178917c794aa5bbce4dde8d Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 25 Sep 2019 08:47:34 +0200 Subject: [PATCH 01/60] add first version of smart handles --- src/OpenMesh/Core/Mesh/SmartHandles.cc | 145 +++++++++++++++++++++++++ src/OpenMesh/Core/Mesh/SmartHandles.hh | 135 +++++++++++++++++++++++ 2 files changed, 280 insertions(+) create mode 100644 src/OpenMesh/Core/Mesh/SmartHandles.cc create mode 100644 src/OpenMesh/Core/Mesh/SmartHandles.hh diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.cc b/src/OpenMesh/Core/Mesh/SmartHandles.cc new file mode 100644 index 00000000..c25633b4 --- /dev/null +++ b/src/OpenMesh/Core/Mesh/SmartHandles.cc @@ -0,0 +1,145 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2019, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + + +//== INCLUDES ================================================================= + +#include "SmartHandles.hh" +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh +{ + +SmartHalfedgeHandle SmartVertexHandle::out() +{ + assert(mesh() != nullptr); + return make_smart(mesh()->halfedge_handle(*this), mesh()); +} + +SmartHalfedgeHandle SmartVertexHandle::halfedge() +{ + return out(); +} + +SmartHalfedgeHandle SmartVertexHandle::in() +{ + return out().opp(); +} + +SmartHalfedgeHandle SmartHalfedgeHandle::next() +{ + assert(mesh() != nullptr); + return make_smart(mesh()->next_halfedge_handle(*this), mesh()); +} + +SmartHalfedgeHandle SmartHalfedgeHandle::prev() +{ + assert(mesh() != nullptr); + return make_smart(mesh()->prev_halfedge_handle(*this), mesh()); +} + +SmartHalfedgeHandle SmartHalfedgeHandle::opp() +{ + assert(mesh() != nullptr); + return make_smart(mesh()->opposite_halfedge_handle(*this), mesh()); +} + +SmartVertexHandle SmartHalfedgeHandle::to() +{ + assert(mesh() != nullptr); + return make_smart(mesh()->to_vertex_handle(*this), mesh()); +} + +SmartVertexHandle SmartHalfedgeHandle::from() +{ + assert(mesh() != nullptr); + return make_smart(mesh()->from_vertex_handle(*this), mesh()); +} + +SmartFaceHandle SmartHalfedgeHandle::face() +{ + assert(mesh() != nullptr); + return make_smart(mesh()->face_handle(*this), mesh()); +} + +SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) +{ + assert(mesh() != nullptr); + return make_smart(mesh()->halfedge_handle(*this, _i), mesh()); +} + +SmartHalfedgeHandle SmartEdgeHandle::h0() +{ + return h(0); +} + +SmartHalfedgeHandle SmartEdgeHandle::h1() +{ + return h(1); +} + +SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) +{ + return h(_i).from(); +} + +SmartVertexHandle SmartEdgeHandle::v0() +{ + return v(0); +} + +SmartVertexHandle SmartEdgeHandle::v1() +{ + return v(1); +} + +SmartHalfedgeHandle SmartFaceHandle::halfedge() +{ + assert(mesh() != nullptr); + return make_smart(mesh()->halfedge_handle(*this), mesh()); +} + + +} + +//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh new file mode 100644 index 00000000..9f4c4c78 --- /dev/null +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -0,0 +1,135 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2019, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + + +#ifndef OPENMESH_SMARTHANDLES_HH +#define OPENMESH_SMARTHANDLES_HH + + +//== INCLUDES ================================================================= + +#include "Handles.hh" + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== FORWARD DECLARATION ====================================================== + +class PolyConnectivity; +struct SmartVertexHandle; +struct SmartHalfedgeHandle; +struct SmartEdgeHandle; +struct SmartFaceHandle; + + +//== CLASS DEFINITION ========================================================= + +class SmartBaseHandle : public BaseHandle +{ +public: + explicit SmartBaseHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : BaseHandle(_idx), mesh_(_mesh) {} + + /// Get the underlying mesh of this handle + PolyConnectivity* mesh() const { return mesh_; } + + // TODO: should operators ==, !=, < look at mesh_? + +private: + PolyConnectivity* mesh_; + +}; + +struct SmartVertexHandle : public SmartBaseHandle, VertexHandle +{ + explicit SmartVertexHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} + + SmartHalfedgeHandle out(); + SmartHalfedgeHandle halfedge(); // alias for out + SmartHalfedgeHandle in(); +}; + +struct SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle +{ + explicit SmartHalfedgeHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} + + SmartHalfedgeHandle next(); + SmartHalfedgeHandle prev(); + SmartHalfedgeHandle opp(); + SmartVertexHandle to(); + SmartVertexHandle from(); + SmartFaceHandle face(); +}; + +struct SmartEdgeHandle : public SmartBaseHandle, EdgeHandle +{ + explicit SmartEdgeHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} + + SmartHalfedgeHandle h(unsigned int _i); + SmartHalfedgeHandle h0(); + SmartHalfedgeHandle h1(); + SmartVertexHandle v(unsigned int _i); + SmartVertexHandle v0(); + SmartVertexHandle v1(); +}; + +struct SmartFaceHandle : public SmartBaseHandle, FaceHandle +{ + explicit SmartFaceHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} + + SmartHalfedgeHandle halfedge(); +}; + + +inline SmartVertexHandle make_smart(VertexHandle _vh, PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); } +inline SmartHalfedgeHandle make_smart(HalfedgeHandle _vh, PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_vh.idx(), _mesh); } +inline SmartEdgeHandle make_smart(EdgeHandle _vh, PolyConnectivity* _mesh) { return SmartEdgeHandle (_vh.idx(), _mesh); } +inline SmartFaceHandle make_smart(FaceHandle _vh, PolyConnectivity* _mesh) { return SmartFaceHandle (_vh.idx(), _mesh); } + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= + + +#endif // OPENMESH_SMARTHANDLES_HH +//============================================================================= From 04ba56511b8dbc1b2c1ab7cad5146cd0e2e4913b Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 25 Sep 2019 09:04:29 +0200 Subject: [PATCH 02/60] make smarthandle methods const --- src/OpenMesh/Core/Mesh/SmartHandles.cc | 32 +++++++++++++------------- src/OpenMesh/Core/Mesh/SmartHandles.hh | 32 +++++++++++++------------- 2 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.cc b/src/OpenMesh/Core/Mesh/SmartHandles.cc index c25633b4..6486ae4f 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.cc +++ b/src/OpenMesh/Core/Mesh/SmartHandles.cc @@ -50,90 +50,90 @@ namespace OpenMesh { -SmartHalfedgeHandle SmartVertexHandle::out() +SmartHalfedgeHandle SmartVertexHandle::out() const { assert(mesh() != nullptr); return make_smart(mesh()->halfedge_handle(*this), mesh()); } -SmartHalfedgeHandle SmartVertexHandle::halfedge() +SmartHalfedgeHandle SmartVertexHandle::halfedge() const { return out(); } -SmartHalfedgeHandle SmartVertexHandle::in() +SmartHalfedgeHandle SmartVertexHandle::in() const { return out().opp(); } -SmartHalfedgeHandle SmartHalfedgeHandle::next() +SmartHalfedgeHandle SmartHalfedgeHandle::next() const { assert(mesh() != nullptr); return make_smart(mesh()->next_halfedge_handle(*this), mesh()); } -SmartHalfedgeHandle SmartHalfedgeHandle::prev() +SmartHalfedgeHandle SmartHalfedgeHandle::prev() const { assert(mesh() != nullptr); return make_smart(mesh()->prev_halfedge_handle(*this), mesh()); } -SmartHalfedgeHandle SmartHalfedgeHandle::opp() +SmartHalfedgeHandle SmartHalfedgeHandle::opp() const { assert(mesh() != nullptr); return make_smart(mesh()->opposite_halfedge_handle(*this), mesh()); } -SmartVertexHandle SmartHalfedgeHandle::to() +SmartVertexHandle SmartHalfedgeHandle::to() const { assert(mesh() != nullptr); return make_smart(mesh()->to_vertex_handle(*this), mesh()); } -SmartVertexHandle SmartHalfedgeHandle::from() +SmartVertexHandle SmartHalfedgeHandle::from() const { assert(mesh() != nullptr); return make_smart(mesh()->from_vertex_handle(*this), mesh()); } -SmartFaceHandle SmartHalfedgeHandle::face() +SmartFaceHandle SmartHalfedgeHandle::face() const { assert(mesh() != nullptr); return make_smart(mesh()->face_handle(*this), mesh()); } -SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) +SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const { assert(mesh() != nullptr); return make_smart(mesh()->halfedge_handle(*this, _i), mesh()); } -SmartHalfedgeHandle SmartEdgeHandle::h0() +SmartHalfedgeHandle SmartEdgeHandle::h0() const { return h(0); } -SmartHalfedgeHandle SmartEdgeHandle::h1() +SmartHalfedgeHandle SmartEdgeHandle::h1() const { return h(1); } -SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) +SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) const { return h(_i).from(); } -SmartVertexHandle SmartEdgeHandle::v0() +SmartVertexHandle SmartEdgeHandle::v0() const { return v(0); } -SmartVertexHandle SmartEdgeHandle::v1() +SmartVertexHandle SmartEdgeHandle::v1() const { return v(1); } -SmartHalfedgeHandle SmartFaceHandle::halfedge() +SmartHalfedgeHandle SmartFaceHandle::halfedge() const { assert(mesh() != nullptr); return make_smart(mesh()->halfedge_handle(*this), mesh()); diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index 9f4c4c78..2b63af46 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -83,40 +83,40 @@ struct SmartVertexHandle : public SmartBaseHandle, VertexHandle { explicit SmartVertexHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} - SmartHalfedgeHandle out(); - SmartHalfedgeHandle halfedge(); // alias for out - SmartHalfedgeHandle in(); + SmartHalfedgeHandle out() const; + SmartHalfedgeHandle halfedge() const; // alias for out + SmartHalfedgeHandle in() const; }; struct SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle { explicit SmartHalfedgeHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} - SmartHalfedgeHandle next(); - SmartHalfedgeHandle prev(); - SmartHalfedgeHandle opp(); - SmartVertexHandle to(); - SmartVertexHandle from(); - SmartFaceHandle face(); + SmartHalfedgeHandle next() const; + SmartHalfedgeHandle prev() const; + SmartHalfedgeHandle opp() const; + SmartVertexHandle to() const; + SmartVertexHandle from() const; + SmartFaceHandle face() const; }; struct SmartEdgeHandle : public SmartBaseHandle, EdgeHandle { explicit SmartEdgeHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} - SmartHalfedgeHandle h(unsigned int _i); - SmartHalfedgeHandle h0(); - SmartHalfedgeHandle h1(); - SmartVertexHandle v(unsigned int _i); - SmartVertexHandle v0(); - SmartVertexHandle v1(); + SmartHalfedgeHandle h(unsigned int _i) const; + SmartHalfedgeHandle h0() const; + SmartHalfedgeHandle h1() const; + SmartVertexHandle v(unsigned int _i) const; + SmartVertexHandle v0() const; + SmartVertexHandle v1() const; }; struct SmartFaceHandle : public SmartBaseHandle, FaceHandle { explicit SmartFaceHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} - SmartHalfedgeHandle halfedge(); + SmartHalfedgeHandle halfedge() const; }; From 844de4145c994b2cd96d61d3f24997ee43463300 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 25 Sep 2019 09:52:18 +0200 Subject: [PATCH 03/60] avoid diamond inheritance and add range and convenience functions --- src/OpenMesh/Core/Mesh/SmartHandles.cc | 110 ++++++++++++++++++++++++- src/OpenMesh/Core/Mesh/SmartHandles.hh | 83 +++++++++++++------ 2 files changed, 164 insertions(+), 29 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.cc b/src/OpenMesh/Core/Mesh/SmartHandles.cc index 6486ae4f..308224dc 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.cc +++ b/src/OpenMesh/Core/Mesh/SmartHandles.cc @@ -66,6 +66,54 @@ SmartHalfedgeHandle SmartVertexHandle::in() const return out().opp(); } +PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->vf_range(*this); +} + +PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->ve_range(*this); +} + +PolyConnectivity::ConstVertexVertexRange SmartVertexHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->vv_range(*this); +} + +PolyConnectivity::ConstVertexIHalfedgeRange SmartVertexHandle::incoming_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->vih_range(*this); +} + +PolyConnectivity::ConstVertexOHalfedgeRange SmartVertexHandle::outgoing_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->voh_range(*this); +} + +uint SmartVertexHandle::valence() const +{ + assert(mesh() != nullptr); + return mesh()->valence(*this); +} + +bool SmartVertexHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + +bool SmartVertexHandle::is_manifold() const +{ + assert(mesh() != nullptr); + return mesh()->is_manifold(*this); +} + SmartHalfedgeHandle SmartHalfedgeHandle::next() const { assert(mesh() != nullptr); @@ -102,12 +150,23 @@ SmartFaceHandle SmartHalfedgeHandle::face() const return make_smart(mesh()->face_handle(*this), mesh()); } -SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const +bool SmartHalfedgeHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + +SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i) const { assert(mesh() != nullptr); return make_smart(mesh()->halfedge_handle(*this, _i), mesh()); } +SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const +{ + return halfedge(_i); +} + SmartHalfedgeHandle SmartEdgeHandle::h0() const { return h(0); @@ -118,9 +177,14 @@ SmartHalfedgeHandle SmartEdgeHandle::h1() const return h(1); } +SmartVertexHandle SmartEdgeHandle::vertex(unsigned int _i) const +{ + return halfedge(_i).from(); +} + SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) const { - return h(_i).from(); + return vertex(_i); } SmartVertexHandle SmartEdgeHandle::v0() const @@ -133,12 +197,54 @@ SmartVertexHandle SmartEdgeHandle::v1() const return v(1); } +bool SmartEdgeHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + SmartHalfedgeHandle SmartFaceHandle::halfedge() const { assert(mesh() != nullptr); return make_smart(mesh()->halfedge_handle(*this), mesh()); } +PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->fv_range(*this); +} + +PolyConnectivity::ConstFaceHalfedgeRange SmartFaceHandle::halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->fh_range(*this); +} + +PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->fe_range(*this); +} + +PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->ff_range(*this); +} + +uint SmartFaceHandle::valence() const +{ + assert(mesh() != nullptr); + return mesh()->valence(*this); +} + +bool SmartFaceHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + } diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index 2b63af46..f2cfeb76 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -47,6 +47,7 @@ //== INCLUDES ================================================================= #include "Handles.hh" +#include //== NAMESPACES =============================================================== @@ -55,7 +56,6 @@ namespace OpenMesh { //== FORWARD DECLARATION ====================================================== -class PolyConnectivity; struct SmartVertexHandle; struct SmartHalfedgeHandle; struct SmartEdgeHandle; @@ -64,66 +64,95 @@ struct SmartFaceHandle; //== CLASS DEFINITION ========================================================= -class SmartBaseHandle : public BaseHandle +class SmartBaseHandle { public: - explicit SmartBaseHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : BaseHandle(_idx), mesh_(_mesh) {} + explicit SmartBaseHandle(const PolyConnectivity* _mesh = nullptr) : mesh_(_mesh) {} /// Get the underlying mesh of this handle - PolyConnectivity* mesh() const { return mesh_; } + const PolyConnectivity* mesh() const { return mesh_; } // TODO: should operators ==, !=, < look at mesh_? private: - PolyConnectivity* mesh_; + const PolyConnectivity* mesh_; }; struct SmartVertexHandle : public SmartBaseHandle, VertexHandle { - explicit SmartVertexHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} + explicit SmartVertexHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), VertexHandle(_idx) {} - SmartHalfedgeHandle out() const; + SmartHalfedgeHandle out() const; SmartHalfedgeHandle halfedge() const; // alias for out - SmartHalfedgeHandle in() const; + SmartHalfedgeHandle in() const; + + PolyConnectivity::ConstVertexFaceRange faces() const; + PolyConnectivity::ConstVertexEdgeRange edges() const; + PolyConnectivity::ConstVertexVertexRange vertices() const; + PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges() const; + PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const; + + uint valence() const; + bool is_boundary() const; + bool is_manifold() const; }; struct SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle { - explicit SmartHalfedgeHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} + explicit SmartHalfedgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), HalfedgeHandle(_idx) {} - SmartHalfedgeHandle next() const; - SmartHalfedgeHandle prev() const; - SmartHalfedgeHandle opp() const; - SmartVertexHandle to() const; - SmartVertexHandle from() const; - SmartFaceHandle face() const; + SmartHalfedgeHandle next() const; + SmartHalfedgeHandle prev() const; + SmartHalfedgeHandle opp() const; + SmartVertexHandle to() const; + SmartVertexHandle from() const; + SmartFaceHandle face() const; + + bool is_boundary() const; }; struct SmartEdgeHandle : public SmartBaseHandle, EdgeHandle { - explicit SmartEdgeHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} + explicit SmartEdgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), EdgeHandle(_idx) {} - SmartHalfedgeHandle h(unsigned int _i) const; - SmartHalfedgeHandle h0() const; - SmartHalfedgeHandle h1() const; - SmartVertexHandle v(unsigned int _i) const; - SmartVertexHandle v0() const; - SmartVertexHandle v1() const; + SmartHalfedgeHandle halfedge(unsigned int _i) const; + SmartHalfedgeHandle h(unsigned int _i) const; + SmartHalfedgeHandle h0() const; + SmartHalfedgeHandle h1() const; + SmartVertexHandle vertex(unsigned int _i) const; + SmartVertexHandle v(unsigned int _i) const; + SmartVertexHandle v0() const; + SmartVertexHandle v1() const; + + bool is_boundary() const; }; struct SmartFaceHandle : public SmartBaseHandle, FaceHandle { - explicit SmartFaceHandle(int _idx=-1, PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_idx, _mesh) {} + explicit SmartFaceHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), FaceHandle(_idx) {} SmartHalfedgeHandle halfedge() const; + + PolyConnectivity::ConstFaceVertexRange vertices() const; + PolyConnectivity::ConstFaceHalfedgeRange halfedges() const; + PolyConnectivity::ConstFaceEdgeRange edges() const; + PolyConnectivity::ConstFaceFaceRange faces() const; + + uint valence() const; + bool is_boundary() const; }; -inline SmartVertexHandle make_smart(VertexHandle _vh, PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); } -inline SmartHalfedgeHandle make_smart(HalfedgeHandle _vh, PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_vh.idx(), _mesh); } -inline SmartEdgeHandle make_smart(EdgeHandle _vh, PolyConnectivity* _mesh) { return SmartEdgeHandle (_vh.idx(), _mesh); } -inline SmartFaceHandle make_smart(FaceHandle _vh, PolyConnectivity* _mesh) { return SmartFaceHandle (_vh.idx(), _mesh); } +inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); } +inline SmartHalfedgeHandle make_smart(HalfedgeHandle _vh, const PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_vh.idx(), _mesh); } +inline SmartEdgeHandle make_smart(EdgeHandle _vh, const PolyConnectivity* _mesh) { return SmartEdgeHandle (_vh.idx(), _mesh); } +inline SmartFaceHandle make_smart(FaceHandle _vh, const PolyConnectivity* _mesh) { return SmartFaceHandle (_vh.idx(), _mesh); } + +inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity& _mesh) { return SmartVertexHandle (_vh.idx(), &_mesh); } +inline SmartHalfedgeHandle make_smart(HalfedgeHandle _vh, const PolyConnectivity& _mesh) { return SmartHalfedgeHandle(_vh.idx(), &_mesh); } +inline SmartEdgeHandle make_smart(EdgeHandle _vh, const PolyConnectivity& _mesh) { return SmartEdgeHandle (_vh.idx(), &_mesh); } +inline SmartFaceHandle make_smart(FaceHandle _vh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_vh.idx(), &_mesh); } //============================================================================= From 92cdc795c7ac11ab56fbeded9fd021448d708f2e Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 25 Sep 2019 12:19:30 +0200 Subject: [PATCH 04/60] add unit tests for smart handles --- src/OpenMesh/Core/Mesh/SmartHandles.hh | 44 +-- src/Unittests/unittests_smart_handles.cc | 324 +++++++++++++++++++++++ 2 files changed, 346 insertions(+), 22 deletions(-) create mode 100644 src/Unittests/unittests_smart_handles.cc diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index f2cfeb76..ccad1203 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -102,12 +102,12 @@ struct SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle { explicit SmartHalfedgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), HalfedgeHandle(_idx) {} - SmartHalfedgeHandle next() const; - SmartHalfedgeHandle prev() const; - SmartHalfedgeHandle opp() const; - SmartVertexHandle to() const; - SmartVertexHandle from() const; - SmartFaceHandle face() const; + SmartHalfedgeHandle next() const; + SmartHalfedgeHandle prev() const; + SmartHalfedgeHandle opp() const; + SmartVertexHandle to() const; + SmartVertexHandle from() const; + SmartFaceHandle face() const; bool is_boundary() const; }; @@ -116,14 +116,14 @@ struct SmartEdgeHandle : public SmartBaseHandle, EdgeHandle { explicit SmartEdgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), EdgeHandle(_idx) {} - SmartHalfedgeHandle halfedge(unsigned int _i) const; - SmartHalfedgeHandle h(unsigned int _i) const; - SmartHalfedgeHandle h0() const; - SmartHalfedgeHandle h1() const; - SmartVertexHandle vertex(unsigned int _i) const; - SmartVertexHandle v(unsigned int _i) const; - SmartVertexHandle v0() const; - SmartVertexHandle v1() const; + SmartHalfedgeHandle halfedge(unsigned int _i) const; + SmartHalfedgeHandle h(unsigned int _i) const; + SmartHalfedgeHandle h0() const; + SmartHalfedgeHandle h1() const; + SmartVertexHandle vertex(unsigned int _i) const; + SmartVertexHandle v(unsigned int _i) const; + SmartVertexHandle v0() const; + SmartVertexHandle v1() const; bool is_boundary() const; }; @@ -144,15 +144,15 @@ struct SmartFaceHandle : public SmartBaseHandle, FaceHandle }; -inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); } -inline SmartHalfedgeHandle make_smart(HalfedgeHandle _vh, const PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_vh.idx(), _mesh); } -inline SmartEdgeHandle make_smart(EdgeHandle _vh, const PolyConnectivity* _mesh) { return SmartEdgeHandle (_vh.idx(), _mesh); } -inline SmartFaceHandle make_smart(FaceHandle _vh, const PolyConnectivity* _mesh) { return SmartFaceHandle (_vh.idx(), _mesh); } +inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); } +inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_hh.idx(), _mesh); } +inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity* _mesh) { return SmartEdgeHandle (_eh.idx(), _mesh); } +inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity* _mesh) { return SmartFaceHandle (_fh.idx(), _mesh); } -inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity& _mesh) { return SmartVertexHandle (_vh.idx(), &_mesh); } -inline SmartHalfedgeHandle make_smart(HalfedgeHandle _vh, const PolyConnectivity& _mesh) { return SmartHalfedgeHandle(_vh.idx(), &_mesh); } -inline SmartEdgeHandle make_smart(EdgeHandle _vh, const PolyConnectivity& _mesh) { return SmartEdgeHandle (_vh.idx(), &_mesh); } -inline SmartFaceHandle make_smart(FaceHandle _vh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_vh.idx(), &_mesh); } +inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity& _mesh) { return SmartVertexHandle (_vh.idx(), &_mesh); } +inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity& _mesh) { return SmartHalfedgeHandle(_hh.idx(), &_mesh); } +inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity& _mesh) { return SmartEdgeHandle (_eh.idx(), &_mesh); } +inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); } //============================================================================= diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc new file mode 100644 index 00000000..dd29ccf5 --- /dev/null +++ b/src/Unittests/unittests_smart_handles.cc @@ -0,0 +1,324 @@ +#include +#include + +#include + +#include +#include + +namespace { + +class OpenMeshSmartHandles : public OpenMeshBase { + +protected: + + // This function is called before each test is run + virtual void SetUp() { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[8]; + vhandle[0] = mesh_.add_vertex(Mesh::Point(-1, -1, 1)); + vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, -1, 1)); + vhandle[2] = mesh_.add_vertex(Mesh::Point( 1, 1, 1)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(-1, 1, 1)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, -1, -1)); + vhandle[5] = mesh_.add_vertex(Mesh::Point( 1, -1, -1)); + vhandle[6] = mesh_.add_vertex(Mesh::Point( 1, 1, -1)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(-1, 1, -1)); + + // Add six faces to form a cube + std::vector face_vhandles; + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + + // Test setup: + // + // + // 3 ======== 2 + // / /| + // / / | z + // 0 ======== 1 | | + // | | | | y + // | 7 | 6 | / + // | | / | / + // | |/ |/ + // 4 ======== 5 -------> x + // + + // Check setup + EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges"; + EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges"; + EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces"; + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + + mesh_.clear(); + } + + // Member already defined in OpenMeshBase + //Mesh mesh_; +}; + +/* + * ==================================================================== + * Define tests below + * ==================================================================== + */ + + + +/* Test if navigation operations on smart handles yield the expected element + */ +TEST_F(OpenMeshSmartHandles, SimpleNavigation) +{ + for (auto vh : mesh_.vertices()) + { + auto svh = OpenMesh::make_smart(vh, mesh_); + EXPECT_EQ(mesh_.halfedge_handle(vh), svh.halfedge()) << "outgoing halfedge of vertex does not match"; + } + + for (auto heh : mesh_.halfedges()) + { + auto sheh = OpenMesh::make_smart(heh, mesh_); + EXPECT_EQ(mesh_.next_halfedge_handle(heh), sheh.next()) << "next halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.prev_halfedge_handle(heh), sheh.prev()) << "prevt halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.opposite_halfedge_handle(heh), sheh.opp()) << "opposite halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.to_vertex_handle(heh), sheh.to()) << "to vertex handle of halfedge does not match"; + EXPECT_EQ(mesh_.from_vertex_handle(heh), sheh.from()) << "from vertex handle of halfedge does not match"; + EXPECT_EQ(mesh_.face_handle(heh), sheh.face()) << "face handle of halfedge does not match"; + } + + for (auto eh : mesh_.edges()) + { + auto seh = OpenMesh::make_smart(eh, mesh_); + EXPECT_EQ(mesh_.halfedge_handle(eh, 0), seh.h0()) << "halfedge 0 of edge does not match"; + EXPECT_EQ(mesh_.halfedge_handle(eh, 1), seh.h1()) << "halfedge 1 of edge does not match"; + EXPECT_EQ(mesh_.from_vertex_handle(mesh_.halfedge_handle(eh, 0)), seh.v0()) << "first vertex of edge does not match"; + EXPECT_EQ(mesh_.to_vertex_handle (mesh_.halfedge_handle(eh, 0)), seh.v1()) << "second vertex of edge does not match"; + } + + for (auto fh : mesh_.faces()) + { + auto sfh = OpenMesh::make_smart(fh, mesh_); + EXPECT_EQ(mesh_.halfedge_handle(fh), sfh.halfedge()) << "halfedge of face does not match"; + } +} + + +/* Test if ranges yield the same elements when using smart handles + */ +TEST_F(OpenMeshSmartHandles, SimpleRanges) +{ + for (auto vh : mesh_.vertices()) + { + auto svh = OpenMesh::make_smart(vh, mesh_); + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + handles0.push_back(h); + for (auto h : svh.vertices()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "vertex range of vertex does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.voh_range(vh)) + handles0.push_back(h); + for (auto h : svh.outgoing_halfedges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "outgoing halfedge range of vertex does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vih_range(vh)) + handles0.push_back(h); + for (auto h : svh.incoming_halfedges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "incoming halfedge range of vertex does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.ve_range(vh)) + handles0.push_back(h); + for (auto h : svh.edges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "edge range of vertex does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vf_range(vh)) + handles0.push_back(h); + for (auto h : svh.faces()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "face range of vertex does not match"; + } + } + + for (auto fh : mesh_.faces()) + { + auto sfh = OpenMesh::make_smart(fh, mesh_); + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.fv_range(fh)) + handles0.push_back(h); + for (auto h : sfh.vertices()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "vertex range of face does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.fh_range(fh)) + handles0.push_back(h); + for (auto h : sfh.halfedges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "halfedge range of face does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.fe_range(fh)) + handles0.push_back(h); + for (auto h : sfh.edges()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "edge range of face does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.ff_range(fh)) + handles0.push_back(h); + for (auto h : sfh.faces()) + handles1.push_back(h); + EXPECT_EQ(handles0, handles1) << "face range of face does not match"; + } + } +} + + +/* Test a chain of navigation on a cube + */ +TEST_F(OpenMeshSmartHandles, ComplicatedNavigtaion) +{ + for (auto vh : mesh_.vertices()) + { + auto svh = OpenMesh::make_smart(vh, mesh_); + EXPECT_EQ(mesh_.next_halfedge_handle( + mesh_.opposite_halfedge_handle( + mesh_.halfedge_handle(vh))), + svh.out().opp().next()); + EXPECT_EQ(mesh_.prev_halfedge_handle( + mesh_.prev_halfedge_handle( + mesh_.opposite_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.halfedge_handle(vh)))))), + svh.out().next().next().opp().prev().prev()); + EXPECT_EQ(mesh_.face_handle( + mesh_.opposite_halfedge_handle( + mesh_.halfedge_handle( + mesh_.face_handle( + mesh_.opposite_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.halfedge_handle(vh))))))), + svh.out().next().opp().face().halfedge().opp().face()); + } +} + + +} From 832a40d63010ef94753d6cb722ad702f6fba2f22 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 25 Sep 2019 13:11:46 +0200 Subject: [PATCH 05/60] add performance test for smart handles --- src/Unittests/unittests_smart_handles.cc | 47 ++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc index dd29ccf5..fc7d4978 100644 --- a/src/Unittests/unittests_smart_handles.cc +++ b/src/Unittests/unittests_smart_handles.cc @@ -321,4 +321,51 @@ TEST_F(OpenMeshSmartHandles, ComplicatedNavigtaion) } +/* Test performance of smart handles + */ +TEST_F(OpenMeshSmartHandles, Performance) +{ + int n_tests = 10000000; + + auto t_before_old = std::chrono::high_resolution_clock::now(); + + std::vector halfedges0; + for (int i = 0; i < n_tests; ++i) + { + for (auto vh : mesh_.vertices()) + { + auto heh = mesh_.prev_halfedge_handle( + mesh_.prev_halfedge_handle( + mesh_.opposite_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.next_halfedge_handle( + mesh_.halfedge_handle(vh)))))); + if (i == 0) + halfedges0.push_back(heh); + } + } + + auto t_after_old = std::chrono::high_resolution_clock::now(); + + std::vector halfedges1; + for (int i = 0; i < n_tests; ++i) + { + for (auto vh : mesh_.vertices()) + { + auto svh = OpenMesh::make_smart(vh, mesh_); + auto heh = svh.out().next().next().opp().prev().prev(); + if (i == 0) + halfedges1.push_back(heh); + } + } + + auto t_after_new = std::chrono::high_resolution_clock::now(); + + std::cout << "Conventional navigation took " << std::chrono::duration_cast(t_after_old-t_before_old).count() << "ms" << std::endl; + std::cout << "SmartHandle navigation took " << std::chrono::duration_cast(t_after_new-t_after_old ).count() << "ms" << std::endl; + + EXPECT_EQ(halfedges0, halfedges1) << "halfedges do not match"; + +} + } From 010a8a0b41f0f0ebaf71c27ac12025ba9bceca2c Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 25 Sep 2019 13:12:31 +0200 Subject: [PATCH 06/60] inline smart handle methods for better performance --- src/OpenMesh/Core/Mesh/SmartHandles.cc | 251 ------------------------- src/OpenMesh/Core/Mesh/SmartHandles.hh | 198 +++++++++++++++++++ 2 files changed, 198 insertions(+), 251 deletions(-) delete mode 100644 src/OpenMesh/Core/Mesh/SmartHandles.cc diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.cc b/src/OpenMesh/Core/Mesh/SmartHandles.cc deleted file mode 100644 index 308224dc..00000000 --- a/src/OpenMesh/Core/Mesh/SmartHandles.cc +++ /dev/null @@ -1,251 +0,0 @@ -/* ========================================================================= * - * * - * OpenMesh * - * Copyright (c) 2001-2019, RWTH-Aachen University * - * Department of Computer Graphics and Multimedia * - * All rights reserved. * - * www.openmesh.org * - * * - *---------------------------------------------------------------------------* - * This file is part of OpenMesh. * - *---------------------------------------------------------------------------* - * * - * Redistribution and use in source and binary forms, with or without * - * modification, are permitted provided that the following conditions * - * are met: * - * * - * 1. Redistributions of source code must retain the above copyright notice, * - * this list of conditions and the following disclaimer. * - * * - * 2. Redistributions in binary form must reproduce the above copyright * - * notice, this list of conditions and the following disclaimer in the * - * documentation and/or other materials provided with the distribution. * - * * - * 3. Neither the name of the copyright holder nor the names of its * - * contributors may be used to endorse or promote products derived from * - * this software without specific prior written permission. * - * * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * - * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * - * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * * - * ========================================================================= */ - - -//== INCLUDES ================================================================= - -#include "SmartHandles.hh" -#include - -//== NAMESPACES =============================================================== - -namespace OpenMesh -{ - -SmartHalfedgeHandle SmartVertexHandle::out() const -{ - assert(mesh() != nullptr); - return make_smart(mesh()->halfedge_handle(*this), mesh()); -} - -SmartHalfedgeHandle SmartVertexHandle::halfedge() const -{ - return out(); -} - -SmartHalfedgeHandle SmartVertexHandle::in() const -{ - return out().opp(); -} - -PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const -{ - assert(mesh() != nullptr); - return mesh()->vf_range(*this); -} - -PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const -{ - assert(mesh() != nullptr); - return mesh()->ve_range(*this); -} - -PolyConnectivity::ConstVertexVertexRange SmartVertexHandle::vertices() const -{ - assert(mesh() != nullptr); - return mesh()->vv_range(*this); -} - -PolyConnectivity::ConstVertexIHalfedgeRange SmartVertexHandle::incoming_halfedges() const -{ - assert(mesh() != nullptr); - return mesh()->vih_range(*this); -} - -PolyConnectivity::ConstVertexOHalfedgeRange SmartVertexHandle::outgoing_halfedges() const -{ - assert(mesh() != nullptr); - return mesh()->voh_range(*this); -} - -uint SmartVertexHandle::valence() const -{ - assert(mesh() != nullptr); - return mesh()->valence(*this); -} - -bool SmartVertexHandle::is_boundary() const -{ - assert(mesh() != nullptr); - return mesh()->is_boundary(*this); -} - -bool SmartVertexHandle::is_manifold() const -{ - assert(mesh() != nullptr); - return mesh()->is_manifold(*this); -} - -SmartHalfedgeHandle SmartHalfedgeHandle::next() const -{ - assert(mesh() != nullptr); - return make_smart(mesh()->next_halfedge_handle(*this), mesh()); -} - -SmartHalfedgeHandle SmartHalfedgeHandle::prev() const -{ - assert(mesh() != nullptr); - return make_smart(mesh()->prev_halfedge_handle(*this), mesh()); -} - -SmartHalfedgeHandle SmartHalfedgeHandle::opp() const -{ - assert(mesh() != nullptr); - return make_smart(mesh()->opposite_halfedge_handle(*this), mesh()); -} - -SmartVertexHandle SmartHalfedgeHandle::to() const -{ - assert(mesh() != nullptr); - return make_smart(mesh()->to_vertex_handle(*this), mesh()); -} - -SmartVertexHandle SmartHalfedgeHandle::from() const -{ - assert(mesh() != nullptr); - return make_smart(mesh()->from_vertex_handle(*this), mesh()); -} - -SmartFaceHandle SmartHalfedgeHandle::face() const -{ - assert(mesh() != nullptr); - return make_smart(mesh()->face_handle(*this), mesh()); -} - -bool SmartHalfedgeHandle::is_boundary() const -{ - assert(mesh() != nullptr); - return mesh()->is_boundary(*this); -} - -SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i) const -{ - assert(mesh() != nullptr); - return make_smart(mesh()->halfedge_handle(*this, _i), mesh()); -} - -SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const -{ - return halfedge(_i); -} - -SmartHalfedgeHandle SmartEdgeHandle::h0() const -{ - return h(0); -} - -SmartHalfedgeHandle SmartEdgeHandle::h1() const -{ - return h(1); -} - -SmartVertexHandle SmartEdgeHandle::vertex(unsigned int _i) const -{ - return halfedge(_i).from(); -} - -SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) const -{ - return vertex(_i); -} - -SmartVertexHandle SmartEdgeHandle::v0() const -{ - return v(0); -} - -SmartVertexHandle SmartEdgeHandle::v1() const -{ - return v(1); -} - -bool SmartEdgeHandle::is_boundary() const -{ - assert(mesh() != nullptr); - return mesh()->is_boundary(*this); -} - -SmartHalfedgeHandle SmartFaceHandle::halfedge() const -{ - assert(mesh() != nullptr); - return make_smart(mesh()->halfedge_handle(*this), mesh()); -} - -PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const -{ - assert(mesh() != nullptr); - return mesh()->fv_range(*this); -} - -PolyConnectivity::ConstFaceHalfedgeRange SmartFaceHandle::halfedges() const -{ - assert(mesh() != nullptr); - return mesh()->fh_range(*this); -} - -PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const -{ - assert(mesh() != nullptr); - return mesh()->fe_range(*this); -} - -PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const -{ - assert(mesh() != nullptr); - return mesh()->ff_range(*this); -} - -uint SmartFaceHandle::valence() const -{ - assert(mesh() != nullptr); - return mesh()->valence(*this); -} - -bool SmartFaceHandle::is_boundary() const -{ - assert(mesh() != nullptr); - return mesh()->is_boundary(*this); -} - - -} - -//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index ccad1203..8f82cbc6 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -155,6 +155,204 @@ inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); } + +inline SmartHalfedgeHandle SmartVertexHandle::out() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->halfedge_handle(*this), mesh()); +} + +inline SmartHalfedgeHandle SmartVertexHandle::halfedge() const +{ + return out(); +} + +inline SmartHalfedgeHandle SmartVertexHandle::in() const +{ + return out().opp(); +} + +inline PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->vf_range(*this); +} + +inline PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->ve_range(*this); +} + +inline PolyConnectivity::ConstVertexVertexRange SmartVertexHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->vv_range(*this); +} + +inline PolyConnectivity::ConstVertexIHalfedgeRange SmartVertexHandle::incoming_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->vih_range(*this); +} + +inline PolyConnectivity::ConstVertexOHalfedgeRange SmartVertexHandle::outgoing_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->voh_range(*this); +} + +inline uint SmartVertexHandle::valence() const +{ + assert(mesh() != nullptr); + return mesh()->valence(*this); +} + +inline bool SmartVertexHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + +inline bool SmartVertexHandle::is_manifold() const +{ + assert(mesh() != nullptr); + return mesh()->is_manifold(*this); +} + +inline SmartHalfedgeHandle SmartHalfedgeHandle::next() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->next_halfedge_handle(*this), mesh()); +} + +inline SmartHalfedgeHandle SmartHalfedgeHandle::prev() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->prev_halfedge_handle(*this), mesh()); +} + +inline SmartHalfedgeHandle SmartHalfedgeHandle::opp() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->opposite_halfedge_handle(*this), mesh()); +} + +inline SmartVertexHandle SmartHalfedgeHandle::to() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->to_vertex_handle(*this), mesh()); +} + +inline SmartVertexHandle SmartHalfedgeHandle::from() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->from_vertex_handle(*this), mesh()); +} + +inline SmartFaceHandle SmartHalfedgeHandle::face() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->face_handle(*this), mesh()); +} + +inline bool SmartHalfedgeHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + +inline SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i) const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->halfedge_handle(*this, _i), mesh()); +} + +inline SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const +{ + return halfedge(_i); +} + +inline SmartHalfedgeHandle SmartEdgeHandle::h0() const +{ + return h(0); +} + +inline SmartHalfedgeHandle SmartEdgeHandle::h1() const +{ + return h(1); +} + +inline SmartVertexHandle SmartEdgeHandle::vertex(unsigned int _i) const +{ + return halfedge(_i).from(); +} + +inline SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) const +{ + return vertex(_i); +} + +inline SmartVertexHandle SmartEdgeHandle::v0() const +{ + return v(0); +} + +inline SmartVertexHandle SmartEdgeHandle::v1() const +{ + return v(1); +} + +inline bool SmartEdgeHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + +inline SmartHalfedgeHandle SmartFaceHandle::halfedge() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->halfedge_handle(*this), mesh()); +} + +inline PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->fv_range(*this); +} + +inline PolyConnectivity::ConstFaceHalfedgeRange SmartFaceHandle::halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->fh_range(*this); +} + +inline PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->fe_range(*this); +} + +inline PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->ff_range(*this); +} + +inline uint SmartFaceHandle::valence() const +{ + assert(mesh() != nullptr); + return mesh()->valence(*this); +} + +inline bool SmartFaceHandle::is_boundary() const +{ + assert(mesh() != nullptr); + return mesh()->is_boundary(*this); +} + + + //============================================================================= } // namespace OpenMesh //============================================================================= From 89f0dcbb51e748b510444d876b02c97eeccb7b75 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 25 Sep 2019 13:21:17 +0200 Subject: [PATCH 07/60] add documentation --- src/OpenMesh/Core/Mesh/SmartHandles.hh | 44 ++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index 8f82cbc6..5c671185 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -64,6 +64,7 @@ struct SmartFaceHandle; //== CLASS DEFINITION ========================================================= +/// Base class for all smart handle types class SmartBaseHandle { public: @@ -79,22 +80,34 @@ private: }; +/// Smart version of VertexHandle contains a pointer to the corresponding mesh and allows easier access to navigation methods struct SmartVertexHandle : public SmartBaseHandle, VertexHandle { explicit SmartVertexHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), VertexHandle(_idx) {} + /// Returns an outgoing halfedge SmartHalfedgeHandle out() const; + /// Returns an outgoing halfedge SmartHalfedgeHandle halfedge() const; // alias for out + /// Returns an incoming halfedge SmartHalfedgeHandle in() const; + /// Returns a range of faces incident to the vertex (PolyConnectivity::vf_range()) PolyConnectivity::ConstVertexFaceRange faces() const; + /// Returns a range of edges incident to the vertex (PolyConnectivity::ve_range()) PolyConnectivity::ConstVertexEdgeRange edges() const; + /// Returns a range of vertices adjacent to the vertex (PolyConnectivity::vv_range()) PolyConnectivity::ConstVertexVertexRange vertices() const; + /// Returns a range of outgoing halfedges incident to the vertex (PolyConnectivity::voh_range()) PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges() const; + /// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::vih_range()) PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const; + /// Returns valence of the vertex uint valence() const; + /// Returns true iff the vertex is incident to a boundary halfedge bool is_boundary() const; + /// Returns true iff (the mesh at) the vertex is two-manifold ? bool is_manifold() const; }; @@ -102,13 +115,20 @@ struct SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle { explicit SmartHalfedgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), HalfedgeHandle(_idx) {} + /// Returns next halfedge handle SmartHalfedgeHandle next() const; + /// Returns previous halfedge handle SmartHalfedgeHandle prev() const; + /// Returns opposite halfedge handle SmartHalfedgeHandle opp() const; + /// Returns vertex pointed to by halfedge SmartVertexHandle to() const; + /// Returns vertex at start of halfedge SmartVertexHandle from() const; + /// Returns incident face of halfedge SmartFaceHandle face() const; + /// Returns true iff the halfedge is on the boundary (i.e. it has no corresponding face) bool is_boundary() const; }; @@ -116,15 +136,24 @@ struct SmartEdgeHandle : public SmartBaseHandle, EdgeHandle { explicit SmartEdgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), EdgeHandle(_idx) {} + /// Returns one of the two halfedges of the edge SmartHalfedgeHandle halfedge(unsigned int _i) const; + /// Shorthand for halfedge() SmartHalfedgeHandle h(unsigned int _i) const; + /// Shorthand for halfedge(0) SmartHalfedgeHandle h0() const; + /// Shorthand for halfedge(1) SmartHalfedgeHandle h1() const; + /// Returns one of the two incident vertices of the edge SmartVertexHandle vertex(unsigned int _i) const; + /// Shorthand for vertex() SmartVertexHandle v(unsigned int _i) const; + /// Shorthand for vertex(0) SmartVertexHandle v0() const; + /// Shorthand for vertex(1) SmartVertexHandle v1() const; + /// Returns true iff the edge lies on the boundary (i.e. one of the halfedges is boundary) bool is_boundary() const; }; @@ -132,26 +161,41 @@ struct SmartFaceHandle : public SmartBaseHandle, FaceHandle { explicit SmartFaceHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), FaceHandle(_idx) {} + /// Returns one of the halfedges of the face SmartHalfedgeHandle halfedge() const; + /// Returns a range of vertices incident to the face (PolyConnectivity::fv_range()) PolyConnectivity::ConstFaceVertexRange vertices() const; + /// Returns a range of halfedges of the face (PolyConnectivity::fh_range()) PolyConnectivity::ConstFaceHalfedgeRange halfedges() const; + /// Returns a range of edges of the face (PolyConnectivity::fv_range()) PolyConnectivity::ConstFaceEdgeRange edges() const; + /// Returns a range adjacent faces of the face (PolyConnectivity::ff_range()) PolyConnectivity::ConstFaceFaceRange faces() const; + /// Returns the valence of the face uint valence() const; + /// Returns true iff the face lies at the boundary (i.e. one of the edges is boundary) bool is_boundary() const; }; +/// Creats a SmartVertexHandle from a VertexHandle and a Mesh inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); } +/// Creats a SmartHalfedgeHandle from a HalfedgeHandle and a Mesh inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_hh.idx(), _mesh); } +/// Creats a SmartEdgeHandle from an EdgeHandle and a Mesh inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity* _mesh) { return SmartEdgeHandle (_eh.idx(), _mesh); } +/// Creats a SmartFaceHandle from a FaceHandle and a Mesh inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity* _mesh) { return SmartFaceHandle (_fh.idx(), _mesh); } +/// Creats a SmartVertexHandle from a VertexHandle and a Mesh inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity& _mesh) { return SmartVertexHandle (_vh.idx(), &_mesh); } +/// Creats a SmartHalfedgeHandle from a HalfedgeHandle and a Mesh inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity& _mesh) { return SmartHalfedgeHandle(_hh.idx(), &_mesh); } +/// Creats a SmartEdgeHandle from an EdgeHandle and a Mesh inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity& _mesh) { return SmartEdgeHandle (_eh.idx(), &_mesh); } +/// Creats a SmartFaceHandle from a FaceHandle and a Mesh inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); } From 253c9b6afa272924bc1cd7f80bbf54bed9e74e12 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 26 Sep 2019 11:14:31 +0200 Subject: [PATCH 08/60] let iterators return smart handles --- src/OpenMesh/Core/Mesh/IteratorsT.hh | 33 ++++++------ src/OpenMesh/Core/Mesh/PolyConnectivity.cc | 40 +++++++++++++++ src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 33 ++++++------ src/OpenMesh/Core/Mesh/SmartHandles.hh | 5 +- src/Unittests/unittests_smart_handles.cc | 58 ++++++++++------------ 5 files changed, 97 insertions(+), 72 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/IteratorsT.hh b/src/OpenMesh/Core/Mesh/IteratorsT.hh index 3ce98609..72621575 100644 --- a/src/OpenMesh/Core/Mesh/IteratorsT.hh +++ b/src/OpenMesh/Core/Mesh/IteratorsT.hh @@ -40,9 +40,7 @@ * ========================================================================= */ - -#ifndef OPENMESH_ITERATORS_HH -#define OPENMESH_ITERATORS_HH +#pragma once //============================================================================= // @@ -56,6 +54,7 @@ #include #include +#include #include #include #include @@ -89,19 +88,20 @@ class GenericIteratorT { typedef value_handle value_type; typedef std::bidirectional_iterator_tag iterator_category; typedef std::ptrdiff_t difference_type; - typedef const value_type& reference; - typedef const value_type* pointer; typedef const Mesh* mesh_ptr; typedef const Mesh& mesh_ref; + typedef decltype(make_smart(std::declval(), std::declval())) SmartHandle; + typedef const SmartHandle& reference; + typedef const SmartHandle* pointer; /// Default constructor. GenericIteratorT() - : mesh_(0), skip_bits_(0) + : hnd_(make_smart(ValueHandle(),nullptr)), skip_bits_(0) {} /// Construct with mesh and a target handle. GenericIteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false) - : mesh_(&_mesh), hnd_(_hnd), skip_bits_(0) + : hnd_(make_smart(_hnd, _mesh)), skip_bits_(0) { if (_skip) enable_skipping(); } @@ -139,7 +139,7 @@ class GenericIteratorT { /// Are two iterators equal? Only valid if they refer to the same mesh! bool operator==(const GenericIteratorT& _rhs) const { - return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_)); + return ((hnd_.mesh() == _rhs.hnd_.mesh()) && (hnd_ == _rhs.hnd_)); } /// Not equal? @@ -210,7 +210,7 @@ class GenericIteratorT { /// Turn on skipping: automatically skip deleted/hidden elements void enable_skipping() { - if (mesh_ && (mesh_->*PrimitiveStatusMember)()) { + if (hnd_.mesh() && (hnd_.mesh()->*PrimitiveStatusMember)()) { Attributes::StatusInfo status; status.set_deleted(true); status.set_hidden(true); @@ -228,21 +228,20 @@ class GenericIteratorT { private: void skip_fwd() { - assert(mesh_ && skip_bits_); - while ((hnd_.idx() < (signed) (mesh_->*PrimitiveCountMember)()) - && (mesh_->status(hnd_).bits() & skip_bits_)) + assert(hnd_.mesh() && skip_bits_); + while ((hnd_.idx() < (signed) (hnd_.mesh()->*PrimitiveCountMember)()) + && (hnd_.mesh()->status(hnd_).bits() & skip_bits_)) hnd_.__increment(); } void skip_bwd() { - assert(mesh_ && skip_bits_); - while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_)) + assert(hnd_.mesh() && skip_bits_); + while ((hnd_.idx() >= 0) && (hnd_.mesh()->status(hnd_).bits() & skip_bits_)) hnd_.__decrement(); } protected: - mesh_ptr mesh_; - value_handle hnd_; + SmartHandle hnd_; unsigned int skip_bits_; }; @@ -250,5 +249,3 @@ class GenericIteratorT { } // namespace Iterators } // namespace OpenMesh //============================================================================= -#endif -//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc index 521f00e6..27c264d5 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc @@ -719,6 +719,46 @@ PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const return ConstFaceIter(*this, FaceHandle(int(n_faces()))); } +PolyConnectivity::VertexIter PolyConnectivity::vertices_sbegin() +{ + return VertexIter(*this, VertexHandle(0), true); +} + +PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_sbegin() const +{ + return ConstVertexIter(*this, VertexHandle(0), true); +} + +PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_sbegin() +{ + return HalfedgeIter(*this, HalfedgeHandle(0), true); +} + +PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_sbegin() const +{ + return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); +} + +PolyConnectivity::EdgeIter PolyConnectivity::edges_sbegin() +{ + return EdgeIter(*this, EdgeHandle(0), true); +} + +PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_sbegin() const +{ + return ConstEdgeIter(*this, EdgeHandle(0), true); +} + +PolyConnectivity::FaceIter PolyConnectivity::faces_sbegin() +{ + return FaceIter(*this, FaceHandle(0), true); +} + +PolyConnectivity::ConstFaceIter PolyConnectivity::faces_sbegin() const +{ + return ConstFaceIter(*this, FaceHandle(0), true); +} + //----------------------------------------------------------------------------- void PolyConnectivity::collapse(HalfedgeHandle _hh) { diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index 78e8a3f9..9d6aaca0 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -45,12 +45,17 @@ #define OPENMESH_POLYCONNECTIVITY_HH #include -#include #include namespace OpenMesh { +namespace Iterators +{ + template + class GenericIteratorT; +} + /** \brief Connectivity Class for polygonal meshes */ class OPENMESHDLLEXPORT PolyConnectivity : public ArrayKernel @@ -532,32 +537,24 @@ public: //@{ /// Begin iterator for vertices - VertexIter vertices_sbegin() - { return VertexIter(*this, VertexHandle(0), true); } + VertexIter vertices_sbegin(); /// Const begin iterator for vertices - ConstVertexIter vertices_sbegin() const - { return ConstVertexIter(*this, VertexHandle(0), true); } + ConstVertexIter vertices_sbegin() const; /// Begin iterator for halfedges - HalfedgeIter halfedges_sbegin() - { return HalfedgeIter(*this, HalfedgeHandle(0), true); } + HalfedgeIter halfedges_sbegin(); /// Const begin iterator for halfedges - ConstHalfedgeIter halfedges_sbegin() const - { return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); } + ConstHalfedgeIter halfedges_sbegin() const; /// Begin iterator for edges - EdgeIter edges_sbegin() - { return EdgeIter(*this, EdgeHandle(0), true); } + EdgeIter edges_sbegin(); /// Const begin iterator for edges - ConstEdgeIter edges_sbegin() const - { return ConstEdgeIter(*this, EdgeHandle(0), true); } + ConstEdgeIter edges_sbegin() const; /// Begin iterator for faces - FaceIter faces_sbegin() - { return FaceIter(*this, FaceHandle(0), true); } + FaceIter faces_sbegin(); /// Const begin iterator for faces - ConstFaceIter faces_sbegin() const - { return ConstFaceIter(*this, FaceHandle(0), true); } + ConstFaceIter faces_sbegin() const; //@} @@ -1627,4 +1624,6 @@ private: // Working storage for add_face() }//namespace OpenMesh +#include + #endif//OPENMESH_POLYCONNECTIVITY_HH diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index 5c671185..5655ffe4 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -40,8 +40,7 @@ * ========================================================================= */ -#ifndef OPENMESH_SMARTHANDLES_HH -#define OPENMESH_SMARTHANDLES_HH +#pragma once //== INCLUDES ================================================================= @@ -401,6 +400,4 @@ inline bool SmartFaceHandle::is_boundary() const } // namespace OpenMesh //============================================================================= - -#endif // OPENMESH_SMARTHANDLES_HH //============================================================================= diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc index fc7d4978..3ddb5fbe 100644 --- a/src/Unittests/unittests_smart_handles.cc +++ b/src/Unittests/unittests_smart_handles.cc @@ -162,34 +162,30 @@ TEST_F(OpenMeshSmartHandles, SimpleNavigation) { for (auto vh : mesh_.vertices()) { - auto svh = OpenMesh::make_smart(vh, mesh_); - EXPECT_EQ(mesh_.halfedge_handle(vh), svh.halfedge()) << "outgoing halfedge of vertex does not match"; + EXPECT_EQ(mesh_.halfedge_handle(vh), vh.halfedge()) << "outgoing halfedge of vertex does not match"; } for (auto heh : mesh_.halfedges()) { - auto sheh = OpenMesh::make_smart(heh, mesh_); - EXPECT_EQ(mesh_.next_halfedge_handle(heh), sheh.next()) << "next halfedge of halfedge does not match"; - EXPECT_EQ(mesh_.prev_halfedge_handle(heh), sheh.prev()) << "prevt halfedge of halfedge does not match"; - EXPECT_EQ(mesh_.opposite_halfedge_handle(heh), sheh.opp()) << "opposite halfedge of halfedge does not match"; - EXPECT_EQ(mesh_.to_vertex_handle(heh), sheh.to()) << "to vertex handle of halfedge does not match"; - EXPECT_EQ(mesh_.from_vertex_handle(heh), sheh.from()) << "from vertex handle of halfedge does not match"; - EXPECT_EQ(mesh_.face_handle(heh), sheh.face()) << "face handle of halfedge does not match"; + EXPECT_EQ(mesh_.next_halfedge_handle(heh), heh.next()) << "next halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.prev_halfedge_handle(heh), heh.prev()) << "prevt halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.opposite_halfedge_handle(heh), heh.opp()) << "opposite halfedge of halfedge does not match"; + EXPECT_EQ(mesh_.to_vertex_handle(heh), heh.to()) << "to vertex handle of halfedge does not match"; + EXPECT_EQ(mesh_.from_vertex_handle(heh), heh.from()) << "from vertex handle of halfedge does not match"; + EXPECT_EQ(mesh_.face_handle(heh), heh.face()) << "face handle of halfedge does not match"; } for (auto eh : mesh_.edges()) { - auto seh = OpenMesh::make_smart(eh, mesh_); - EXPECT_EQ(mesh_.halfedge_handle(eh, 0), seh.h0()) << "halfedge 0 of edge does not match"; - EXPECT_EQ(mesh_.halfedge_handle(eh, 1), seh.h1()) << "halfedge 1 of edge does not match"; - EXPECT_EQ(mesh_.from_vertex_handle(mesh_.halfedge_handle(eh, 0)), seh.v0()) << "first vertex of edge does not match"; - EXPECT_EQ(mesh_.to_vertex_handle (mesh_.halfedge_handle(eh, 0)), seh.v1()) << "second vertex of edge does not match"; + EXPECT_EQ(mesh_.halfedge_handle(eh, 0), eh.h0()) << "halfedge 0 of edge does not match"; + EXPECT_EQ(mesh_.halfedge_handle(eh, 1), eh.h1()) << "halfedge 1 of edge does not match"; + EXPECT_EQ(mesh_.from_vertex_handle(mesh_.halfedge_handle(eh, 0)), eh.v0()) << "first vertex of edge does not match"; + EXPECT_EQ(mesh_.to_vertex_handle (mesh_.halfedge_handle(eh, 0)), eh.v1()) << "second vertex of edge does not match"; } for (auto fh : mesh_.faces()) { - auto sfh = OpenMesh::make_smart(fh, mesh_); - EXPECT_EQ(mesh_.halfedge_handle(fh), sfh.halfedge()) << "halfedge of face does not match"; + EXPECT_EQ(mesh_.halfedge_handle(fh), fh.halfedge()) << "halfedge of face does not match"; } } @@ -200,13 +196,12 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) { for (auto vh : mesh_.vertices()) { - auto svh = OpenMesh::make_smart(vh, mesh_); { std::vector handles0; std::vector handles1; for (auto h : mesh_.vv_range(vh)) handles0.push_back(h); - for (auto h : svh.vertices()) + for (auto h : vh.vertices()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "vertex range of vertex does not match"; } @@ -215,7 +210,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.voh_range(vh)) handles0.push_back(h); - for (auto h : svh.outgoing_halfedges()) + for (auto h : vh.outgoing_halfedges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "outgoing halfedge range of vertex does not match"; } @@ -224,7 +219,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.vih_range(vh)) handles0.push_back(h); - for (auto h : svh.incoming_halfedges()) + for (auto h : vh.incoming_halfedges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "incoming halfedge range of vertex does not match"; } @@ -233,7 +228,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.ve_range(vh)) handles0.push_back(h); - for (auto h : svh.edges()) + for (auto h : vh.edges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "edge range of vertex does not match"; } @@ -242,7 +237,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.vf_range(vh)) handles0.push_back(h); - for (auto h : svh.faces()) + for (auto h : vh.faces()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "face range of vertex does not match"; } @@ -250,13 +245,12 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) for (auto fh : mesh_.faces()) { - auto sfh = OpenMesh::make_smart(fh, mesh_); { std::vector handles0; std::vector handles1; for (auto h : mesh_.fv_range(fh)) handles0.push_back(h); - for (auto h : sfh.vertices()) + for (auto h : fh.vertices()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "vertex range of face does not match"; } @@ -265,7 +259,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.fh_range(fh)) handles0.push_back(h); - for (auto h : sfh.halfedges()) + for (auto h : fh.halfedges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "halfedge range of face does not match"; } @@ -274,7 +268,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.fe_range(fh)) handles0.push_back(h); - for (auto h : sfh.edges()) + for (auto h : fh.edges()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "edge range of face does not match"; } @@ -283,7 +277,7 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) std::vector handles1; for (auto h : mesh_.ff_range(fh)) handles0.push_back(h); - for (auto h : sfh.faces()) + for (auto h : fh.faces()) handles1.push_back(h); EXPECT_EQ(handles0, handles1) << "face range of face does not match"; } @@ -297,18 +291,17 @@ TEST_F(OpenMeshSmartHandles, ComplicatedNavigtaion) { for (auto vh : mesh_.vertices()) { - auto svh = OpenMesh::make_smart(vh, mesh_); EXPECT_EQ(mesh_.next_halfedge_handle( mesh_.opposite_halfedge_handle( mesh_.halfedge_handle(vh))), - svh.out().opp().next()); + vh.out().opp().next()); EXPECT_EQ(mesh_.prev_halfedge_handle( mesh_.prev_halfedge_handle( mesh_.opposite_halfedge_handle( mesh_.next_halfedge_handle( mesh_.next_halfedge_handle( mesh_.halfedge_handle(vh)))))), - svh.out().next().next().opp().prev().prev()); + vh.out().next().next().opp().prev().prev()); EXPECT_EQ(mesh_.face_handle( mesh_.opposite_halfedge_handle( mesh_.halfedge_handle( @@ -316,7 +309,7 @@ TEST_F(OpenMeshSmartHandles, ComplicatedNavigtaion) mesh_.opposite_halfedge_handle( mesh_.next_halfedge_handle( mesh_.halfedge_handle(vh))))))), - svh.out().next().opp().face().halfedge().opp().face()); + vh.out().next().opp().face().halfedge().opp().face()); } } @@ -352,8 +345,7 @@ TEST_F(OpenMeshSmartHandles, Performance) { for (auto vh : mesh_.vertices()) { - auto svh = OpenMesh::make_smart(vh, mesh_); - auto heh = svh.out().next().next().opp().prev().prev(); + auto heh = vh.out().next().next().opp().prev().prev(); if (i == 0) halfedges1.push_back(heh); } From b62d846f3267c9c13aa601bc22375a716ce8fb5a Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 09:29:27 +0200 Subject: [PATCH 09/60] let circulators return smart handles --- src/OpenMesh/Core/Mesh/CirculatorsT.hh | 58 +- src/OpenMesh/Core/Mesh/PolyConnectivity.cc | 135 -- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 1333 +++++++++++++------- src/Unittests/unittests_smart_handles.cc | 97 ++ 4 files changed, 1034 insertions(+), 589 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/CirculatorsT.hh b/src/OpenMesh/Core/Mesh/CirculatorsT.hh index 395f6055..97b90732 100644 --- a/src/OpenMesh/Core/Mesh/CirculatorsT.hh +++ b/src/OpenMesh/Core/Mesh/CirculatorsT.hh @@ -40,9 +40,8 @@ * ========================================================================= */ +#pragma once -#ifndef OPENMESH_CIRCULATORS_HH -#define OPENMESH_CIRCULATORS_HH //============================================================================= // // Vertex and Face circulators for PolyMesh/TriMesh @@ -54,6 +53,7 @@ //== INCLUDES ================================================================= #include +#include #include #include #include @@ -248,19 +248,25 @@ class GenericCirculatorBaseT { int lap_counter_; }; -template::*Handle2Value)() const, bool CW = true > -class GenericCirculatorT : protected GenericCirculatorBaseT { +//template::*Handle2Value)() const, bool CW = true > +template +class GenericCirculatorT : protected GenericCirculatorBaseT { public: + using Mesh = typename GenericCirculatorT_TraitsT::Mesh; + using value_type = typename GenericCirculatorT_TraitsT::ValueHandle; + using CenterEntityHandle = typename GenericCirculatorT_TraitsT::CenterEntityHandle; + + using smart_value_type = decltype(make_smart(std::declval(), std::declval())); + typedef std::ptrdiff_t difference_type; - typedef ValueHandle value_type; typedef const value_type& reference; - typedef const value_type* pointer; + typedef const smart_value_type* pointer; typedef std::bidirectional_iterator_tag iterator_category; typedef typename GenericCirculatorBaseT::mesh_ptr mesh_ptr; typedef typename GenericCirculatorBaseT::mesh_ref mesh_ref; - typedef GenericCirculator_ValueHandleFnsT GenericCirculator_ValueHandleFns; + typedef GenericCirculator_ValueHandleFnsT GenericCirculator_ValueHandleFns; public: GenericCirculatorT() {} @@ -276,8 +282,8 @@ class GenericCirculatorT : protected GenericCirculatorBaseT { } GenericCirculatorT(const GenericCirculatorT &rhs) : GenericCirculatorBaseT(rhs) {} - friend class GenericCirculatorT; - explicit GenericCirculatorT( const GenericCirculatorT& rhs ) + friend class GenericCirculatorT; + explicit GenericCirculatorT( const GenericCirculatorT& rhs ) :GenericCirculatorBaseT(rhs){} GenericCirculatorT& operator++() { @@ -308,16 +314,16 @@ class GenericCirculatorT : protected GenericCirculatorBaseT { } /// Standard dereferencing operator. - value_type operator*() const { + smart_value_type operator*() const { // We can't use this due to a GCC6 compiler bug const GenericCirculatorBaseT* self = this; #ifndef NDEBUG assert(this->heh_.is_valid()); - value_type res = (self->*Handle2Value)(); + value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_); assert(res.is_valid()); return res; #else - return (self->*Handle2Value)(); + return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_); #endif } @@ -357,7 +363,7 @@ class GenericCirculatorT : protected GenericCirculatorBaseT { } private: - mutable value_type pointer_deref_value; + mutable smart_value_type pointer_deref_value; }; ////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -420,19 +426,22 @@ class GenericCirculator_ValueHandleFnsT_DEPRECATED::*Handle2Value)() const> -class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { +template +class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { public: + using Mesh = typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh; + using CenterEntityHandle = typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle; + using value_type = typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle; + using smart_value_type = decltype (make_smart(std::declval(), std::declval())); + typedef std::ptrdiff_t difference_type; - typedef ValueHandle value_type; typedef const value_type& reference; - typedef const value_type* pointer; + typedef const smart_value_type* pointer; typedef std::bidirectional_iterator_tag iterator_category; typedef typename GenericCirculatorBaseT::mesh_ptr mesh_ptr; typedef typename GenericCirculatorBaseT::mesh_ref mesh_ref; - typedef GenericCirculator_ValueHandleFnsT_DEPRECATED GenericCirculator_ValueHandleFns; + typedef GenericCirculator_ValueHandleFnsT_DEPRECATED GenericCirculator_ValueHandleFns; public: GenericCirculatorT_DEPRECATED() {} @@ -494,16 +503,16 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { } /// Standard dereferencing operator. - value_type operator*() const { + smart_value_type operator*() const { // We can't use this due to a GCC6 compiler bug const GenericCirculatorBaseT* self = this; #ifndef NDEBUG assert(this->heh_.is_valid()); - value_type res = (self->*Handle2Value)(); + value_type res = (self->GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_); assert(res.is_valid()); return res; #else - return (self->*Handle2Value)(); + return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_); #endif } @@ -584,10 +593,9 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT { } private: - mutable value_type pointer_deref_value; + mutable smart_value_type pointer_deref_value; }; } // namespace Iterators } // namespace OpenMesh -#endif diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc index 27c264d5..1be2a823 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc @@ -623,141 +623,6 @@ void PolyConnectivity::delete_face(FaceHandle _fh, bool _delete_isolated_vertice adjust_outgoing_halfedge(*v_it); } -//----------------------------------------------------------------------------- -PolyConnectivity::VertexIter PolyConnectivity::vertices_begin() -{ - return VertexIter(*this, VertexHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_begin() const -{ - return ConstVertexIter(*this, VertexHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::VertexIter PolyConnectivity::vertices_end() -{ - return VertexIter(*this, VertexHandle( int(n_vertices() ) )); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_end() const -{ - return ConstVertexIter(*this, VertexHandle( int(n_vertices()) )); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_begin() -{ - return HalfedgeIter(*this, HalfedgeHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_begin() const -{ - return ConstHalfedgeIter(*this, HalfedgeHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_end() -{ - return HalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_end() const -{ - return ConstHalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::EdgeIter PolyConnectivity::edges_begin() -{ - return EdgeIter(*this, EdgeHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_begin() const -{ - return ConstEdgeIter(*this, EdgeHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::EdgeIter PolyConnectivity::edges_end() -{ - return EdgeIter(*this, EdgeHandle(int(n_edges()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_end() const -{ - return ConstEdgeIter(*this, EdgeHandle(int(n_edges()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::FaceIter PolyConnectivity::faces_begin() -{ - return FaceIter(*this, FaceHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstFaceIter PolyConnectivity::faces_begin() const -{ - return ConstFaceIter(*this, FaceHandle(0)); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::FaceIter PolyConnectivity::faces_end() -{ - return FaceIter(*this, FaceHandle(int(n_faces()))); -} - -//----------------------------------------------------------------------------- -PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const -{ - return ConstFaceIter(*this, FaceHandle(int(n_faces()))); -} - -PolyConnectivity::VertexIter PolyConnectivity::vertices_sbegin() -{ - return VertexIter(*this, VertexHandle(0), true); -} - -PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_sbegin() const -{ - return ConstVertexIter(*this, VertexHandle(0), true); -} - -PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_sbegin() -{ - return HalfedgeIter(*this, HalfedgeHandle(0), true); -} - -PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_sbegin() const -{ - return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); -} - -PolyConnectivity::EdgeIter PolyConnectivity::edges_sbegin() -{ - return EdgeIter(*this, EdgeHandle(0), true); -} - -PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_sbegin() const -{ - return ConstEdgeIter(*this, EdgeHandle(0), true); -} - -PolyConnectivity::FaceIter PolyConnectivity::faces_sbegin() -{ - return FaceIter(*this, FaceHandle(0), true); -} - -PolyConnectivity::ConstFaceIter PolyConnectivity::faces_sbegin() const -{ - return ConstFaceIter(*this, FaceHandle(0), true); -} //----------------------------------------------------------------------------- void PolyConnectivity::collapse(HalfedgeHandle _hh) diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index 9d6aaca0..bdce69b5 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -45,7 +45,6 @@ #define OPENMESH_POLYCONNECTIVITY_HH #include -#include namespace OpenMesh { @@ -54,6 +53,15 @@ namespace Iterators { template class GenericIteratorT; + + template + class GenericCirculatorBaseT; + + template + class GenericCirculatorT_DEPRECATED; + + template + class GenericCirculatorT; } /** \brief Connectivity Class for polygonal meshes @@ -106,99 +114,122 @@ public: * Vertex-centered circulators */ + struct VertexVertexTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::VertexHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->to_vertex_handle(_heh);} + }; + + /** * Enumerates 1-ring vertices in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toVertexHandle> - VertexVertexIter; - typedef Iterators::GenericCirculatorT::toVertexHandle> VertexVertexCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexVertexIter; + typedef Iterators::GenericCirculatorT VertexVertexCWIter; /** * Enumerates 1-ring vertices in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toVertexHandle, false> - VertexVertexCCWIter; + typedef Iterators::GenericCirculatorT VertexVertexCCWIter; + + + struct VertexHalfedgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::HalfedgeHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _heh;} + }; /** * Enumerates outgoing half edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toHalfedgeHandle> - VertexOHalfedgeIter; - typedef Iterators::GenericCirculatorT::toHalfedgeHandle> VertexOHalfedgeCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexOHalfedgeIter; + typedef Iterators::GenericCirculatorT VertexOHalfedgeCWIter; /** * Enumerates outgoing half edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toHalfedgeHandle, false> - VertexOHalfedgeCCWIter; + typedef Iterators::GenericCirculatorT VertexOHalfedgeCCWIter; + + struct VertexOppositeHalfedgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::HalfedgeHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->opposite_halfedge_handle(_heh); } + }; /** * Enumerates incoming half edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toOppositeHalfedgeHandle> - VertexIHalfedgeIter; - typedef Iterators::GenericCirculatorT::toOppositeHalfedgeHandle> VertexIHalfedgeCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexIHalfedgeIter; + typedef Iterators::GenericCirculatorT VertexIHalfedgeCWIter; /** * Enumerates incoming half edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toOppositeHalfedgeHandle, false> - VertexIHalfedgeCCWIter; + typedef Iterators::GenericCirculatorT VertexIHalfedgeCCWIter; + + + struct VertexFaceTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::FaceHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->face_handle(_heh); } + }; /** * Enumerates incident faces in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toFaceHandle> - VertexFaceIter; - typedef Iterators::GenericCirculatorT::toFaceHandle> VertexFaceCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexFaceIter; + typedef Iterators::GenericCirculatorT VertexFaceCWIter; /** * Enumerates incident faces in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toFaceHandle, false> - VertexFaceCCWIter; + typedef Iterators::GenericCirculatorT VertexFaceCCWIter; + + + struct VertexEdgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::VertexHandle; + using ValueHandle = This::EdgeHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->edge_handle(_heh); } + }; /** * Enumerates incident edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toEdgeHandle> - VertexEdgeIter; - typedef Iterators::GenericCirculatorT::toEdgeHandle> VertexEdgeCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED VertexEdgeIter; + typedef Iterators::GenericCirculatorT VertexEdgeCWIter; /** * Enumerates incident edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toEdgeHandle, false> - VertexEdgeCCWIter; + typedef Iterators::GenericCirculatorT VertexEdgeCCWIter; + + + struct FaceHalfedgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::FaceHandle; + using ValueHandle = This::HalfedgeHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _heh; } + }; /** * Identical to #FaceHalfedgeIter. God knows why this typedef exists. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toHalfedgeHandle> - HalfedgeLoopIter; - typedef Iterators::GenericCirculatorT::toHalfedgeHandle, false> HalfedgeLoopCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED HalfedgeLoopIter; + typedef Iterators::GenericCirculatorT HalfedgeLoopCWIter; /** * Identical to #FaceHalfedgeIter. God knows why this typedef exists. */ - typedef Iterators::GenericCirculatorT::toHalfedgeHandle> - HalfedgeLoopCCWIter; + typedef Iterators::GenericCirculatorT HalfedgeLoopCCWIter; typedef VertexVertexIter ConstVertexVertexIter; typedef VertexVertexCWIter ConstVertexVertexCWIter; @@ -220,69 +251,75 @@ public: * Face-centered circulators */ + struct FaceVertexTraits + { + using Mesh = This; + using CenterEntityHandle = This::FaceHandle; + using ValueHandle = This::VertexHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->to_vertex_handle(_heh); } + }; + /** * Enumerate incident vertices in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toVertexHandle> - FaceVertexIter; - typedef Iterators::GenericCirculatorT::toVertexHandle> FaceVertexCCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED FaceVertexIter; + typedef Iterators::GenericCirculatorT FaceVertexCCWIter; /** * Enumerate incident vertices in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toVertexHandle, false> - FaceVertexCWIter; + typedef Iterators::GenericCirculatorT FaceVertexCWIter; /** * Enumerate incident half edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toHalfedgeHandle> - FaceHalfedgeIter; - typedef Iterators::GenericCirculatorT::toHalfedgeHandle> FaceHalfedgeCCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED FaceHalfedgeIter; + typedef Iterators::GenericCirculatorT FaceHalfedgeCCWIter; /** * Enumerate incident half edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toHalfedgeHandle, false> - FaceHalfedgeCWIter; + typedef Iterators::GenericCirculatorT FaceHalfedgeCWIter; + + + struct FaceEdgeTraits + { + using Mesh = This; + using CenterEntityHandle = This::FaceHandle; + using ValueHandle = This::EdgeHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->edge_handle(_heh); } + }; /** * Enumerate incident edges in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toEdgeHandle> - FaceEdgeIter; - typedef Iterators::GenericCirculatorT::toEdgeHandle> FaceEdgeCCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED FaceEdgeIter; + typedef Iterators::GenericCirculatorT FaceEdgeCCWIter; /** * Enumerate incident edges in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toEdgeHandle, false> - FaceEdgeCWIter; + typedef Iterators::GenericCirculatorT FaceEdgeCWIter; + + + struct FaceFaceTraits + { + using Mesh = This; + using CenterEntityHandle = This::FaceHandle; + using ValueHandle = This::FaceHandle; + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->face_handle(_mesh->opposite_halfedge_handle(_heh)); } + }; /** * Enumerate adjacent faces in a counter clockwise fashion. */ - typedef Iterators::GenericCirculatorT_DEPRECATED::toOppositeFaceHandle> - FaceFaceIter; - typedef Iterators::GenericCirculatorT::toOppositeFaceHandle> FaceFaceCCWIter; + typedef Iterators::GenericCirculatorT_DEPRECATED FaceFaceIter; + typedef Iterators::GenericCirculatorT FaceFaceCCWIter; /** * Enumerate adjacent faces in a clockwise fashion. */ - typedef Iterators::GenericCirculatorT::toOppositeFaceHandle, false> - FaceFaceCWIter; + typedef Iterators::GenericCirculatorT FaceFaceCWIter; typedef FaceVertexIter ConstFaceVertexIter; typedef FaceVertexCWIter ConstFaceVertexCWIter; @@ -565,543 +602,369 @@ public: //@{ /// vertex - vertex circulator - VertexVertexIter vv_iter(VertexHandle _vh) - { return VertexVertexIter(*this, _vh); } + VertexVertexIter vv_iter(VertexHandle _vh); /// vertex - vertex circulator cw - VertexVertexCWIter vv_cwiter(VertexHandle _vh) - { return VertexVertexCWIter(*this, _vh); } + VertexVertexCWIter vv_cwiter(VertexHandle _vh); /// vertex - vertex circulator ccw - VertexVertexCCWIter vv_ccwiter(VertexHandle _vh) - { return VertexVertexCCWIter(*this, _vh); } + VertexVertexCCWIter vv_ccwiter(VertexHandle _vh); /// vertex - incoming halfedge circulator - VertexIHalfedgeIter vih_iter(VertexHandle _vh) - { return VertexIHalfedgeIter(*this, _vh); } + VertexIHalfedgeIter vih_iter(VertexHandle _vh); /// vertex - incoming halfedge circulator cw - VertexIHalfedgeCWIter vih_cwiter(VertexHandle _vh) - { return VertexIHalfedgeCWIter(*this, _vh); } + VertexIHalfedgeCWIter vih_cwiter(VertexHandle _vh); /// vertex - incoming halfedge circulator ccw - VertexIHalfedgeCCWIter vih_ccwiter(VertexHandle _vh) - { return VertexIHalfedgeCCWIter(*this, _vh); } + VertexIHalfedgeCCWIter vih_ccwiter(VertexHandle _vh); /// vertex - outgoing halfedge circulator - VertexOHalfedgeIter voh_iter(VertexHandle _vh) - { return VertexOHalfedgeIter(*this, _vh); } + VertexOHalfedgeIter voh_iter(VertexHandle _vh); /// vertex - outgoing halfedge circulator cw - VertexOHalfedgeCWIter voh_cwiter(VertexHandle _vh) - { return VertexOHalfedgeCWIter(*this, _vh); } + VertexOHalfedgeCWIter voh_cwiter(VertexHandle _vh); /// vertex - outgoing halfedge circulator ccw - VertexOHalfedgeCCWIter voh_ccwiter(VertexHandle _vh) - { return VertexOHalfedgeCCWIter(*this, _vh); } + VertexOHalfedgeCCWIter voh_ccwiter(VertexHandle _vh); /// vertex - edge circulator - VertexEdgeIter ve_iter(VertexHandle _vh) - { return VertexEdgeIter(*this, _vh); } + VertexEdgeIter ve_iter(VertexHandle _vh); /// vertex - edge circulator cw - VertexEdgeCWIter ve_cwiter(VertexHandle _vh) - { return VertexEdgeCWIter(*this, _vh); } + VertexEdgeCWIter ve_cwiter(VertexHandle _vh); /// vertex - edge circulator ccw - VertexEdgeCCWIter ve_ccwiter(VertexHandle _vh) - { return VertexEdgeCCWIter(*this, _vh); } + VertexEdgeCCWIter ve_ccwiter(VertexHandle _vh); /// vertex - face circulator - VertexFaceIter vf_iter(VertexHandle _vh) - { return VertexFaceIter(*this, _vh); } + VertexFaceIter vf_iter(VertexHandle _vh); /// vertex - face circulator cw - VertexFaceCWIter vf_cwiter(VertexHandle _vh) - { return VertexFaceCWIter(*this, _vh); } + VertexFaceCWIter vf_cwiter(VertexHandle _vh); /// vertex - face circulator ccw - VertexFaceCCWIter vf_ccwiter(VertexHandle _vh) - { return VertexFaceCCWIter(*this, _vh); } + VertexFaceCCWIter vf_ccwiter(VertexHandle _vh); /// const vertex circulator - ConstVertexVertexIter cvv_iter(VertexHandle _vh) const - { return ConstVertexVertexIter(*this, _vh); } + ConstVertexVertexIter cvv_iter(VertexHandle _vh) const; /// const vertex circulator cw - ConstVertexVertexCWIter cvv_cwiter(VertexHandle _vh) const - { return ConstVertexVertexCWIter(*this, _vh); } + ConstVertexVertexCWIter cvv_cwiter(VertexHandle _vh) const; /// const vertex circulator ccw - ConstVertexVertexCCWIter cvv_ccwiter(VertexHandle _vh) const - { return ConstVertexVertexCCWIter(*this, _vh); } + ConstVertexVertexCCWIter cvv_ccwiter(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator - ConstVertexIHalfedgeIter cvih_iter(VertexHandle _vh) const - { return ConstVertexIHalfedgeIter(*this, _vh); } + ConstVertexIHalfedgeIter cvih_iter(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator cw - ConstVertexIHalfedgeCWIter cvih_cwiter(VertexHandle _vh) const - { return ConstVertexIHalfedgeCWIter(*this, _vh); } + ConstVertexIHalfedgeCWIter cvih_cwiter(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator ccw - ConstVertexIHalfedgeCCWIter cvih_ccwiter(VertexHandle _vh) const - { return ConstVertexIHalfedgeCCWIter(*this, _vh); } + ConstVertexIHalfedgeCCWIter cvih_ccwiter(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator - ConstVertexOHalfedgeIter cvoh_iter(VertexHandle _vh) const - { return ConstVertexOHalfedgeIter(*this, _vh); } + ConstVertexOHalfedgeIter cvoh_iter(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator cw - ConstVertexOHalfedgeCWIter cvoh_cwiter(VertexHandle _vh) const - { return ConstVertexOHalfedgeCWIter(*this, _vh); } + ConstVertexOHalfedgeCWIter cvoh_cwiter(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator ccw - ConstVertexOHalfedgeCCWIter cvoh_ccwiter(VertexHandle _vh) const - { return ConstVertexOHalfedgeCCWIter(*this, _vh); } + ConstVertexOHalfedgeCCWIter cvoh_ccwiter(VertexHandle _vh) const; /// const vertex - edge circulator - ConstVertexEdgeIter cve_iter(VertexHandle _vh) const - { return ConstVertexEdgeIter(*this, _vh); } + ConstVertexEdgeIter cve_iter(VertexHandle _vh) const; /// const vertex - edge circulator cw - ConstVertexEdgeCWIter cve_cwiter(VertexHandle _vh) const - { return ConstVertexEdgeCWIter(*this, _vh); } + ConstVertexEdgeCWIter cve_cwiter(VertexHandle _vh) const; /// const vertex - edge circulator ccw - ConstVertexEdgeCCWIter cve_ccwiter(VertexHandle _vh) const - { return ConstVertexEdgeCCWIter(*this, _vh); } + ConstVertexEdgeCCWIter cve_ccwiter(VertexHandle _vh) const; /// const vertex - face circulator - ConstVertexFaceIter cvf_iter(VertexHandle _vh) const - { return ConstVertexFaceIter(*this, _vh); } + ConstVertexFaceIter cvf_iter(VertexHandle _vh) const; /// const vertex - face circulator cw - ConstVertexFaceCWIter cvf_cwiter(VertexHandle _vh) const - { return ConstVertexFaceCWIter(*this, _vh); } + ConstVertexFaceCWIter cvf_cwiter(VertexHandle _vh) const; /// const vertex - face circulator ccw - ConstVertexFaceCCWIter cvf_ccwiter(VertexHandle _vh) const - { return ConstVertexFaceCCWIter(*this, _vh); } + ConstVertexFaceCCWIter cvf_ccwiter(VertexHandle _vh) const; /// face - vertex circulator - FaceVertexIter fv_iter(FaceHandle _fh) - { return FaceVertexIter(*this, _fh); } + FaceVertexIter fv_iter(FaceHandle _fh); /// face - vertex circulator cw - FaceVertexCWIter fv_cwiter(FaceHandle _fh) - { return FaceVertexCWIter(*this, _fh); } + FaceVertexCWIter fv_cwiter(FaceHandle _fh); /// face - vertex circulator ccw - FaceVertexCCWIter fv_ccwiter(FaceHandle _fh) - { return FaceVertexCCWIter(*this, _fh); } + FaceVertexCCWIter fv_ccwiter(FaceHandle _fh); /// face - halfedge circulator - FaceHalfedgeIter fh_iter(FaceHandle _fh) - { return FaceHalfedgeIter(*this, _fh); } + FaceHalfedgeIter fh_iter(FaceHandle _fh); /// face - halfedge circulator cw - FaceHalfedgeCWIter fh_cwiter(FaceHandle _fh) - { return FaceHalfedgeCWIter(*this, _fh); } + FaceHalfedgeCWIter fh_cwiter(FaceHandle _fh); /// face - halfedge circulator ccw - FaceHalfedgeCCWIter fh_ccwiter(FaceHandle _fh) - { return FaceHalfedgeCCWIter(*this, _fh); } + FaceHalfedgeCCWIter fh_ccwiter(FaceHandle _fh); /// face - edge circulator - FaceEdgeIter fe_iter(FaceHandle _fh) - { return FaceEdgeIter(*this, _fh); } + FaceEdgeIter fe_iter(FaceHandle _fh); /// face - edge circulator cw - FaceEdgeCWIter fe_cwiter(FaceHandle _fh) - { return FaceEdgeCWIter(*this, _fh); } + FaceEdgeCWIter fe_cwiter(FaceHandle _fh); /// face - edge circulator ccw - FaceEdgeCCWIter fe_ccwiter(FaceHandle _fh) - { return FaceEdgeCCWIter(*this, _fh); } + FaceEdgeCCWIter fe_ccwiter(FaceHandle _fh); /// face - face circulator - FaceFaceIter ff_iter(FaceHandle _fh) - { return FaceFaceIter(*this, _fh); } + FaceFaceIter ff_iter(FaceHandle _fh); /// face - face circulator cw - FaceFaceCWIter ff_cwiter(FaceHandle _fh) - { return FaceFaceCWIter(*this, _fh); } + FaceFaceCWIter ff_cwiter(FaceHandle _fh); /// face - face circulator ccw - FaceFaceCCWIter ff_ccwiter(FaceHandle _fh) - { return FaceFaceCCWIter(*this, _fh); } + FaceFaceCCWIter ff_ccwiter(FaceHandle _fh); /// const face - vertex circulator - ConstFaceVertexIter cfv_iter(FaceHandle _fh) const - { return ConstFaceVertexIter(*this, _fh); } + ConstFaceVertexIter cfv_iter(FaceHandle _fh) const; /// const face - vertex circulator cw - ConstFaceVertexCWIter cfv_cwiter(FaceHandle _fh) const - { return ConstFaceVertexCWIter(*this, _fh); } + ConstFaceVertexCWIter cfv_cwiter(FaceHandle _fh) const; /// const face - vertex circulator ccw - ConstFaceVertexCCWIter cfv_ccwiter(FaceHandle _fh) const - { return ConstFaceVertexCCWIter(*this, _fh); } + ConstFaceVertexCCWIter cfv_ccwiter(FaceHandle _fh) const; /// const face - halfedge circulator - ConstFaceHalfedgeIter cfh_iter(FaceHandle _fh) const - { return ConstFaceHalfedgeIter(*this, _fh); } + ConstFaceHalfedgeIter cfh_iter(FaceHandle _fh) const; /// const face - halfedge circulator cw - ConstFaceHalfedgeCWIter cfh_cwiter(FaceHandle _fh) const - { return ConstFaceHalfedgeCWIter(*this, _fh); } + ConstFaceHalfedgeCWIter cfh_cwiter(FaceHandle _fh) const; /// const face - halfedge circulator ccw - ConstFaceHalfedgeCCWIter cfh_ccwiter(FaceHandle _fh) const - { return ConstFaceHalfedgeCCWIter(*this, _fh); } + ConstFaceHalfedgeCCWIter cfh_ccwiter(FaceHandle _fh) const; /// const face - edge circulator - ConstFaceEdgeIter cfe_iter(FaceHandle _fh) const - { return ConstFaceEdgeIter(*this, _fh); } + ConstFaceEdgeIter cfe_iter(FaceHandle _fh) const; /// const face - edge circulator cw - ConstFaceEdgeCWIter cfe_cwiter(FaceHandle _fh) const - { return ConstFaceEdgeCWIter(*this, _fh); } + ConstFaceEdgeCWIter cfe_cwiter(FaceHandle _fh) const; /// const face - edge circulator ccw - ConstFaceEdgeCCWIter cfe_ccwiter(FaceHandle _fh) const - { return ConstFaceEdgeCCWIter(*this, _fh); } + ConstFaceEdgeCCWIter cfe_ccwiter(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceIter cff_iter(FaceHandle _fh) const - { return ConstFaceFaceIter(*this, _fh); } + ConstFaceFaceIter cff_iter(FaceHandle _fh) const; /// const face - face circulator cw - ConstFaceFaceCWIter cff_cwiter(FaceHandle _fh) const - { return ConstFaceFaceCWIter(*this, _fh); } + ConstFaceFaceCWIter cff_cwiter(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceCCWIter cff_ccwiter(FaceHandle _fh) const - { return ConstFaceFaceCCWIter(*this, _fh); } + ConstFaceFaceCCWIter cff_ccwiter(FaceHandle _fh) const; // 'begin' circulators /// vertex - vertex circulator - VertexVertexIter vv_begin(VertexHandle _vh) - { return VertexVertexIter(*this, _vh); } + VertexVertexIter vv_begin(VertexHandle _vh); /// vertex - vertex circulator cw - VertexVertexCWIter vv_cwbegin(VertexHandle _vh) - { return VertexVertexCWIter(*this, _vh); } + VertexVertexCWIter vv_cwbegin(VertexHandle _vh); /// vertex - vertex circulator ccw - VertexVertexCCWIter vv_ccwbegin(VertexHandle _vh) - { return VertexVertexCCWIter(*this, _vh); } + VertexVertexCCWIter vv_ccwbegin(VertexHandle _vh); /// vertex - incoming halfedge circulator - VertexIHalfedgeIter vih_begin(VertexHandle _vh) - { return VertexIHalfedgeIter(*this, _vh); } + VertexIHalfedgeIter vih_begin(VertexHandle _vh); /// vertex - incoming halfedge circulator cw - VertexIHalfedgeCWIter vih_cwbegin(VertexHandle _vh) - { return VertexIHalfedgeCWIter(*this, _vh); } + VertexIHalfedgeCWIter vih_cwbegin(VertexHandle _vh); /// vertex - incoming halfedge circulator ccw - VertexIHalfedgeCCWIter vih_ccwbegin(VertexHandle _vh) - { return VertexIHalfedgeCCWIter(*this, _vh); } + VertexIHalfedgeCCWIter vih_ccwbegin(VertexHandle _vh); /// vertex - outgoing halfedge circulator - VertexOHalfedgeIter voh_begin(VertexHandle _vh) - { return VertexOHalfedgeIter(*this, _vh); } + VertexOHalfedgeIter voh_begin(VertexHandle _vh); /// vertex - outgoing halfedge circulator cw - VertexOHalfedgeCWIter voh_cwbegin(VertexHandle _vh) - { return VertexOHalfedgeCWIter(*this, _vh); } + VertexOHalfedgeCWIter voh_cwbegin(VertexHandle _vh); /// vertex - outgoing halfedge circulator ccw - VertexOHalfedgeCCWIter voh_ccwbegin(VertexHandle _vh) - { return VertexOHalfedgeCCWIter(*this, _vh); } + VertexOHalfedgeCCWIter voh_ccwbegin(VertexHandle _vh); /// vertex - edge circulator - VertexEdgeIter ve_begin(VertexHandle _vh) - { return VertexEdgeIter(*this, _vh); } + VertexEdgeIter ve_begin(VertexHandle _vh); /// vertex - edge circulator cw - VertexEdgeCWIter ve_cwbegin(VertexHandle _vh) - { return VertexEdgeCWIter(*this, _vh); } + VertexEdgeCWIter ve_cwbegin(VertexHandle _vh); /// vertex - edge circulator ccw - VertexEdgeCCWIter ve_ccwbegin(VertexHandle _vh) - { return VertexEdgeCCWIter(*this, _vh); } + VertexEdgeCCWIter ve_ccwbegin(VertexHandle _vh); /// vertex - face circulator - VertexFaceIter vf_begin(VertexHandle _vh) - { return VertexFaceIter(*this, _vh); } + VertexFaceIter vf_begin(VertexHandle _vh); /// vertex - face circulator cw - VertexFaceCWIter vf_cwbegin(VertexHandle _vh) - { return VertexFaceCWIter(*this, _vh); } + VertexFaceCWIter vf_cwbegin(VertexHandle _vh); /// vertex - face circulator ccw - VertexFaceCCWIter vf_ccwbegin(VertexHandle _vh) - { return VertexFaceCCWIter(*this, _vh); } + VertexFaceCCWIter vf_ccwbegin(VertexHandle _vh); /// const vertex circulator - ConstVertexVertexIter cvv_begin(VertexHandle _vh) const - { return ConstVertexVertexIter(*this, _vh); } + ConstVertexVertexIter cvv_begin(VertexHandle _vh) const; /// const vertex circulator cw - ConstVertexVertexCWIter cvv_cwbegin(VertexHandle _vh) const - { return ConstVertexVertexCWIter(*this, _vh); } + ConstVertexVertexCWIter cvv_cwbegin(VertexHandle _vh) const; /// const vertex circulator ccw - ConstVertexVertexCCWIter cvv_ccwbegin(VertexHandle _vh) const - { return ConstVertexVertexCCWIter(*this, _vh); } + ConstVertexVertexCCWIter cvv_ccwbegin(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator - ConstVertexIHalfedgeIter cvih_begin(VertexHandle _vh) const - { return ConstVertexIHalfedgeIter(*this, _vh); } + ConstVertexIHalfedgeIter cvih_begin(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator cw - ConstVertexIHalfedgeCWIter cvih_cwbegin(VertexHandle _vh) const - { return ConstVertexIHalfedgeCWIter(*this, _vh); } + ConstVertexIHalfedgeCWIter cvih_cwbegin(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator ccw - ConstVertexIHalfedgeCCWIter cvih_ccwbegin(VertexHandle _vh) const - { return ConstVertexIHalfedgeCCWIter(*this, _vh); } + ConstVertexIHalfedgeCCWIter cvih_ccwbegin(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator - ConstVertexOHalfedgeIter cvoh_begin(VertexHandle _vh) const - { return ConstVertexOHalfedgeIter(*this, _vh); } + ConstVertexOHalfedgeIter cvoh_begin(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator cw - ConstVertexOHalfedgeCWIter cvoh_cwbegin(VertexHandle _vh) const - { return ConstVertexOHalfedgeCWIter(*this, _vh); } + ConstVertexOHalfedgeCWIter cvoh_cwbegin(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator ccw - ConstVertexOHalfedgeCCWIter cvoh_ccwbegin(VertexHandle _vh) const - { return ConstVertexOHalfedgeCCWIter(*this, _vh); } + ConstVertexOHalfedgeCCWIter cvoh_ccwbegin(VertexHandle _vh) const; /// const vertex - edge circulator - ConstVertexEdgeIter cve_begin(VertexHandle _vh) const - { return ConstVertexEdgeIter(*this, _vh); } + ConstVertexEdgeIter cve_begin(VertexHandle _vh) const; /// const vertex - edge circulator cw - ConstVertexEdgeCWIter cve_cwbegin(VertexHandle _vh) const - { return ConstVertexEdgeCWIter(*this, _vh); } + ConstVertexEdgeCWIter cve_cwbegin(VertexHandle _vh) const; /// const vertex - edge circulator ccw - ConstVertexEdgeCCWIter cve_ccwbegin(VertexHandle _vh) const - { return ConstVertexEdgeCCWIter(*this, _vh); } + ConstVertexEdgeCCWIter cve_ccwbegin(VertexHandle _vh) const; /// const vertex - face circulator - ConstVertexFaceIter cvf_begin(VertexHandle _vh) const - { return ConstVertexFaceIter(*this, _vh); } + ConstVertexFaceIter cvf_begin(VertexHandle _vh) const; /// const vertex - face circulator cw - ConstVertexFaceCWIter cvf_cwbegin(VertexHandle _vh) const - { return ConstVertexFaceCWIter(*this, _vh); } + ConstVertexFaceCWIter cvf_cwbegin(VertexHandle _vh) const; /// const vertex - face circulator ccw - ConstVertexFaceCCWIter cvf_ccwbegin(VertexHandle _vh) const - { return ConstVertexFaceCCWIter(*this, _vh); } + ConstVertexFaceCCWIter cvf_ccwbegin(VertexHandle _vh) const; /// face - vertex circulator - FaceVertexIter fv_begin(FaceHandle _fh) - { return FaceVertexIter(*this, _fh); } + FaceVertexIter fv_begin(FaceHandle _fh); /// face - vertex circulator cw - FaceVertexCWIter fv_cwbegin(FaceHandle _fh) - { return FaceVertexCWIter(*this, _fh); } + FaceVertexCWIter fv_cwbegin(FaceHandle _fh); /// face - vertex circulator ccw - FaceVertexCCWIter fv_ccwbegin(FaceHandle _fh) - { return FaceVertexCCWIter(*this, _fh); } + FaceVertexCCWIter fv_ccwbegin(FaceHandle _fh); /// face - halfedge circulator - FaceHalfedgeIter fh_begin(FaceHandle _fh) - { return FaceHalfedgeIter(*this, _fh); } + FaceHalfedgeIter fh_begin(FaceHandle _fh); /// face - halfedge circulator cw - FaceHalfedgeCWIter fh_cwbegin(FaceHandle _fh) - { return FaceHalfedgeCWIter(*this, _fh); } + FaceHalfedgeCWIter fh_cwbegin(FaceHandle _fh); /// face - halfedge circulator ccw - FaceHalfedgeCCWIter fh_ccwbegin(FaceHandle _fh) - { return FaceHalfedgeCCWIter(*this, _fh); } + FaceHalfedgeCCWIter fh_ccwbegin(FaceHandle _fh); /// face - edge circulator - FaceEdgeIter fe_begin(FaceHandle _fh) - { return FaceEdgeIter(*this, _fh); } + FaceEdgeIter fe_begin(FaceHandle _fh); /// face - edge circulator cw - FaceEdgeCWIter fe_cwbegin(FaceHandle _fh) - { return FaceEdgeCWIter(*this, _fh); } + FaceEdgeCWIter fe_cwbegin(FaceHandle _fh); /// face - edge circulator ccw - FaceEdgeCCWIter fe_ccwbegin(FaceHandle _fh) - { return FaceEdgeCCWIter(*this, _fh); } + FaceEdgeCCWIter fe_ccwbegin(FaceHandle _fh); /// face - face circulator - FaceFaceIter ff_begin(FaceHandle _fh) - { return FaceFaceIter(*this, _fh); } + FaceFaceIter ff_begin(FaceHandle _fh); /// face - face circulator cw - FaceFaceCWIter ff_cwbegin(FaceHandle _fh) - { return FaceFaceCWIter(*this, _fh); } + FaceFaceCWIter ff_cwbegin(FaceHandle _fh); /// face - face circulator ccw - FaceFaceCCWIter ff_ccwbegin(FaceHandle _fh) - { return FaceFaceCCWIter(*this, _fh); } + FaceFaceCCWIter ff_ccwbegin(FaceHandle _fh); /// halfedge circulator - HalfedgeLoopIter hl_begin(HalfedgeHandle _heh) - { return HalfedgeLoopIter(*this, _heh); } + HalfedgeLoopIter hl_begin(HalfedgeHandle _heh); /// halfedge circulator - HalfedgeLoopCWIter hl_cwbegin(HalfedgeHandle _heh) - { return HalfedgeLoopCWIter(*this, _heh); } + HalfedgeLoopCWIter hl_cwbegin(HalfedgeHandle _heh); /// halfedge circulator ccw - HalfedgeLoopCCWIter hl_ccwbegin(HalfedgeHandle _heh) - { return HalfedgeLoopCCWIter(*this, _heh); } + HalfedgeLoopCCWIter hl_ccwbegin(HalfedgeHandle _heh); /// const face - vertex circulator - ConstFaceVertexIter cfv_begin(FaceHandle _fh) const - { return ConstFaceVertexIter(*this, _fh); } + ConstFaceVertexIter cfv_begin(FaceHandle _fh) const; /// const face - vertex circulator cw - ConstFaceVertexCWIter cfv_cwbegin(FaceHandle _fh) const - { return ConstFaceVertexCWIter(*this, _fh); } + ConstFaceVertexCWIter cfv_cwbegin(FaceHandle _fh) const; /// const face - vertex circulator ccw - ConstFaceVertexCCWIter cfv_ccwbegin(FaceHandle _fh) const - { return ConstFaceVertexCCWIter(*this, _fh); } + ConstFaceVertexCCWIter cfv_ccwbegin(FaceHandle _fh) const; /// const face - halfedge circulator - ConstFaceHalfedgeIter cfh_begin(FaceHandle _fh) const - { return ConstFaceHalfedgeIter(*this, _fh); } + ConstFaceHalfedgeIter cfh_begin(FaceHandle _fh) const; /// const face - halfedge circulator cw - ConstFaceHalfedgeCWIter cfh_cwbegin(FaceHandle _fh) const - { return ConstFaceHalfedgeCWIter(*this, _fh); } + ConstFaceHalfedgeCWIter cfh_cwbegin(FaceHandle _fh) const; /// const face - halfedge circulator ccw - ConstFaceHalfedgeCCWIter cfh_ccwbegin(FaceHandle _fh) const - { return ConstFaceHalfedgeCCWIter(*this, _fh); } + ConstFaceHalfedgeCCWIter cfh_ccwbegin(FaceHandle _fh) const; /// const face - edge circulator - ConstFaceEdgeIter cfe_begin(FaceHandle _fh) const - { return ConstFaceEdgeIter(*this, _fh); } + ConstFaceEdgeIter cfe_begin(FaceHandle _fh) const; /// const face - edge circulator cw - ConstFaceEdgeCWIter cfe_cwbegin(FaceHandle _fh) const - { return ConstFaceEdgeCWIter(*this, _fh); } + ConstFaceEdgeCWIter cfe_cwbegin(FaceHandle _fh) const; /// const face - edge circulator ccw - ConstFaceEdgeCCWIter cfe_ccwbegin(FaceHandle _fh) const - { return ConstFaceEdgeCCWIter(*this, _fh); } + ConstFaceEdgeCCWIter cfe_ccwbegin(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceIter cff_begin(FaceHandle _fh) const - { return ConstFaceFaceIter(*this, _fh); } + ConstFaceFaceIter cff_begin(FaceHandle _fh) const; /// const face - face circulator cw - ConstFaceFaceCWIter cff_cwbegin(FaceHandle _fh) const - { return ConstFaceFaceCWIter(*this, _fh); } + ConstFaceFaceCWIter cff_cwbegin(FaceHandle _fh) const; /// const face - face circulator ccw - ConstFaceFaceCCWIter cff_ccwbegin(FaceHandle _fh) const - { return ConstFaceFaceCCWIter(*this, _fh); } + ConstFaceFaceCCWIter cff_ccwbegin(FaceHandle _fh) const; /// const halfedge circulator - ConstHalfedgeLoopIter chl_begin(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopIter(*this, _heh); } + ConstHalfedgeLoopIter chl_begin(HalfedgeHandle _heh) const; /// const halfedge circulator cw - ConstHalfedgeLoopCWIter chl_cwbegin(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopCWIter(*this, _heh); } + ConstHalfedgeLoopCWIter chl_cwbegin(HalfedgeHandle _heh) const; /// const halfedge circulator ccw - ConstHalfedgeLoopCCWIter chl_ccwbegin(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopCCWIter(*this, _heh); } + ConstHalfedgeLoopCCWIter chl_ccwbegin(HalfedgeHandle _heh) const; // 'end' circulators /// vertex - vertex circulator - VertexVertexIter vv_end(VertexHandle _vh) - { return VertexVertexIter(*this, _vh, true); } + VertexVertexIter vv_end(VertexHandle _vh); /// vertex - vertex circulator cw - VertexVertexCWIter vv_cwend(VertexHandle _vh) - { return VertexVertexCWIter(*this, _vh, true); } + VertexVertexCWIter vv_cwend(VertexHandle _vh); /// vertex - vertex circulator ccw - VertexVertexCCWIter vv_ccwend(VertexHandle _vh) - { return VertexVertexCCWIter(*this, _vh, true); } + VertexVertexCCWIter vv_ccwend(VertexHandle _vh); /// vertex - incoming halfedge circulator - VertexIHalfedgeIter vih_end(VertexHandle _vh) - { return VertexIHalfedgeIter(*this, _vh, true); } + VertexIHalfedgeIter vih_end(VertexHandle _vh); /// vertex - incoming halfedge circulator cw - VertexIHalfedgeCWIter vih_cwend(VertexHandle _vh) - { return VertexIHalfedgeCWIter(*this, _vh, true); } + VertexIHalfedgeCWIter vih_cwend(VertexHandle _vh); /// vertex - incoming halfedge circulator ccw - VertexIHalfedgeCCWIter vih_ccwend(VertexHandle _vh) - { return VertexIHalfedgeCCWIter(*this, _vh, true); } + VertexIHalfedgeCCWIter vih_ccwend(VertexHandle _vh); /// vertex - outgoing halfedge circulator - VertexOHalfedgeIter voh_end(VertexHandle _vh) - { return VertexOHalfedgeIter(*this, _vh, true); } + VertexOHalfedgeIter voh_end(VertexHandle _vh); /// vertex - outgoing halfedge circulator cw - VertexOHalfedgeCWIter voh_cwend(VertexHandle _vh) - { return VertexOHalfedgeCWIter(*this, _vh, true); } + VertexOHalfedgeCWIter voh_cwend(VertexHandle _vh); /// vertex - outgoing halfedge circulator ccw - VertexOHalfedgeCCWIter voh_ccwend(VertexHandle _vh) - { return VertexOHalfedgeCCWIter(*this, _vh, true); } + VertexOHalfedgeCCWIter voh_ccwend(VertexHandle _vh); /// vertex - edge circulator - VertexEdgeIter ve_end(VertexHandle _vh) - { return VertexEdgeIter(*this, _vh, true); } + VertexEdgeIter ve_end(VertexHandle _vh); /// vertex - edge circulator cw - VertexEdgeCWIter ve_cwend(VertexHandle _vh) - { return VertexEdgeCWIter(*this, _vh, true); } + VertexEdgeCWIter ve_cwend(VertexHandle _vh); /// vertex - edge circulator ccw - VertexEdgeCCWIter ve_ccwend(VertexHandle _vh) - { return VertexEdgeCCWIter(*this, _vh, true); } + VertexEdgeCCWIter ve_ccwend(VertexHandle _vh); /// vertex - face circulator - VertexFaceIter vf_end(VertexHandle _vh) - { return VertexFaceIter(*this, _vh, true); } + VertexFaceIter vf_end(VertexHandle _vh); /// vertex - face circulator cw - VertexFaceCWIter vf_cwend(VertexHandle _vh) - { return VertexFaceCWIter(*this, _vh, true); } + VertexFaceCWIter vf_cwend(VertexHandle _vh); /// vertex - face circulator ccw - VertexFaceCCWIter vf_ccwend(VertexHandle _vh) - { return VertexFaceCCWIter(*this, _vh, true); } + VertexFaceCCWIter vf_ccwend(VertexHandle _vh); /// const vertex circulator - ConstVertexVertexIter cvv_end(VertexHandle _vh) const - { return ConstVertexVertexIter(*this, _vh, true); } + ConstVertexVertexIter cvv_end(VertexHandle _vh) const; /// const vertex circulator cw - ConstVertexVertexCWIter cvv_cwend(VertexHandle _vh) const - { return ConstVertexVertexCWIter(*this, _vh, true); } + ConstVertexVertexCWIter cvv_cwend(VertexHandle _vh) const; /// const vertex circulator ccw - ConstVertexVertexCCWIter cvv_ccwend(VertexHandle _vh) const - { return ConstVertexVertexCCWIter(*this, _vh, true); } + ConstVertexVertexCCWIter cvv_ccwend(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator - ConstVertexIHalfedgeIter cvih_end(VertexHandle _vh) const - { return ConstVertexIHalfedgeIter(*this, _vh, true); } + ConstVertexIHalfedgeIter cvih_end(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator cw - ConstVertexIHalfedgeCWIter cvih_cwend(VertexHandle _vh) const - { return ConstVertexIHalfedgeCWIter(*this, _vh, true); } + ConstVertexIHalfedgeCWIter cvih_cwend(VertexHandle _vh) const; /// const vertex - incoming halfedge circulator ccw - ConstVertexIHalfedgeCCWIter cvih_ccwend(VertexHandle _vh) const - { return ConstVertexIHalfedgeCCWIter(*this, _vh, true); } + ConstVertexIHalfedgeCCWIter cvih_ccwend(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator - ConstVertexOHalfedgeIter cvoh_end(VertexHandle _vh) const - { return ConstVertexOHalfedgeIter(*this, _vh, true); } + ConstVertexOHalfedgeIter cvoh_end(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator cw - ConstVertexOHalfedgeCWIter cvoh_cwend(VertexHandle _vh) const - { return ConstVertexOHalfedgeCWIter(*this, _vh, true); } + ConstVertexOHalfedgeCWIter cvoh_cwend(VertexHandle _vh) const; /// const vertex - outgoing halfedge circulator ccw - ConstVertexOHalfedgeCCWIter cvoh_ccwend(VertexHandle _vh) const - { return ConstVertexOHalfedgeCCWIter(*this, _vh, true); } + ConstVertexOHalfedgeCCWIter cvoh_ccwend(VertexHandle _vh) const; /// const vertex - edge circulator - ConstVertexEdgeIter cve_end(VertexHandle _vh) const - { return ConstVertexEdgeIter(*this, _vh, true); } + ConstVertexEdgeIter cve_end(VertexHandle _vh) const; /// const vertex - edge circulator cw - ConstVertexEdgeCWIter cve_cwend(VertexHandle _vh) const - { return ConstVertexEdgeCWIter(*this, _vh, true); } + ConstVertexEdgeCWIter cve_cwend(VertexHandle _vh) const; /// const vertex - edge circulator ccw - ConstVertexEdgeCCWIter cve_ccwend(VertexHandle _vh) const - { return ConstVertexEdgeCCWIter(*this, _vh, true); } + ConstVertexEdgeCCWIter cve_ccwend(VertexHandle _vh) const; /// const vertex - face circulator - ConstVertexFaceIter cvf_end(VertexHandle _vh) const - { return ConstVertexFaceIter(*this, _vh, true); } + ConstVertexFaceIter cvf_end(VertexHandle _vh) const; /// const vertex - face circulator cw - ConstVertexFaceCWIter cvf_cwend(VertexHandle _vh) const - { return ConstVertexFaceCWIter(*this, _vh, true); } + ConstVertexFaceCWIter cvf_cwend(VertexHandle _vh) const; /// const vertex - face circulator ccw - ConstVertexFaceCCWIter cvf_ccwend(VertexHandle _vh) const - { return ConstVertexFaceCCWIter(*this, _vh, true); } + ConstVertexFaceCCWIter cvf_ccwend(VertexHandle _vh) const; /// face - vertex circulator - FaceVertexIter fv_end(FaceHandle _fh) - { return FaceVertexIter(*this, _fh, true); } + FaceVertexIter fv_end(FaceHandle _fh); /// face - vertex circulator cw - FaceVertexCWIter fv_cwend(FaceHandle _fh) - { return FaceVertexCWIter(*this, _fh, true); } + FaceVertexCWIter fv_cwend(FaceHandle _fh); /// face - vertex circulator ccw - FaceVertexCCWIter fv_ccwend(FaceHandle _fh) - { return FaceVertexCCWIter(*this, _fh, true); } + FaceVertexCCWIter fv_ccwend(FaceHandle _fh); /// face - halfedge circulator - FaceHalfedgeIter fh_end(FaceHandle _fh) - { return FaceHalfedgeIter(*this, _fh, true); } + FaceHalfedgeIter fh_end(FaceHandle _fh); /// face - halfedge circulator cw - FaceHalfedgeCWIter fh_cwend(FaceHandle _fh) - { return FaceHalfedgeCWIter(*this, _fh, true); } + FaceHalfedgeCWIter fh_cwend(FaceHandle _fh); /// face - halfedge circulator ccw - FaceHalfedgeCCWIter fh_ccwend(FaceHandle _fh) - { return FaceHalfedgeCCWIter(*this, _fh, true); } + FaceHalfedgeCCWIter fh_ccwend(FaceHandle _fh); /// face - edge circulator - FaceEdgeIter fe_end(FaceHandle _fh) - { return FaceEdgeIter(*this, _fh, true); } + FaceEdgeIter fe_end(FaceHandle _fh); /// face - edge circulator cw - FaceEdgeCWIter fe_cwend(FaceHandle _fh) - { return FaceEdgeCWIter(*this, _fh, true); } + FaceEdgeCWIter fe_cwend(FaceHandle _fh); /// face - edge circulator ccw - FaceEdgeCCWIter fe_ccwend(FaceHandle _fh) - { return FaceEdgeCCWIter(*this, _fh, true); } + FaceEdgeCCWIter fe_ccwend(FaceHandle _fh); /// face - face circulator - FaceFaceIter ff_end(FaceHandle _fh) - { return FaceFaceIter(*this, _fh, true); } + FaceFaceIter ff_end(FaceHandle _fh); /// face - face circulator cw - FaceFaceCWIter ff_cwend(FaceHandle _fh) - { return FaceFaceCWIter(*this, _fh, true); } + FaceFaceCWIter ff_cwend(FaceHandle _fh); /// face - face circulator ccw - FaceFaceCCWIter ff_ccwend(FaceHandle _fh) - { return FaceFaceCCWIter(*this, _fh, true); } + FaceFaceCCWIter ff_ccwend(FaceHandle _fh); /// face - face circulator - HalfedgeLoopIter hl_end(HalfedgeHandle _heh) - { return HalfedgeLoopIter(*this, _heh, true); } + HalfedgeLoopIter hl_end(HalfedgeHandle _heh); /// face - face circulator cw - HalfedgeLoopCWIter hl_cwend(HalfedgeHandle _heh) - { return HalfedgeLoopCWIter(*this, _heh, true); } + HalfedgeLoopCWIter hl_cwend(HalfedgeHandle _heh); /// face - face circulator ccw - HalfedgeLoopCCWIter hl_ccwend(HalfedgeHandle _heh) - { return HalfedgeLoopCCWIter(*this, _heh, true); } + HalfedgeLoopCCWIter hl_ccwend(HalfedgeHandle _heh); /// const face - vertex circulator - ConstFaceVertexIter cfv_end(FaceHandle _fh) const - { return ConstFaceVertexIter(*this, _fh, true); } + ConstFaceVertexIter cfv_end(FaceHandle _fh) const; /// const face - vertex circulator cw - ConstFaceVertexCWIter cfv_cwend(FaceHandle _fh) const - { return ConstFaceVertexCWIter(*this, _fh, true); } + ConstFaceVertexCWIter cfv_cwend(FaceHandle _fh) const; /// const face - vertex circulator ccw - ConstFaceVertexCCWIter cfv_ccwend(FaceHandle _fh) const - { return ConstFaceVertexCCWIter(*this, _fh, true); } + ConstFaceVertexCCWIter cfv_ccwend(FaceHandle _fh) const; /// const face - halfedge circulator - ConstFaceHalfedgeIter cfh_end(FaceHandle _fh) const - { return ConstFaceHalfedgeIter(*this, _fh, true); } + ConstFaceHalfedgeIter cfh_end(FaceHandle _fh) const; /// const face - halfedge circulator cw - ConstFaceHalfedgeCWIter cfh_cwend(FaceHandle _fh) const - { return ConstFaceHalfedgeCWIter(*this, _fh, true); } + ConstFaceHalfedgeCWIter cfh_cwend(FaceHandle _fh) const; /// const face - halfedge circulator ccw - ConstFaceHalfedgeCCWIter cfh_ccwend(FaceHandle _fh) const - { return ConstFaceHalfedgeCCWIter(*this, _fh, true); } + ConstFaceHalfedgeCCWIter cfh_ccwend(FaceHandle _fh) const; /// const face - edge circulator - ConstFaceEdgeIter cfe_end(FaceHandle _fh) const - { return ConstFaceEdgeIter(*this, _fh, true); } + ConstFaceEdgeIter cfe_end(FaceHandle _fh) const; /// const face - edge circulator cw - ConstFaceEdgeCWIter cfe_cwend(FaceHandle _fh) const - { return ConstFaceEdgeCWIter(*this, _fh, true); } + ConstFaceEdgeCWIter cfe_cwend(FaceHandle _fh) const; /// const face - edge circulator ccw - ConstFaceEdgeCCWIter cfe_ccwend(FaceHandle _fh) const - { return ConstFaceEdgeCCWIter(*this, _fh, true); } + ConstFaceEdgeCCWIter cfe_ccwend(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceIter cff_end(FaceHandle _fh) const - { return ConstFaceFaceIter(*this, _fh, true); } + ConstFaceFaceIter cff_end(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceCWIter cff_cwend(FaceHandle _fh) const - { return ConstFaceFaceCWIter(*this, _fh, true); } + ConstFaceFaceCWIter cff_cwend(FaceHandle _fh) const; /// const face - face circulator - ConstFaceFaceCCWIter cff_ccwend(FaceHandle _fh) const - { return ConstFaceFaceCCWIter(*this, _fh, true); } + ConstFaceFaceCCWIter cff_ccwend(FaceHandle _fh) const; /// const face - face circulator - ConstHalfedgeLoopIter chl_end(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopIter(*this, _heh, true); } + ConstHalfedgeLoopIter chl_end(HalfedgeHandle _heh) const; /// const face - face circulator cw - ConstHalfedgeLoopCWIter chl_cwend(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopCWIter(*this, _heh, true); } + ConstHalfedgeLoopCWIter chl_cwend(HalfedgeHandle _heh) const; /// const face - face circulator ccw - ConstHalfedgeLoopCCWIter chl_ccwend(HalfedgeHandle _heh) const - { return ConstHalfedgeLoopCCWIter(*this, _heh, true); } + ConstHalfedgeLoopCCWIter chl_ccwend(HalfedgeHandle _heh) const; //@} /** @name Range based iterators and circulators */ @@ -1625,5 +1488,617 @@ private: // Working storage for add_face() }//namespace OpenMesh #include +#include + +namespace OpenMesh { + + +inline PolyConnectivity::VertexIter PolyConnectivity::vertices_begin() +{ return VertexIter(*this, VertexHandle(0)); } + +inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_begin() const +{ return ConstVertexIter(*this, VertexHandle(0)); } + +inline PolyConnectivity::VertexIter PolyConnectivity::vertices_end() +{ return VertexIter(*this, VertexHandle( int(n_vertices() ) )); } + +inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_end() const +{ return ConstVertexIter(*this, VertexHandle( int(n_vertices()) )); } + +inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_begin() +{ return HalfedgeIter(*this, HalfedgeHandle(0)); } + +inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_begin() const +{ return ConstHalfedgeIter(*this, HalfedgeHandle(0)); } + +inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_end() +{ return HalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); } + +inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_end() const +{ return ConstHalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); } + +inline PolyConnectivity::EdgeIter PolyConnectivity::edges_begin() +{ return EdgeIter(*this, EdgeHandle(0)); } + +inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_begin() const +{ return ConstEdgeIter(*this, EdgeHandle(0)); } + +inline PolyConnectivity::EdgeIter PolyConnectivity::edges_end() +{ return EdgeIter(*this, EdgeHandle(int(n_edges()))); } + +inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_end() const +{ return ConstEdgeIter(*this, EdgeHandle(int(n_edges()))); } + +inline PolyConnectivity::FaceIter PolyConnectivity::faces_begin() +{ return FaceIter(*this, FaceHandle(0)); } + +inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_begin() const +{ return ConstFaceIter(*this, FaceHandle(0)); } + +inline PolyConnectivity::FaceIter PolyConnectivity::faces_end() +{ return FaceIter(*this, FaceHandle(int(n_faces()))); } + + +inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const +{ return ConstFaceIter(*this, FaceHandle(int(n_faces()))); } + +inline PolyConnectivity::VertexIter PolyConnectivity::vertices_sbegin() +{ return VertexIter(*this, VertexHandle(0), true); } + +inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_sbegin() const +{ return ConstVertexIter(*this, VertexHandle(0), true); } + +inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_sbegin() +{ return HalfedgeIter(*this, HalfedgeHandle(0), true); } + +inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_sbegin() const +{ return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); } + +inline PolyConnectivity::EdgeIter PolyConnectivity::edges_sbegin() +{ return EdgeIter(*this, EdgeHandle(0), true); } + +inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_sbegin() const +{ return ConstEdgeIter(*this, EdgeHandle(0), true); } + +inline PolyConnectivity::FaceIter PolyConnectivity::faces_sbegin() +{ return FaceIter(*this, FaceHandle(0), true); } + +inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_sbegin() const +{ return ConstFaceIter(*this, FaceHandle(0), true); } + +inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_iter(ArrayKernel::VertexHandle _vh) +{ return VertexVertexIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_iter(ArrayKernel::VertexHandle _vh) +{ return VertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_iter(ArrayKernel::VertexHandle _vh) +{ return VertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_iter(ArrayKernel::VertexHandle _vh) +{ return VertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_iter(ArrayKernel::VertexHandle _vh) +{ return VertexFaceIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexFaceCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexVertexIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexFaceIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexFaceCCWIter(*this, _vh); } + +inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_iter(ArrayKernel::FaceHandle _fh) +{ return FaceVertexIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_iter(ArrayKernel::FaceHandle _fh) +{ return FaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_iter(ArrayKernel::FaceHandle _fh) +{ return FaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_iter(ArrayKernel::FaceHandle _fh) +{ return FaceFaceIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceFaceCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceVertexIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceFaceIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceFaceCCWIter(*this, _fh); } + + +inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_begin(VertexHandle _vh) +{ return VertexVertexIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwbegin(VertexHandle _vh) +{ return VertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwbegin(VertexHandle _vh) +{ return VertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_begin(VertexHandle _vh) +{ return VertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwbegin(VertexHandle _vh) +{ return VertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwbegin(VertexHandle _vh) +{ return VertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_begin(VertexHandle _vh) +{ return VertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwbegin(VertexHandle _vh) +{ return VertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwbegin(VertexHandle _vh) +{ return VertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_begin(VertexHandle _vh) +{ return VertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwbegin(VertexHandle _vh) +{ return VertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwbegin(VertexHandle _vh) +{ return VertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_begin(VertexHandle _vh) +{ return VertexFaceIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwbegin(VertexHandle _vh) +{ return VertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwbegin(VertexHandle _vh) +{ return VertexFaceCCWIter(*this, _vh); } + + +inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_begin(VertexHandle _vh) const +{ return ConstVertexVertexIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwbegin(VertexHandle _vh) const +{ return ConstVertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwbegin(VertexHandle _vh) const +{ return ConstVertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_begin(VertexHandle _vh) const +{ return ConstVertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwbegin(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwbegin(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_begin(VertexHandle _vh) const +{ return ConstVertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwbegin(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwbegin(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_begin(VertexHandle _vh) const +{ return ConstVertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwbegin(VertexHandle _vh) const +{ return ConstVertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwbegin(VertexHandle _vh) const +{ return ConstVertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_begin(VertexHandle _vh) const +{ return ConstVertexFaceIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwbegin(VertexHandle _vh) const +{ return ConstVertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwbegin(VertexHandle _vh) const +{ return ConstVertexFaceCCWIter(*this, _vh); } + + +inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_begin(FaceHandle _fh) +{ return FaceVertexIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwbegin(FaceHandle _fh) +{ return FaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwbegin(FaceHandle _fh) +{ return FaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_begin(FaceHandle _fh) +{ return FaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwbegin(FaceHandle _fh) +{ return FaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwbegin(FaceHandle _fh) +{ return FaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_begin(FaceHandle _fh) +{ return FaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwbegin(FaceHandle _fh) +{ return FaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwbegin(FaceHandle _fh) +{ return FaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_begin(FaceHandle _fh) +{ return FaceFaceIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwbegin(FaceHandle _fh) +{ return FaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwbegin(FaceHandle _fh) +{ return FaceFaceCCWIter(*this, _fh); } + +inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_begin(HalfedgeHandle _heh) +{ return HalfedgeLoopIter(*this, _heh); } + +inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwbegin(HalfedgeHandle _heh) +{ return HalfedgeLoopCWIter(*this, _heh); } + +inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwbegin(HalfedgeHandle _heh) +{ return HalfedgeLoopCCWIter(*this, _heh); } + + +inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_begin(FaceHandle _fh) const +{ return ConstFaceVertexIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwbegin(FaceHandle _fh) const +{ return ConstFaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwbegin(FaceHandle _fh) const +{ return ConstFaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_begin(FaceHandle _fh) const +{ return ConstFaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwbegin(FaceHandle _fh) const +{ return ConstFaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwbegin(FaceHandle _fh) const +{ return ConstFaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_begin(FaceHandle _fh) const +{ return ConstFaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwbegin(FaceHandle _fh) const +{ return ConstFaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwbegin(FaceHandle _fh) const +{ return ConstFaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_begin(FaceHandle _fh) const +{ return ConstFaceFaceIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwbegin(FaceHandle _fh) const +{ return ConstFaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwbegin(FaceHandle _fh) const +{ return ConstFaceFaceCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_begin(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopIter(*this, _heh); } + +inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwbegin(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCWIter(*this, _heh); } + +inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwbegin(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCCWIter(*this, _heh); } + +// 'end' circulators + +inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_end(VertexHandle _vh) +{ return VertexVertexIter(*this, _vh, true); } + +inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwend(VertexHandle _vh) +{ return VertexVertexCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwend(VertexHandle _vh) +{ return VertexVertexCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_end(VertexHandle _vh) +{ return VertexIHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwend(VertexHandle _vh) +{ return VertexIHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwend(VertexHandle _vh) +{ return VertexIHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_end(VertexHandle _vh) +{ return VertexOHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwend(VertexHandle _vh) +{ return VertexOHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwend(VertexHandle _vh) +{ return VertexOHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_end(VertexHandle _vh) +{ return VertexEdgeIter(*this, _vh, true); } + +inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwend(VertexHandle _vh) +{ return VertexEdgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwend(VertexHandle _vh) +{ return VertexEdgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_end(VertexHandle _vh) +{ return VertexFaceIter(*this, _vh, true); } + +inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwend(VertexHandle _vh) +{ return VertexFaceCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwend(VertexHandle _vh) +{ return VertexFaceCCWIter(*this, _vh, true); } + + +inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_end(VertexHandle _vh) const +{ return ConstVertexVertexIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwend(VertexHandle _vh) const +{ return ConstVertexVertexCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwend(VertexHandle _vh) const +{ return ConstVertexVertexCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_end(VertexHandle _vh) const +{ return ConstVertexIHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwend(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwend(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_end(VertexHandle _vh) const +{ return ConstVertexOHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwend(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwend(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_end(VertexHandle _vh) const +{ return ConstVertexEdgeIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwend(VertexHandle _vh) const +{ return ConstVertexEdgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwend(VertexHandle _vh) const +{ return ConstVertexEdgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_end(VertexHandle _vh) const +{ return ConstVertexFaceIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwend(VertexHandle _vh) const +{ return ConstVertexFaceCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwend(VertexHandle _vh) const +{ return ConstVertexFaceCCWIter(*this, _vh, true); } + + +inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_end(FaceHandle _fh) +{ return FaceVertexIter(*this, _fh, true); } + +inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwend(FaceHandle _fh) +{ return FaceVertexCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwend(FaceHandle _fh) +{ return FaceVertexCCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_end(FaceHandle _fh) +{ return FaceHalfedgeIter(*this, _fh, true); } + +inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwend(FaceHandle _fh) +{ return FaceHalfedgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwend(FaceHandle _fh) +{ return FaceHalfedgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_end(FaceHandle _fh) +{ return FaceEdgeIter(*this, _fh, true); } + +inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwend(FaceHandle _fh) +{ return FaceEdgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwend(FaceHandle _fh) +{ return FaceEdgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_end(FaceHandle _fh) +{ return FaceFaceIter(*this, _fh, true); } + +inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwend(FaceHandle _fh) +{ return FaceFaceCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwend(FaceHandle _fh) +{ return FaceFaceCCWIter(*this, _fh, true); } + +inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_end(HalfedgeHandle _heh) +{ return HalfedgeLoopIter(*this, _heh, true); } + +inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwend(HalfedgeHandle _heh) +{ return HalfedgeLoopCWIter(*this, _heh, true); } + +inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwend(HalfedgeHandle _heh) +{ return HalfedgeLoopCCWIter(*this, _heh, true); } + + +inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_end(FaceHandle _fh) const +{ return ConstFaceVertexIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwend(FaceHandle _fh) const +{ return ConstFaceVertexCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwend(FaceHandle _fh) const +{ return ConstFaceVertexCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_end(FaceHandle _fh) const +{ return ConstFaceHalfedgeIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwend(FaceHandle _fh) const +{ return ConstFaceHalfedgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwend(FaceHandle _fh) const +{ return ConstFaceHalfedgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_end(FaceHandle _fh) const +{ return ConstFaceEdgeIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwend(FaceHandle _fh) const +{ return ConstFaceEdgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwend(FaceHandle _fh) const +{ return ConstFaceEdgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_end(FaceHandle _fh) const +{ return ConstFaceFaceIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwend(FaceHandle _fh) const +{ return ConstFaceFaceCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwend(FaceHandle _fh) const +{ return ConstFaceFaceCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_end(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopIter(*this, _heh, true); } + +inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwend(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCWIter(*this, _heh, true); } + +inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwend(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCCWIter(*this, _heh, true); } + + +}//namespace OpenMesh + #endif//OPENMESH_POLYCONNECTIVITY_HH diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc index 3ddb5fbe..65aa80c0 100644 --- a/src/Unittests/unittests_smart_handles.cc +++ b/src/Unittests/unittests_smart_handles.cc @@ -284,6 +284,103 @@ TEST_F(OpenMeshSmartHandles, SimpleRanges) } } +/* Test if ranges yield the same elements when using smart handles + */ +TEST_F(OpenMeshSmartHandles, RangesOfRanges) +{ + for (auto vh : mesh_.vertices()) + { + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.vv_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.vertices()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "vertex range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.voh_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.outgoing_halfedges()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "outgoing halfedge range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.vih_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.incoming_halfedges()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "incoming halfedge range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.ve_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.edges()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "edge range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vv_range(vh)) + for (auto h2 : mesh_.vf_range(h)) + handles0.push_back(h2); + for (auto h : vh.vertices()) + for (auto h2 : h.faces()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "face range of vertex range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vf_range(vh)) + for (auto h2 : mesh_.fv_range(h)) + handles0.push_back(h2); + for (auto h : vh.faces()) + for (auto h2 : h.vertices()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "vertex range of face range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vf_range(vh)) + for (auto h2 : mesh_.fh_range(h)) + handles0.push_back(h2); + for (auto h : vh.faces()) + for (auto h2 : h.halfedges()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "vertex range of face range does not match"; + } + { + std::vector handles0; + std::vector handles1; + for (auto h : mesh_.vf_range(vh)) + for (auto h2 : mesh_.ff_range(h)) + handles0.push_back(h2); + for (auto h : vh.faces()) + for (auto h2 : h.faces()) + handles1.push_back(h2); + EXPECT_EQ(handles0, handles1) << "vertex range of face range does not match"; + } + } +} + /* Test a chain of navigation on a cube */ From 16ca9b363ef474d22d7d7e72b1c302c22e481acc Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 09:38:09 +0200 Subject: [PATCH 10/60] fix circulator return value in debug mode --- src/OpenMesh/Core/Mesh/CirculatorsT.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/CirculatorsT.hh b/src/OpenMesh/Core/Mesh/CirculatorsT.hh index 97b90732..3e559235 100644 --- a/src/OpenMesh/Core/Mesh/CirculatorsT.hh +++ b/src/OpenMesh/Core/Mesh/CirculatorsT.hh @@ -321,7 +321,7 @@ class GenericCirculatorT : protected GenericCirculatorBaseTheh_.is_valid()); value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_); assert(res.is_valid()); - return res; + return make_smart(res, this->mesh_); #else return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_); #endif @@ -510,7 +510,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseTheh_.is_valid()); value_type res = (self->GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_); assert(res.is_valid()); - return res; + return make_smart(res, this->mesh_); #else return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_); #endif From 8446eaee6f84b714d90bbb571cda3588d68db3a7 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 10:38:56 +0200 Subject: [PATCH 11/60] fix more issues for debug builds --- src/OpenMesh/Core/Mesh/CirculatorsT.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/CirculatorsT.hh b/src/OpenMesh/Core/Mesh/CirculatorsT.hh index 3e559235..4ae25858 100644 --- a/src/OpenMesh/Core/Mesh/CirculatorsT.hh +++ b/src/OpenMesh/Core/Mesh/CirculatorsT.hh @@ -508,7 +508,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT* self = this; #ifndef NDEBUG assert(this->heh_.is_valid()); - value_type res = (self->GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_); + value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_)); assert(res.is_valid()); return make_smart(res, this->mesh_); #else From e0d8f2dbe04beaaf9d52e8e7582886dc0b7ffcf8 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 10:39:10 +0200 Subject: [PATCH 12/60] use fewer iterations in performance test of smart handles when in debug build --- src/Unittests/unittests_smart_handles.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc index 65aa80c0..2979b327 100644 --- a/src/Unittests/unittests_smart_handles.cc +++ b/src/Unittests/unittests_smart_handles.cc @@ -415,7 +415,11 @@ TEST_F(OpenMeshSmartHandles, ComplicatedNavigtaion) */ TEST_F(OpenMeshSmartHandles, Performance) { +#if DEBUG + int n_tests = 300000; +#else int n_tests = 10000000; +#endif auto t_before_old = std::chrono::high_resolution_clock::now(); From 011a53e7ba1ac6dcabe4746755e9b43c7666d43c Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 12:55:57 +0200 Subject: [PATCH 13/60] let handle function of circulator return smart handle --- src/OpenMesh/Core/Mesh/CirculatorsT.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/CirculatorsT.hh b/src/OpenMesh/Core/Mesh/CirculatorsT.hh index 4ae25858..6436ae61 100644 --- a/src/OpenMesh/Core/Mesh/CirculatorsT.hh +++ b/src/OpenMesh/Core/Mesh/CirculatorsT.hh @@ -572,7 +572,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT and * instead. */ OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.") - value_type handle() const { + smart_value_type handle() const { return **this; } From aa91a88f7b46832ad1216fa3ac86bd9f71f0d092 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 14:12:22 +0200 Subject: [PATCH 14/60] add first version of smart ranges --- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 271 +++++++++++++-------- src/OpenMesh/Core/Mesh/SmartRange.hh | 84 +++++++ src/Unittests/unittests_smart_ranges.cc | 196 +++++++++++++++ 3 files changed, 453 insertions(+), 98 deletions(-) create mode 100644 src/OpenMesh/Core/Mesh/SmartRange.hh create mode 100644 src/Unittests/unittests_smart_ranges.cc diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index bdce69b5..d8adcd15 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -45,6 +45,7 @@ #define OPENMESH_POLYCONNECTIVITY_HH #include +#include namespace OpenMesh { @@ -64,6 +65,42 @@ namespace Iterators class GenericCirculatorT; } +template +class EntityRange; + +template< + typename CONTAINER_T, + typename ITER_T, + ITER_T (CONTAINER_T::*begin_fn)() const, + ITER_T (CONTAINER_T::*end_fn)() const> +struct RangeTraitT +{ + using CONTAINER_TYPE = CONTAINER_T; + using ITER_TYPE = ITER_T; + static ITER_TYPE begin(const CONTAINER_TYPE& _container) { return (_container.*begin_fn)(); } + static ITER_TYPE end(const CONTAINER_TYPE& _container) { return (_container.*end_fn)(); } +}; + + +template< + typename CONTAINER_T, + typename ITER_T, + typename CENTER_ENTITY_T, + typename TO_ENTITY_T, + ITER_T (CONTAINER_T::*begin_fn)(CENTER_ENTITY_T) const, + ITER_T (CONTAINER_T::*end_fn)(CENTER_ENTITY_T) const> +struct CirculatorRangeTraitT +{ + using CONTAINER_TYPE = CONTAINER_T; + using ITER_TYPE = ITER_T; + using CENTER_ENTITY_TYPE = CENTER_ENTITY_T; + using TO_ENTITYE_TYPE = TO_ENTITY_T; + static ITER_TYPE begin(const CONTAINER_TYPE& _container, CENTER_ENTITY_TYPE _ce) { return (_container.*begin_fn)(_ce); } + static ITER_TYPE end(const CONTAINER_TYPE& _container, CENTER_ENTITY_TYPE _ce) { return (_container.*end_fn)(_ce); } +}; + + + /** \brief Connectivity Class for polygonal meshes */ class OPENMESHDLLEXPORT PolyConnectivity : public ArrayKernel @@ -970,122 +1007,104 @@ public: /** @name Range based iterators and circulators */ //@{ - /// Generic class for vertex/halfedge/edge/face ranges. - template< - typename CONTAINER_TYPE, - typename ITER_TYPE, - ITER_TYPE (CONTAINER_TYPE::*begin_fn)() const, - ITER_TYPE (CONTAINER_TYPE::*end_fn)() const> - class EntityRange { - public: - typedef ITER_TYPE iterator; - typedef ITER_TYPE const_iterator; - - explicit EntityRange(CONTAINER_TYPE &container) : container_(container) {} - ITER_TYPE begin() const { return (container_.*begin_fn)(); } - ITER_TYPE end() const { return (container_.*end_fn)(); } - - private: - CONTAINER_TYPE &container_; - }; - typedef EntityRange< + typedef EntityRange ConstVertexRange; - typedef EntityRange< + &PolyConnectivity::vertices_end>> ConstVertexRange; + typedef EntityRange ConstVertexRangeSkipping; - typedef EntityRange< + &PolyConnectivity::vertices_end>> ConstVertexRangeSkipping; + typedef EntityRange ConstHalfedgeRange; - typedef EntityRange< + &PolyConnectivity::halfedges_end>> ConstHalfedgeRange; + typedef EntityRange ConstHalfedgeRangeSkipping; - typedef EntityRange< + &PolyConnectivity::halfedges_end>> ConstHalfedgeRangeSkipping; + typedef EntityRange ConstEdgeRange; - typedef EntityRange< + &PolyConnectivity::edges_end>> ConstEdgeRange; + typedef EntityRange ConstEdgeRangeSkipping; - typedef EntityRange< + &PolyConnectivity::edges_end>> ConstEdgeRangeSkipping; + typedef EntityRange ConstFaceRange; - typedef EntityRange< + &PolyConnectivity::faces_end>> ConstFaceRange; + typedef EntityRange ConstFaceRangeSkipping; + &PolyConnectivity::faces_end>> ConstFaceRangeSkipping; + /** * @return The vertices as a range object suitable * for C++11 range based for loops. Will skip deleted vertices. */ - ConstVertexRangeSkipping vertices() const { return ConstVertexRangeSkipping(*this); } + ConstVertexRangeSkipping vertices() const; /** * @return The vertices as a range object suitable * for C++11 range based for loops. Will include deleted vertices. */ - ConstVertexRange all_vertices() const { return ConstVertexRange(*this); } + ConstVertexRange all_vertices() const; /** * @return The halfedges as a range object suitable * for C++11 range based for loops. Will skip deleted halfedges. */ - ConstHalfedgeRangeSkipping halfedges() const { return ConstHalfedgeRangeSkipping(*this); } + ConstHalfedgeRangeSkipping halfedges() const; /** * @return The halfedges as a range object suitable * for C++11 range based for loops. Will include deleted halfedges. */ - ConstHalfedgeRange all_halfedges() const { return ConstHalfedgeRange(*this); } + ConstHalfedgeRange all_halfedges() const; /** * @return The edges as a range object suitable * for C++11 range based for loops. Will skip deleted edges. */ - ConstEdgeRangeSkipping edges() const { return ConstEdgeRangeSkipping(*this); } + ConstEdgeRangeSkipping edges() const; /** * @return The edges as a range object suitable * for C++11 range based for loops. Will include deleted edges. */ - ConstEdgeRange all_edges() const { return ConstEdgeRange(*this); } + ConstEdgeRange all_edges() const; /** * @return The faces as a range object suitable * for C++11 range based for loops. Will skip deleted faces. */ - ConstFaceRangeSkipping faces() const { return ConstFaceRangeSkipping(*this); } + ConstFaceRangeSkipping faces() const; /** * @return The faces as a range object suitable * for C++11 range based for loops. Will include deleted faces. */ - ConstFaceRange all_faces() const { return ConstFaceRange(*this); } + ConstFaceRange all_faces() const; + /// Generic class for iterator ranges. - template< - typename CONTAINER_TYPE, - typename ITER_TYPE, - typename CENTER_ENTITY_TYPE, - ITER_TYPE (CONTAINER_TYPE::*begin_fn)(CENTER_ENTITY_TYPE) const, - ITER_TYPE (CONTAINER_TYPE::*end_fn)(CENTER_ENTITY_TYPE) const> - class CirculatorRange { + template + class CirculatorRange : public SmartRangeT, typename CirculatorRangeTraitT::TO_ENTITYE_TYPE>{ public: + typedef typename CirculatorRangeTraitT::ITER_TYPE ITER_TYPE; + typedef typename CirculatorRangeTraitT::CENTER_ENTITY_TYPE CENTER_ENTITY_TYPE; + typedef typename CirculatorRangeTraitT::CONTAINER_TYPE CONTAINER_TYPE; typedef ITER_TYPE iterator; typedef ITER_TYPE const_iterator; @@ -1093,139 +1112,132 @@ public: const CONTAINER_TYPE &container, CENTER_ENTITY_TYPE center) : container_(container), center_(center) {} - ITER_TYPE begin() const { return (container_.*begin_fn)(center_); } - ITER_TYPE end() const { return (container_.*end_fn)(center_); } + ITER_TYPE begin() const { return CirculatorRangeTraitT::begin(container_, center_); } + ITER_TYPE end() const { return CirculatorRangeTraitT::end(container_, center_); } private: const CONTAINER_TYPE &container_; CENTER_ENTITY_TYPE center_; }; - typedef CirculatorRange< + + typedef CirculatorRange ConstVertexVertexRange; - typedef CirculatorRange< + &PolyConnectivity::cvv_cwend>> ConstVertexVertexRange; + typedef CirculatorRange ConstVertexIHalfedgeRange; - typedef CirculatorRange< + &PolyConnectivity::cvih_end>> ConstVertexIHalfedgeRange; + typedef CirculatorRange ConstVertexOHalfedgeRange; - typedef CirculatorRange< + &PolyConnectivity::cvoh_end>> ConstVertexOHalfedgeRange; + typedef CirculatorRange ConstVertexEdgeRange; - typedef CirculatorRange< + &PolyConnectivity::cve_end>> ConstVertexEdgeRange; + typedef CirculatorRange ConstVertexFaceRange; - typedef CirculatorRange< + &PolyConnectivity::cvf_end>> ConstVertexFaceRange; + typedef CirculatorRange ConstFaceVertexRange; - typedef CirculatorRange< + &PolyConnectivity::cfv_end>> ConstFaceVertexRange; + typedef CirculatorRange ConstFaceHalfedgeRange; - typedef CirculatorRange< + &PolyConnectivity::cfh_end>> ConstFaceHalfedgeRange; + typedef CirculatorRange ConstFaceEdgeRange; - typedef CirculatorRange< + &PolyConnectivity::cfe_end>> ConstFaceEdgeRange; + typedef CirculatorRange ConstFaceFaceRange; + &PolyConnectivity::cff_end>> ConstFaceFaceRange; /** * @return The vertices adjacent to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexVertexRange vv_range(VertexHandle _vh) const { - return ConstVertexVertexRange(*this, _vh); - } + ConstVertexVertexRange vv_range(VertexHandle _vh) const; /** * @return The incoming halfedges incident to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexIHalfedgeRange vih_range(VertexHandle _vh) const { - return ConstVertexIHalfedgeRange(*this, _vh); - } + ConstVertexIHalfedgeRange vih_range(VertexHandle _vh) const; /** * @return The outgoing halfedges incident to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexOHalfedgeRange voh_range(VertexHandle _vh) const { - return ConstVertexOHalfedgeRange(*this, _vh); - } + ConstVertexOHalfedgeRange voh_range(VertexHandle _vh) const; /** * @return The edges incident to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexEdgeRange ve_range(VertexHandle _vh) const { - return ConstVertexEdgeRange(*this, _vh); - } + ConstVertexEdgeRange ve_range(VertexHandle _vh) const ; /** * @return The faces incident to the specified vertex * as a range object suitable for C++11 range based for loops. */ - ConstVertexFaceRange vf_range(VertexHandle _vh) const { - return ConstVertexFaceRange(*this, _vh); - } + ConstVertexFaceRange vf_range(VertexHandle _vh) const; /** * @return The vertices incident to the specified face * as a range object suitable for C++11 range based for loops. */ - ConstFaceVertexRange fv_range(FaceHandle _fh) const { - return ConstFaceVertexRange(*this, _fh); - } + ConstFaceVertexRange fv_range(FaceHandle _fh) const; /** * @return The halfedges incident to the specified face * as a range object suitable for C++11 range based for loops. */ - ConstFaceHalfedgeRange fh_range(FaceHandle _fh) const { - return ConstFaceHalfedgeRange(*this, _fh); - } + ConstFaceHalfedgeRange fh_range(FaceHandle _fh) const; /** * @return The edges incident to the specified face * as a range object suitable for C++11 range based for loops. */ - ConstFaceEdgeRange fe_range(FaceHandle _fh) const { - return ConstFaceEdgeRange(*this, _fh); - } + ConstFaceEdgeRange fe_range(FaceHandle _fh) const; /** * @return The faces adjacent to the specified face * as a range object suitable for C++11 range based for loops. */ - ConstFaceFaceRange ff_range(FaceHandle _fh) const { - return ConstFaceFaceRange(*this, _fh); - } + ConstFaceFaceRange ff_range(FaceHandle _fh) const; //@} @@ -1487,11 +1499,74 @@ private: // Working storage for add_face() }//namespace OpenMesh + #include #include namespace OpenMesh { +/// Generic class for vertex/halfedge/edge/face ranges. +template +class EntityRange : public SmartRangeT, typename RangeTraitT::ITER_TYPE::value_handle> { + public: + typedef typename RangeTraitT::ITER_TYPE iterator; + typedef typename RangeTraitT::ITER_TYPE const_iterator; + + explicit EntityRange(typename RangeTraitT::CONTAINER_TYPE &container) : container_(container) {} + typename RangeTraitT::ITER_TYPE begin() const { return RangeTraitT::begin(container_); } + typename RangeTraitT::ITER_TYPE end() const { return RangeTraitT::end(container_); } + + private: + typename RangeTraitT::CONTAINER_TYPE &container_; +}; + + +inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::vertices() const { return ConstVertexRangeSkipping(*this); } +inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_vertices() const { return ConstVertexRange(*this); } +inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::halfedges() const { return ConstHalfedgeRangeSkipping(*this); } +inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_halfedges() const { return ConstHalfedgeRange(*this); } +inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::edges() const { return ConstEdgeRangeSkipping(*this); } +inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_edges() const { return ConstEdgeRange(*this); } +inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::faces() const { return ConstFaceRangeSkipping(*this); } +inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_faces() const { return ConstFaceRange(*this); } + +inline PolyConnectivity::ConstVertexVertexRange PolyConnectivity::vv_range(VertexHandle _vh) const { + return ConstVertexVertexRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexIHalfedgeRange PolyConnectivity::vih_range(VertexHandle _vh) const { + return ConstVertexIHalfedgeRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexOHalfedgeRange PolyConnectivity::voh_range(VertexHandle _vh) const { + return ConstVertexOHalfedgeRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexEdgeRange PolyConnectivity::ve_range(VertexHandle _vh) const { + return ConstVertexEdgeRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexFaceRange PolyConnectivity::vf_range(VertexHandle _vh) const { + return ConstVertexFaceRange(*this, _vh); +} + +inline PolyConnectivity::ConstFaceVertexRange PolyConnectivity::fv_range(FaceHandle _fh) const { + return ConstFaceVertexRange(*this, _fh); +} + +inline PolyConnectivity::ConstFaceHalfedgeRange PolyConnectivity::fh_range(FaceHandle _fh) const { + return ConstFaceHalfedgeRange(*this, _fh); +} + +inline PolyConnectivity::ConstFaceEdgeRange PolyConnectivity::fe_range(FaceHandle _fh) const { + return ConstFaceEdgeRange(*this, _fh); +} + +inline PolyConnectivity::ConstFaceFaceRange PolyConnectivity::ff_range(FaceHandle _fh) const { + return ConstFaceFaceRange(*this, _fh); +} + + inline PolyConnectivity::VertexIter PolyConnectivity::vertices_begin() { return VertexIter(*this, VertexHandle(0)); } diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh new file mode 100644 index 00000000..fdb2b15b --- /dev/null +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -0,0 +1,84 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2019, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + + +#pragma once + +#include + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//== FORWARD DECLARATION ====================================================== + +//== CLASS DEFINITION ========================================================= + +/// Base class for all smart range types +template +struct SmartRangeT +{ + // TODO: Someone with better c++ knowledge may improve the code below. + + template + auto sum(Functor f) -> decltype (f(std::declval())+f(std::declval())) + { + auto range = static_cast(this); + auto begin = range->begin(); + auto end = range->end(); + assert(begin != end); + decltype (f(*begin) + f(*begin)) sum = f(*begin); + auto it = begin; + ++it; + for (; it != end; ++it) + sum += f(*it); + return sum; + } + +}; + + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= + +//============================================================================= diff --git a/src/Unittests/unittests_smart_ranges.cc b/src/Unittests/unittests_smart_ranges.cc new file mode 100644 index 00000000..e817bc07 --- /dev/null +++ b/src/Unittests/unittests_smart_ranges.cc @@ -0,0 +1,196 @@ +#include +#include + +#include + +#include +#include + +namespace { + +class OpenMeshSmartRanges : public OpenMeshBase { + +protected: + + // This function is called before each test is run + virtual void SetUp() { + + mesh_.clear(); + + // Add some vertices + Mesh::VertexHandle vhandle[8]; + vhandle[0] = mesh_.add_vertex(Mesh::Point(-1, -1, 1)); + vhandle[1] = mesh_.add_vertex(Mesh::Point( 1, -1, 1)); + vhandle[2] = mesh_.add_vertex(Mesh::Point( 1, 1, 1)); + vhandle[3] = mesh_.add_vertex(Mesh::Point(-1, 1, 1)); + vhandle[4] = mesh_.add_vertex(Mesh::Point(-1, -1, -1)); + vhandle[5] = mesh_.add_vertex(Mesh::Point( 1, -1, -1)); + vhandle[6] = mesh_.add_vertex(Mesh::Point( 1, 1, -1)); + vhandle[7] = mesh_.add_vertex(Mesh::Point(-1, 1, -1)); + + // Add six faces to form a cube + std::vector face_vhandles; + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[3]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[4]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[1]); + face_vhandles.push_back(vhandle[5]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[5]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[2]); + face_vhandles.push_back(vhandle[6]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[6]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + //======================= + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[3]); + face_vhandles.push_back(vhandle[7]); + mesh_.add_face(face_vhandles); + + face_vhandles.clear(); + face_vhandles.push_back(vhandle[0]); + face_vhandles.push_back(vhandle[7]); + face_vhandles.push_back(vhandle[4]); + mesh_.add_face(face_vhandles); + + + // Test setup: + // + // + // 3 ======== 2 + // / /| + // / / | z + // 0 ======== 1 | | + // | | | | y + // | 7 | 6 | / + // | | / | / + // | |/ |/ + // 4 ======== 5 -------> x + // + + // Check setup + EXPECT_EQ(18u, mesh_.n_edges() ) << "Wrong number of Edges"; + EXPECT_EQ(36u, mesh_.n_halfedges() ) << "Wrong number of HalfEdges"; + EXPECT_EQ(8u, mesh_.n_vertices() ) << "Wrong number of vertices"; + EXPECT_EQ(12u, mesh_.n_faces() ) << "Wrong number of faces"; + } + + // This function is called after all tests are through + virtual void TearDown() { + + // Do some final stuff with the member data here... + + mesh_.clear(); + } + + // Member already defined in OpenMeshBase + //Mesh mesh_; +}; + +/* + * ==================================================================== + * Define tests below + * ==================================================================== + */ + + +template +struct F +{ + int operator()(HandleT ) { return 1; } +}; + +/* Test if smart ranges work + */ +TEST_F(OpenMeshSmartRanges, Sum) +{ + auto one = [](OpenMesh::VertexHandle ) { return 1; }; + EXPECT_EQ(mesh_.vertices().sum(one), mesh_.n_vertices()); + EXPECT_EQ(mesh_.vertices().sum(F()), mesh_.n_vertices()); + EXPECT_EQ(mesh_.halfedges().sum(F()), mesh_.n_halfedges()); + EXPECT_EQ(mesh_.edges().sum(F()), mesh_.n_edges()); + EXPECT_EQ(mesh_.faces().sum(F()), mesh_.n_faces()); + + for (auto vh : mesh_.vertices()) + EXPECT_EQ(vh.vertices().sum(F()), mesh_.valence(vh)); + for (auto vh : mesh_.vertices()) + EXPECT_EQ(vh.faces().sum(F()), mesh_.valence(vh)); + for (auto vh : mesh_.vertices()) + EXPECT_EQ(vh.outgoing_halfedges().sum(F()), mesh_.valence(vh)); + for (auto vh : mesh_.vertices()) + EXPECT_EQ(vh.incoming_halfedges().sum(F()), mesh_.valence(vh)); + + for (auto fh : mesh_.faces()) + EXPECT_EQ(fh.vertices().sum(F()), mesh_.valence(fh)); + for (auto fh : mesh_.faces()) + EXPECT_EQ(fh.halfedges().sum(F()), mesh_.valence(fh)); + for (auto fh : mesh_.faces()) + EXPECT_EQ(fh.edges().sum(F()), mesh_.valence(fh)); + for (auto fh : mesh_.faces()) + EXPECT_EQ(fh.faces().sum(F()), 3); +} + + + +} From f71696f29435b16683aa5f0ed1f579e626fb0394 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 14:45:20 +0200 Subject: [PATCH 15/60] allow PropertyManagers to be used in smart ranges --- src/OpenMesh/Core/Mesh/SmartRange.hh | 23 ++++++++++++++++++++- src/OpenMesh/Core/Utils/PropertyManager.hh | 24 ++++++++++++++++++++++ src/Unittests/unittests_smart_ranges.cc | 21 +++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index fdb2b15b..f6bac807 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -59,7 +59,7 @@ struct SmartRangeT // TODO: Someone with better c++ knowledge may improve the code below. template - auto sum(Functor f) -> decltype (f(std::declval())+f(std::declval())) + auto sum(Functor&& f) -> decltype (f(std::declval())+f(std::declval())) { auto range = static_cast(this); auto begin = range->begin(); @@ -73,6 +73,27 @@ struct SmartRangeT return sum; } + template + auto avg(Functor&& f) -> decltype (1.0 * (f(std::declval())+f(std::declval()))) + { + auto range = static_cast(this); + auto begin = range->begin(); + auto end = range->end(); + assert(begin != end); + decltype (f(*begin) + f(*begin)) sum = f(*begin); + auto it = begin; + ++it; + int n_elements = 1; + for (; it != end; ++it) + { + sum += f(*it); + ++n_elements; + } + return (1.0 / n_elements) * sum; + } + + + }; diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index fb3860f5..0feb3aa5 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -380,6 +380,30 @@ class PropertyManager { return mesh_->property(prop_, handle); } + /** + * Enables convenient access to the encapsulated property. + * + * For a usage example see this class' documentation. + * + * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) + */ + template + inline typename PROPTYPE::reference operator() (const HandleType &handle) { + return mesh_->property(prop_, handle); + } + + /** + * Enables convenient access to the encapsulated property. + * + * For a usage example see this class' documentation. + * + * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) + */ + template + inline typename PROPTYPE::const_reference operator() (const HandleType &handle) const { + return mesh_->property(prop_, handle); + } + /** * Conveniently set the property for an entire range of values. * diff --git a/src/Unittests/unittests_smart_ranges.cc b/src/Unittests/unittests_smart_ranges.cc index e817bc07..15b7da3f 100644 --- a/src/Unittests/unittests_smart_ranges.cc +++ b/src/Unittests/unittests_smart_ranges.cc @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -192,5 +193,25 @@ TEST_F(OpenMeshSmartRanges, Sum) } +/* Test if Property Manager can be used in smart ranges + */ +TEST_F(OpenMeshSmartRanges, PropertyManagerAsFunctor) +{ + auto myPos = OpenMesh::makeTemporaryProperty(mesh_); + + for (auto vh : mesh_.vertices()) + myPos(vh) = mesh_.point(vh); + + Mesh::Point cog(0,0,0); + for (auto vh : mesh_.vertices()) + cog += mesh_.point(vh); + cog /= mesh_.n_vertices(); + + auto cog2 = mesh_.vertices().avg(myPos); + + EXPECT_LT(norm(cog - cog2), 0.00001) << "Computed center of gravities are significantly different."; +} + + } From b5b708a6bad5ddf858e7f0d30fad61978e37bd4f Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 16:34:20 +0200 Subject: [PATCH 16/60] smart range improvements --- src/OpenMesh/Core/Mesh/SmartRange.hh | 82 +++++++++++++++++++++++++ src/Unittests/unittests_smart_ranges.cc | 64 ++++++++++++++++++- 2 files changed, 145 insertions(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index f6bac807..43ab02cd 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -43,6 +43,8 @@ #pragma once #include +#include +#include //== NAMESPACES =============================================================== @@ -52,12 +54,24 @@ namespace OpenMesh { //== CLASS DEFINITION ========================================================= +namespace { + +struct Identity +{ + template + T operator()(const T& _t) const { return _t; } +}; + +} + /// Base class for all smart range types template struct SmartRangeT { // TODO: Someone with better c++ knowledge may improve the code below. + + template auto sum(Functor&& f) -> decltype (f(std::declval())+f(std::declval())) { @@ -92,6 +106,74 @@ struct SmartRangeT return (1.0 / n_elements) * sum; } + template + auto to_array(Functor&& f = {}) -> std::array()))>::type, n> + { + auto range = static_cast(this); + std::array()))>::type, n> res; + auto it = range->begin(); + auto end = range->end(); + int i = 0; + while (i < n && it != end) + res[i++] = f(*(it++)); + return res; + } + + template + auto to_vector(Functor&& f = {}) -> std::vector()))>::type> + { + auto range = static_cast(this); + std::vector()))>::type> res; + for (auto e : *range) + res.push_back(f(e)); + return res; + } + + + template + auto elem_wise_min(Functor&& f) -> typename std::remove_reference()))>::type + { + auto range = static_cast(this); + auto it = range->begin(); + auto end = range->end(); + assert(it != end); + + typename std::remove_reference()))>::type min = f(*it); + ++it; + + for (; it != end; ++it) + { + const auto& tmp = f(*it); + for (int i = 0; i < n; ++i) + min[i] = std::min(min[i], tmp[i]); + } + + return min; + } + + template + auto elem_wise_max(Functor&& f) -> typename std::remove_reference()))>::type + { + auto range = static_cast(this); + auto it = range->begin(); + auto end = range->end(); + assert(it != end); + + typename std::remove_reference()))>::type max = f(*it); + ++it; + + for (; it != end; ++it) + { + const auto& tmp = f(*it); + for (int i = 0; i < n; ++i) + max[i] = std::max(max[i], tmp[i]); + } + + return max; + } + + + }; diff --git a/src/Unittests/unittests_smart_ranges.cc b/src/Unittests/unittests_smart_ranges.cc index 15b7da3f..892c0c73 100644 --- a/src/Unittests/unittests_smart_ranges.cc +++ b/src/Unittests/unittests_smart_ranges.cc @@ -198,7 +198,6 @@ TEST_F(OpenMeshSmartRanges, Sum) TEST_F(OpenMeshSmartRanges, PropertyManagerAsFunctor) { auto myPos = OpenMesh::makeTemporaryProperty(mesh_); - for (auto vh : mesh_.vertices()) myPos(vh) = mesh_.point(vh); @@ -212,6 +211,69 @@ TEST_F(OpenMeshSmartRanges, PropertyManagerAsFunctor) EXPECT_LT(norm(cog - cog2), 0.00001) << "Computed center of gravities are significantly different."; } +/* Test to vector + */ +TEST_F(OpenMeshSmartRanges, ToVector) +{ + auto uvs = OpenMesh::makeTemporaryProperty(mesh_); + + for (auto heh : mesh_.halfedges()) + uvs(heh) = OpenMesh::Vec2d(heh.idx(), (heh.idx() * 13)%7); + + for (auto fh : mesh_.faces()) + { + auto tri_uvs = fh.halfedges().to_vector(uvs); + auto heh_handles = fh.halfedges().to_vector(); +// for (auto heh : heh_handles) +// auto n = heh.next(); + } + + auto vertex_vec = mesh_.vertices().to_vector(); + for (auto vh : vertex_vec) + auto heh = vh.out(); +} + +/* Test to array + */ +TEST_F(OpenMeshSmartRanges, ToArray) +{ + auto uvs = OpenMesh::makeTemporaryProperty(mesh_); + + for (auto heh : mesh_.halfedges()) + uvs(heh) = OpenMesh::Vec2d(heh.idx(), (heh.idx() * 13)%7); + + for (auto fh : mesh_.faces()) + { + auto tri_uvs = fh.halfedges().to_array<3>(uvs); + auto heh_handles = fh.halfedges().to_array<3>(); + } +} + +/* Test bounding box + */ +TEST_F(OpenMeshSmartRanges, BoundingBox) +{ + auto myPos = OpenMesh::makeTemporaryProperty(mesh_); + for (auto vh : mesh_.vertices()) + myPos(vh) = mesh_.point(vh); + + auto uvs = OpenMesh::makeTemporaryProperty(mesh_); + for (auto heh : mesh_.halfedges()) + uvs(heh) = OpenMesh::Vec2d(heh.idx(), (heh.idx() * 13)%7); + + auto bb_min = mesh_.vertices().elem_wise_min<3>(myPos); + auto bb_max = mesh_.vertices().elem_wise_max<3>(myPos); + + EXPECT_LT(norm(bb_min - Mesh::Point(-1,-1,-1)), 0.000001) << "Bounding box minimum seems off"; + EXPECT_LT(norm(bb_max - Mesh::Point( 1, 1, 1)), 0.000001) << "Bounding box maximum seems off"; + + for (auto fh : mesh_.faces()) + { + auto uv_bb_min = fh.halfedges().elem_wise_min<2>(uvs); + auto uv_bb_max = fh.halfedges().elem_wise_max<2>(uvs); + } +} + } From 7c804acef17638a0873cc15f2a99a0cbfd5fa9b3 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 27 Sep 2019 17:08:09 +0200 Subject: [PATCH 17/60] for the cost of adding SmartHandles.cc with weird include order make smart ranges smarter by letting them know their smart handle types --- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 51 ++++----- src/OpenMesh/Core/Mesh/SmartHandles.cc | 115 +++++++++++++++++++++ src/OpenMesh/Core/Mesh/SmartHandles.hh | 63 ++--------- src/Unittests/unittests_smart_ranges.cc | 4 +- 4 files changed, 153 insertions(+), 80 deletions(-) create mode 100644 src/OpenMesh/Core/Mesh/SmartHandles.cc diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index d8adcd15..85cfa102 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -82,6 +82,9 @@ struct RangeTraitT }; +template +class CirculatorRange; + template< typename CONTAINER_T, typename ITER_T, @@ -1098,29 +1101,6 @@ public: ConstFaceRange all_faces() const; - /// Generic class for iterator ranges. - template - class CirculatorRange : public SmartRangeT, typename CirculatorRangeTraitT::TO_ENTITYE_TYPE>{ - public: - typedef typename CirculatorRangeTraitT::ITER_TYPE ITER_TYPE; - typedef typename CirculatorRangeTraitT::CENTER_ENTITY_TYPE CENTER_ENTITY_TYPE; - typedef typename CirculatorRangeTraitT::CONTAINER_TYPE CONTAINER_TYPE; - typedef ITER_TYPE iterator; - typedef ITER_TYPE const_iterator; - - CirculatorRange( - const CONTAINER_TYPE &container, - CENTER_ENTITY_TYPE center) : - container_(container), center_(center) {} - ITER_TYPE begin() const { return CirculatorRangeTraitT::begin(container_, center_); } - ITER_TYPE end() const { return CirculatorRangeTraitT::end(container_, center_); } - - private: - const CONTAINER_TYPE &container_; - CENTER_ENTITY_TYPE center_; - }; - - typedef CirculatorRange -class EntityRange : public SmartRangeT, typename RangeTraitT::ITER_TYPE::value_handle> { +class EntityRange : public SmartRangeT, typename RangeTraitT::ITER_TYPE::SmartHandle> { public: typedef typename RangeTraitT::ITER_TYPE iterator; typedef typename RangeTraitT::ITER_TYPE const_iterator; @@ -1520,6 +1500,29 @@ class EntityRange : public SmartRangeT, typename RangeT typename RangeTraitT::CONTAINER_TYPE &container_; }; +/// Generic class for iterator ranges. +template +//class CirculatorRange : public SmartRangeT, decltype (make_smart(std::declval(), std::declval()))>{ +class CirculatorRange : public SmartRangeT, typename SmartHandle::type>{ + public: + typedef typename CirculatorRangeTraitT::ITER_TYPE ITER_TYPE; + typedef typename CirculatorRangeTraitT::CENTER_ENTITY_TYPE CENTER_ENTITY_TYPE; + typedef typename CirculatorRangeTraitT::CONTAINER_TYPE CONTAINER_TYPE; + typedef ITER_TYPE iterator; + typedef ITER_TYPE const_iterator; + + CirculatorRange( + const CONTAINER_TYPE &container, + CENTER_ENTITY_TYPE center) : + container_(container), center_(center) {} + ITER_TYPE begin() const { return CirculatorRangeTraitT::begin(container_, center_); } + ITER_TYPE end() const { return CirculatorRangeTraitT::end(container_, center_); } + + private: + const CONTAINER_TYPE &container_; + CENTER_ENTITY_TYPE center_; +}; + inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::vertices() const { return ConstVertexRangeSkipping(*this); } inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_vertices() const { return ConstVertexRange(*this); } diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.cc b/src/OpenMesh/Core/Mesh/SmartHandles.cc new file mode 100644 index 00000000..a9156aa3 --- /dev/null +++ b/src/OpenMesh/Core/Mesh/SmartHandles.cc @@ -0,0 +1,115 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2019, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + + +//== INCLUDES ================================================================= + +#include +#include "SmartHandles.hh" + + +//== NAMESPACES =============================================================== + +namespace OpenMesh { + +//TODO: I was not able to leave those in the header. If you find a way to do that, please do. + +PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->vf_range(*this); +} + +PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->ve_range(*this); +} + +PolyConnectivity::ConstVertexVertexRange SmartVertexHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->vv_range(*this); +} + +PolyConnectivity::ConstVertexIHalfedgeRange SmartVertexHandle::incoming_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->vih_range(*this); +} + +PolyConnectivity::ConstVertexOHalfedgeRange SmartVertexHandle::outgoing_halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->voh_range(*this); +} + + +PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const +{ + assert(mesh() != nullptr); + return mesh()->fv_range(*this); +} + +PolyConnectivity::ConstFaceHalfedgeRange SmartFaceHandle::halfedges() const +{ + assert(mesh() != nullptr); + return mesh()->fh_range(*this); +} + +PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const +{ + assert(mesh() != nullptr); + return mesh()->fe_range(*this); +} + +PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const +{ + assert(mesh() != nullptr); + return mesh()->ff_range(*this); +} + + +//============================================================================= +} // namespace OpenMesh +//============================================================================= + +//============================================================================= diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index 5655ffe4..b444e1d7 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -198,6 +198,15 @@ inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); } +// helper to convert Handle Types to Smarthandle Types +template +struct SmartHandle; + +template <> struct SmartHandle { using type = SmartVertexHandle; }; +template <> struct SmartHandle { using type = SmartHalfedgeHandle; }; +template <> struct SmartHandle { using type = SmartEdgeHandle; }; +template <> struct SmartHandle { using type = SmartFaceHandle; }; + inline SmartHalfedgeHandle SmartVertexHandle::out() const { @@ -215,36 +224,6 @@ inline SmartHalfedgeHandle SmartVertexHandle::in() const return out().opp(); } -inline PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const -{ - assert(mesh() != nullptr); - return mesh()->vf_range(*this); -} - -inline PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const -{ - assert(mesh() != nullptr); - return mesh()->ve_range(*this); -} - -inline PolyConnectivity::ConstVertexVertexRange SmartVertexHandle::vertices() const -{ - assert(mesh() != nullptr); - return mesh()->vv_range(*this); -} - -inline PolyConnectivity::ConstVertexIHalfedgeRange SmartVertexHandle::incoming_halfedges() const -{ - assert(mesh() != nullptr); - return mesh()->vih_range(*this); -} - -inline PolyConnectivity::ConstVertexOHalfedgeRange SmartVertexHandle::outgoing_halfedges() const -{ - assert(mesh() != nullptr); - return mesh()->voh_range(*this); -} - inline uint SmartVertexHandle::valence() const { assert(mesh() != nullptr); @@ -358,30 +337,6 @@ inline SmartHalfedgeHandle SmartFaceHandle::halfedge() const return make_smart(mesh()->halfedge_handle(*this), mesh()); } -inline PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const -{ - assert(mesh() != nullptr); - return mesh()->fv_range(*this); -} - -inline PolyConnectivity::ConstFaceHalfedgeRange SmartFaceHandle::halfedges() const -{ - assert(mesh() != nullptr); - return mesh()->fh_range(*this); -} - -inline PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const -{ - assert(mesh() != nullptr); - return mesh()->fe_range(*this); -} - -inline PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const -{ - assert(mesh() != nullptr); - return mesh()->ff_range(*this); -} - inline uint SmartFaceHandle::valence() const { assert(mesh() != nullptr); diff --git a/src/Unittests/unittests_smart_ranges.cc b/src/Unittests/unittests_smart_ranges.cc index 892c0c73..fe613952 100644 --- a/src/Unittests/unittests_smart_ranges.cc +++ b/src/Unittests/unittests_smart_ranges.cc @@ -224,8 +224,8 @@ TEST_F(OpenMeshSmartRanges, ToVector) { auto tri_uvs = fh.halfedges().to_vector(uvs); auto heh_handles = fh.halfedges().to_vector(); -// for (auto heh : heh_handles) -// auto n = heh.next(); + for (auto heh : heh_handles) + auto n = heh.next(); } auto vertex_vec = mesh_.vertices().to_vector(); From 05332c70c1cc8945ed158e0a869780043d2cb16e Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Mon, 7 Oct 2019 10:58:18 +0200 Subject: [PATCH 18/60] dllexport SmartHandles --- src/OpenMesh/Core/Mesh/SmartHandles.hh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index b444e1d7..7ff382d1 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -47,6 +47,7 @@ #include "Handles.hh" #include +#include //== NAMESPACES =============================================================== @@ -64,7 +65,7 @@ struct SmartFaceHandle; //== CLASS DEFINITION ========================================================= /// Base class for all smart handle types -class SmartBaseHandle +class OPENMESHDLLEXPORT SmartBaseHandle { public: explicit SmartBaseHandle(const PolyConnectivity* _mesh = nullptr) : mesh_(_mesh) {} @@ -80,7 +81,7 @@ private: }; /// Smart version of VertexHandle contains a pointer to the corresponding mesh and allows easier access to navigation methods -struct SmartVertexHandle : public SmartBaseHandle, VertexHandle +struct OPENMESHDLLEXPORT SmartVertexHandle : public SmartBaseHandle, VertexHandle { explicit SmartVertexHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), VertexHandle(_idx) {} @@ -110,7 +111,7 @@ struct SmartVertexHandle : public SmartBaseHandle, VertexHandle bool is_manifold() const; }; -struct SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle +struct OPENMESHDLLEXPORT SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle { explicit SmartHalfedgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), HalfedgeHandle(_idx) {} @@ -131,7 +132,7 @@ struct SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle bool is_boundary() const; }; -struct SmartEdgeHandle : public SmartBaseHandle, EdgeHandle +struct OPENMESHDLLEXPORT SmartEdgeHandle : public SmartBaseHandle, EdgeHandle { explicit SmartEdgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), EdgeHandle(_idx) {} @@ -156,7 +157,7 @@ struct SmartEdgeHandle : public SmartBaseHandle, EdgeHandle bool is_boundary() const; }; -struct SmartFaceHandle : public SmartBaseHandle, FaceHandle +struct OPENMESHDLLEXPORT SmartFaceHandle : public SmartBaseHandle, FaceHandle { explicit SmartFaceHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), FaceHandle(_idx) {} From 592c13ab5c6d5e68e0056f914ba286c18c8b2963 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Mon, 7 Oct 2019 13:05:49 +0200 Subject: [PATCH 19/60] add non-member versions of min and max for vector class --- src/OpenMesh/Core/Geometry/Vector11T.hh | 15 +++++++++++++++ src/OpenMesh/Core/Geometry/VectorT.hh | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/OpenMesh/Core/Geometry/Vector11T.hh b/src/OpenMesh/Core/Geometry/Vector11T.hh index b9113a6a..3ebf2394 100644 --- a/src/OpenMesh/Core/Geometry/Vector11T.hh +++ b/src/OpenMesh/Core/Geometry/Vector11T.hh @@ -759,6 +759,21 @@ VectorT& minimize(VectorT& _v1, VectorT& return _v1.minimize(_v2); } +/// \relates OpenMesh::VectorT +/// non-member max +template +VectorT& max(VectorT& _v1, VectorT& _v2) { + return VectorT(_v1).maximize(_v2); +} + +/// \relates OpenMesh::VectorT +/// non-member min +template +VectorT& min(VectorT& _v1, VectorT& _v2) { + return VectorT(_v1).minimize(_v2); +} + + //== TYPEDEFS ================================================================= /** 1-byte signed vector */ diff --git a/src/OpenMesh/Core/Geometry/VectorT.hh b/src/OpenMesh/Core/Geometry/VectorT.hh index ef407a2a..cf8e7c40 100644 --- a/src/OpenMesh/Core/Geometry/VectorT.hh +++ b/src/OpenMesh/Core/Geometry/VectorT.hh @@ -317,6 +317,22 @@ VectorT& minimize(VectorT& _v1, VectorT& } +/// \relates OpenMesh::VectorT +/// non-member max +template +VectorT& max(VectorT& _v1, VectorT& _v2) { + return VectorT(_v1).maximize(_v2); +} + + +/// \relates OpenMesh::VectorT +/// non-member min +template +VectorT& max(VectorT& _v1, VectorT& _v2) { + return VectorT(_v1).minimize(_v2); +} + + //== TYPEDEFS ================================================================= /** 1-byte signed vector */ From 1948883fd1c3d1d1032fc1964ddb092d05dbdc25 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Mon, 7 Oct 2019 13:06:15 +0200 Subject: [PATCH 20/60] update min and max functions on ranges and add minmax function --- src/OpenMesh/Core/Mesh/SmartRange.hh | 40 +++++++++++++------------ src/Unittests/unittests_smart_ranges.cc | 26 +++++++++------- 2 files changed, 37 insertions(+), 29 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index 43ab02cd..9ccc3a36 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -71,7 +71,6 @@ struct SmartRangeT // TODO: Someone with better c++ knowledge may improve the code below. - template auto sum(Functor&& f) -> decltype (f(std::declval())+f(std::declval())) { @@ -130,46 +129,49 @@ struct SmartRangeT } - template - auto elem_wise_min(Functor&& f) -> typename std::remove_reference()))>::type + template + auto min(Functor&& f) -> typename std::remove_reference()))>::type { + using std::min; + auto range = static_cast(this); auto it = range->begin(); auto end = range->end(); assert(it != end); - typename std::remove_reference()))>::type min = f(*it); + typename std::remove_reference()))>::type res = f(*it); ++it; for (; it != end; ++it) - { - const auto& tmp = f(*it); - for (int i = 0; i < n; ++i) - min[i] = std::min(min[i], tmp[i]); - } + res = min(res, f(*it)); - return min; + return res; } - template - auto elem_wise_max(Functor&& f) -> typename std::remove_reference()))>::type + template + auto max(Functor&& f) -> typename std::remove_reference()))>::type { + using std::max; + auto range = static_cast(this); auto it = range->begin(); auto end = range->end(); assert(it != end); - typename std::remove_reference()))>::type max = f(*it); + typename std::remove_reference()))>::type res = f(*it); ++it; for (; it != end; ++it) - { - const auto& tmp = f(*it); - for (int i = 0; i < n; ++i) - max[i] = std::max(max[i], tmp[i]); - } + res = max(res, f(*it)); - return max; + return res; + } + + template + auto minmax(Functor&& f) -> std::pair()))>::type, + typename std::remove_reference()))>::type> + { + return std::make_pair(this->min(f), this->max(f)); } diff --git a/src/Unittests/unittests_smart_ranges.cc b/src/Unittests/unittests_smart_ranges.cc index fe613952..be5a3dc0 100644 --- a/src/Unittests/unittests_smart_ranges.cc +++ b/src/Unittests/unittests_smart_ranges.cc @@ -249,28 +249,34 @@ TEST_F(OpenMeshSmartRanges, ToArray) } } + /* Test bounding box */ TEST_F(OpenMeshSmartRanges, BoundingBox) { - auto myPos = OpenMesh::makeTemporaryProperty(mesh_); + // The custom vecs OpenMesh are tested with here do not implement a min or max function. + // Thus we convert here. + auto myPos = OpenMesh::makeTemporaryProperty(mesh_); for (auto vh : mesh_.vertices()) - myPos(vh) = mesh_.point(vh); + for (size_t i = 0; i < 3; ++i) + myPos(vh)[i] = mesh_.point(vh)[i]; + + auto bb_min = mesh_.vertices().min(myPos); + auto bb_max = mesh_.vertices().max(myPos); + auto bb = mesh_.vertices().minmax(myPos); + + EXPECT_LT(norm(bb_min - OpenMesh::Vec3f(-1,-1,-1)), 0.000001) << "Bounding box minimum seems off"; + EXPECT_LT(norm(bb_max - OpenMesh::Vec3f( 1, 1, 1)), 0.000001) << "Bounding box maximum seems off"; + auto uvs = OpenMesh::makeTemporaryProperty(mesh_); for (auto heh : mesh_.halfedges()) uvs(heh) = OpenMesh::Vec2d(heh.idx(), (heh.idx() * 13)%7); - auto bb_min = mesh_.vertices().elem_wise_min<3>(myPos); - auto bb_max = mesh_.vertices().elem_wise_max<3>(myPos); - - EXPECT_LT(norm(bb_min - Mesh::Point(-1,-1,-1)), 0.000001) << "Bounding box minimum seems off"; - EXPECT_LT(norm(bb_max - Mesh::Point( 1, 1, 1)), 0.000001) << "Bounding box maximum seems off"; - for (auto fh : mesh_.faces()) { - auto uv_bb_min = fh.halfedges().elem_wise_min<2>(uvs); - auto uv_bb_max = fh.halfedges().elem_wise_max<2>(uvs); + auto uv_bb_min = fh.halfedges().min(uvs); + auto uv_bb_max = fh.halfedges().max(uvs); } } From e6fca39d15710c667d11141c89d4f467f7c192ed Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Mon, 7 Oct 2019 13:16:12 +0200 Subject: [PATCH 21/60] allow one more cppcheck warning --- CI/ci-cppcheck.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CI/ci-cppcheck.sh b/CI/ci-cppcheck.sh index 914376c2..520ed1be 100755 --- a/CI/ci-cppcheck.sh +++ b/CI/ci-cppcheck.sh @@ -30,7 +30,7 @@ echo "CPPCHECK Summary" echo "==============================================================================" echo -e "${NC}" -MAX_COUNT=26 +MAX_COUNT=27 if [ $COUNT -gt $MAX_COUNT ]; then echo -e ${WARNING} From da233b391e407bb6c49dec5ebcc6228f26bbf2d8 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Mon, 7 Oct 2019 14:57:24 +0200 Subject: [PATCH 22/60] fix return type of non-member min and max functions --- src/OpenMesh/Core/Geometry/Vector11T.hh | 4 ++-- src/OpenMesh/Core/Geometry/VectorT.hh | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenMesh/Core/Geometry/Vector11T.hh b/src/OpenMesh/Core/Geometry/Vector11T.hh index 3ebf2394..6c78777e 100644 --- a/src/OpenMesh/Core/Geometry/Vector11T.hh +++ b/src/OpenMesh/Core/Geometry/Vector11T.hh @@ -762,14 +762,14 @@ VectorT& minimize(VectorT& _v1, VectorT& /// \relates OpenMesh::VectorT /// non-member max template -VectorT& max(VectorT& _v1, VectorT& _v2) { +VectorT max(VectorT& _v1, VectorT& _v2) { return VectorT(_v1).maximize(_v2); } /// \relates OpenMesh::VectorT /// non-member min template -VectorT& min(VectorT& _v1, VectorT& _v2) { +VectorT min(VectorT& _v1, VectorT& _v2) { return VectorT(_v1).minimize(_v2); } diff --git a/src/OpenMesh/Core/Geometry/VectorT.hh b/src/OpenMesh/Core/Geometry/VectorT.hh index cf8e7c40..87a7e1d0 100644 --- a/src/OpenMesh/Core/Geometry/VectorT.hh +++ b/src/OpenMesh/Core/Geometry/VectorT.hh @@ -320,7 +320,7 @@ VectorT& minimize(VectorT& _v1, VectorT& /// \relates OpenMesh::VectorT /// non-member max template -VectorT& max(VectorT& _v1, VectorT& _v2) { +VectorT max(VectorT& _v1, VectorT& _v2) { return VectorT(_v1).maximize(_v2); } @@ -328,7 +328,7 @@ VectorT& max(VectorT& _v1, VectorT& _v2) /// \relates OpenMesh::VectorT /// non-member min template -VectorT& max(VectorT& _v1, VectorT& _v2) { +VectorT min(VectorT& _v1, VectorT& _v2) { return VectorT(_v1).minimize(_v2); } From 81f3fcc2c1c66c17fb9c7e7ed7f2e44dba9922df Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 17 Oct 2019 09:20:06 +0200 Subject: [PATCH 23/60] add test to check if old api works with new api --- src/Unittests/unittests_smart_handles.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc index 2979b327..3a098fc1 100644 --- a/src/Unittests/unittests_smart_handles.cc +++ b/src/Unittests/unittests_smart_handles.cc @@ -461,4 +461,16 @@ TEST_F(OpenMeshSmartHandles, Performance) } + +/* Mix old and new api + */ +TEST_F(OpenMeshSmartHandles, MixOldAndNew) +{ + for (auto heh : mesh_.halfedges()) + { + heh = mesh_.opposite_halfedge_handle(heh); + } +} + + } From 3b21aa14fbe4f58e712e7c867caa00cf81e2f86d Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 17 Oct 2019 12:56:48 +0200 Subject: [PATCH 24/60] make smart handles more compatible with mixing old api --- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 75 +++++++++++++++++++--- src/OpenMesh/Core/Mesh/SmartHandles.hh | 8 +++ src/Unittests/unittests_smart_handles.cc | 5 +- 3 files changed, 79 insertions(+), 9 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index 85cfa102..b87d40dc 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -102,7 +102,10 @@ struct CirculatorRangeTraitT static ITER_TYPE end(const CONTAINER_TYPE& _container, CENTER_ENTITY_TYPE _ce) { return (_container.*end_fn)(_ce); } }; - +struct SmartVertexHandle; +struct SmartHalfedgeHandle; +struct SmartEdgeHandle; +struct SmartFaceHandle; /** \brief Connectivity Class for polygonal meshes */ @@ -180,7 +183,7 @@ public: using Mesh = This; using CenterEntityHandle = This::VertexHandle; using ValueHandle = This::HalfedgeHandle; - static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _heh;} + static ValueHandle toHandle(const Mesh* const /*_mesh*/, This::HalfedgeHandle _heh) { return _heh;} }; /** @@ -219,7 +222,7 @@ public: using Mesh = This; using CenterEntityHandle = This::VertexHandle; using ValueHandle = This::FaceHandle; - static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->face_handle(_heh); } + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->face_handle(_heh); } }; /** @@ -239,7 +242,7 @@ public: using Mesh = This; using CenterEntityHandle = This::VertexHandle; using ValueHandle = This::EdgeHandle; - static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->edge_handle(_heh); } + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->edge_handle(_heh); } }; /** @@ -258,7 +261,7 @@ public: using Mesh = This; using CenterEntityHandle = This::FaceHandle; using ValueHandle = This::HalfedgeHandle; - static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _heh; } + static ValueHandle toHandle(const Mesh* const /*_mesh*/, This::HalfedgeHandle _heh) { return _heh; } }; /** @@ -296,7 +299,7 @@ public: using Mesh = This; using CenterEntityHandle = This::FaceHandle; using ValueHandle = This::VertexHandle; - static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->to_vertex_handle(_heh); } + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->to_vertex_handle(_heh); } }; /** @@ -327,7 +330,7 @@ public: using Mesh = This; using CenterEntityHandle = This::FaceHandle; using ValueHandle = This::EdgeHandle; - static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->edge_handle(_heh); } + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->edge_handle(_heh); } }; /** @@ -347,7 +350,7 @@ public: using Mesh = This; using CenterEntityHandle = This::FaceHandle; using ValueHandle = This::FaceHandle; - static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return _mesh->face_handle(_mesh->opposite_halfedge_handle(_heh)); } + static ValueHandle toHandle(const Mesh* const _mesh, This::HalfedgeHandle _heh) { return static_cast(_mesh)->face_handle(_mesh->opposite_halfedge_handle(_heh)); } }; /** @@ -565,6 +568,42 @@ public: */ void delete_face(FaceHandle _fh, bool _delete_isolated_vertices=true); + + //@} + + /** \name Navigation with smart handles to allow usage of old-style navigation with smart handles + */ + //@{ + + using ArrayKernel::next_halfedge_handle; + using ArrayKernel::prev_halfedge_handle; + using ArrayKernel::opposite_halfedge_handle; + using ArrayKernel::ccw_rotated_halfedge_handle; + using ArrayKernel::cw_rotated_halfedge_handle; + + inline SmartHalfedgeHandle next_halfedge_handle (SmartHalfedgeHandle _heh) const; + inline SmartHalfedgeHandle prev_halfedge_handle (SmartHalfedgeHandle _heh) const; + inline SmartHalfedgeHandle opposite_halfedge_handle (SmartHalfedgeHandle _heh) const; + inline SmartHalfedgeHandle ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const; + inline SmartHalfedgeHandle cw_rotated_halfedge_handle (SmartHalfedgeHandle _heh) const; + + using ArrayKernel::s_halfedge_handle; + using ArrayKernel::s_edge_handle; + + static SmartHalfedgeHandle s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i); + static SmartEdgeHandle s_edge_handle(SmartHalfedgeHandle _heh); + + using ArrayKernel::halfedge_handle; + using ArrayKernel::edge_handle; + using ArrayKernel::face_handle; + + inline SmartHalfedgeHandle halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const; + inline SmartHalfedgeHandle halfedge_handle(SmartFaceHandle _fh) const; + inline SmartHalfedgeHandle halfedge_handle(SmartVertexHandle _vh) const; + inline SmartEdgeHandle edge_handle(SmartHalfedgeHandle _heh) const; + inline SmartFaceHandle face_handle(SmartHalfedgeHandle _heh) const; + + //@} /** \name Begin and end iterators @@ -1482,9 +1521,29 @@ private: // Working storage for add_face() #include #include +#include namespace OpenMesh { + +inline SmartHalfedgeHandle PolyConnectivity::next_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.next(); } +inline SmartHalfedgeHandle PolyConnectivity::prev_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.prev(); } +inline SmartHalfedgeHandle PolyConnectivity::opposite_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.opp(); } +inline SmartHalfedgeHandle PolyConnectivity::ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.prev().opp(); } +inline SmartHalfedgeHandle PolyConnectivity::cw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.opp().next();} + +inline SmartHalfedgeHandle PolyConnectivity::s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) { return make_smart(ArrayKernel::s_halfedge_handle(EdgeHandle(_eh), _i), _eh.mesh()); } +inline SmartEdgeHandle PolyConnectivity::s_edge_handle(SmartHalfedgeHandle _heh) { return make_smart(ArrayKernel::s_edge_handle(HalfedgeHandle(_heh)), _heh.mesh()); } + +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const { return _eh.halfedge(_i); } +inline SmartEdgeHandle PolyConnectivity::edge_handle(SmartHalfedgeHandle _heh) const { return _heh.edge(); } +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartFaceHandle _fh) const { return _fh.halfedge(); } +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartVertexHandle _vh) const { return _vh.halfedge(); } + +inline SmartFaceHandle PolyConnectivity::face_handle(SmartHalfedgeHandle _heh) const { return _heh.face(); } + + + /// Generic class for vertex/halfedge/edge/face ranges. template class EntityRange : public SmartRangeT, typename RangeTraitT::ITER_TYPE::SmartHandle> { diff --git a/src/OpenMesh/Core/Mesh/SmartHandles.hh b/src/OpenMesh/Core/Mesh/SmartHandles.hh index 7ff382d1..920cc0d8 100644 --- a/src/OpenMesh/Core/Mesh/SmartHandles.hh +++ b/src/OpenMesh/Core/Mesh/SmartHandles.hh @@ -125,6 +125,8 @@ struct OPENMESHDLLEXPORT SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeH SmartVertexHandle to() const; /// Returns vertex at start of halfedge SmartVertexHandle from() const; + /// Returns incident edge of halfedge + SmartEdgeHandle edge() const; /// Returns incident face of halfedge SmartFaceHandle face() const; @@ -273,6 +275,12 @@ inline SmartVertexHandle SmartHalfedgeHandle::from() const return make_smart(mesh()->from_vertex_handle(*this), mesh()); } +inline SmartEdgeHandle SmartHalfedgeHandle::edge() const +{ + assert(mesh() != nullptr); + return make_smart(mesh()->edge_handle(*this), mesh()); +} + inline SmartFaceHandle SmartHalfedgeHandle::face() const { assert(mesh() != nullptr); diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc index 3a098fc1..fdfc5175 100644 --- a/src/Unittests/unittests_smart_handles.cc +++ b/src/Unittests/unittests_smart_handles.cc @@ -466,9 +466,12 @@ TEST_F(OpenMeshSmartHandles, Performance) */ TEST_F(OpenMeshSmartHandles, MixOldAndNew) { - for (auto heh : mesh_.halfedges()) + for (OpenMesh::SmartHalfedgeHandle heh : mesh_.halfedges()) { heh = mesh_.opposite_halfedge_handle(heh); + OpenMesh::SmartEdgeHandle eh = OpenMesh::PolyConnectivity::s_edge_handle(heh); + OpenMesh::SmartEdgeHandle eh2 = mesh_.edge_handle(heh); + OpenMesh::SmartFaceHandle fh = mesh_.face_handle(heh); } } From bd33706300060c1de00db266f2f20e0125545439 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 17 Oct 2019 13:47:08 +0200 Subject: [PATCH 25/60] fix infinite recursion --- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index b87d40dc..24918df2 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -1526,21 +1526,21 @@ private: // Working storage for add_face() namespace OpenMesh { -inline SmartHalfedgeHandle PolyConnectivity::next_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.next(); } -inline SmartHalfedgeHandle PolyConnectivity::prev_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.prev(); } -inline SmartHalfedgeHandle PolyConnectivity::opposite_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.opp(); } -inline SmartHalfedgeHandle PolyConnectivity::ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.prev().opp(); } -inline SmartHalfedgeHandle PolyConnectivity::cw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return _heh.opp().next();} +inline SmartHalfedgeHandle PolyConnectivity::next_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(next_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::prev_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(prev_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::opposite_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(opposite_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(ccw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::cw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(cw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } inline SmartHalfedgeHandle PolyConnectivity::s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) { return make_smart(ArrayKernel::s_halfedge_handle(EdgeHandle(_eh), _i), _eh.mesh()); } inline SmartEdgeHandle PolyConnectivity::s_edge_handle(SmartHalfedgeHandle _heh) { return make_smart(ArrayKernel::s_edge_handle(HalfedgeHandle(_heh)), _heh.mesh()); } -inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const { return _eh.halfedge(_i); } -inline SmartEdgeHandle PolyConnectivity::edge_handle(SmartHalfedgeHandle _heh) const { return _heh.edge(); } -inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartFaceHandle _fh) const { return _fh.halfedge(); } -inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartVertexHandle _vh) const { return _vh.halfedge(); } +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const { return make_smart(halfedge_handle(EdgeHandle(_eh), _i), *this); } +inline SmartEdgeHandle PolyConnectivity::edge_handle(SmartHalfedgeHandle _heh) const { return make_smart(edge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartFaceHandle _fh) const { return make_smart(halfedge_handle(FaceHandle(_fh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartVertexHandle _vh) const { return make_smart(halfedge_handle(VertexHandle(_vh)), *this); } -inline SmartFaceHandle PolyConnectivity::face_handle(SmartHalfedgeHandle _heh) const { return _heh.face(); } +inline SmartFaceHandle PolyConnectivity::face_handle(SmartHalfedgeHandle _heh) const { return make_smart(face_handle(HalfedgeHandle(_heh)), *this); } From e222791c4992c06482142b4c7d88e9903e5b417d Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 17 Oct 2019 14:10:32 +0200 Subject: [PATCH 26/60] add test that does some comparisons between smart handles and handles --- src/Unittests/unittests_smart_handles.cc | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc index fdfc5175..8d63d024 100644 --- a/src/Unittests/unittests_smart_handles.cc +++ b/src/Unittests/unittests_smart_handles.cc @@ -476,4 +476,30 @@ TEST_F(OpenMeshSmartHandles, MixOldAndNew) } + +/* comparability + */ +TEST_F(OpenMeshSmartHandles, ComparisionBetweenSmartHandleAndNormalHandles) +{ + OpenMesh::VertexHandle vh(0); + OpenMesh::SmartVertexHandle svh(0, &mesh_); + EXPECT_EQ(vh, svh) << "Vertex handle and smart vertex handle are different"; + + std::vector vertices = mesh_.vertices().to_vector([](OpenMesh::SmartVertexHandle _svh) { return OpenMesh::VertexHandle(_svh); }); + + std::replace(vertices.begin(), vertices.end(), OpenMesh::VertexHandle(0), OpenMesh::VertexHandle(1)); + EXPECT_EQ(vertices[0], OpenMesh::VertexHandle(1)); + + std::vector smart_vertices = mesh_.vertices().to_vector(); + + std::replace(smart_vertices.begin(), smart_vertices.end(), OpenMesh::SmartVertexHandle(0, &mesh_), OpenMesh::SmartVertexHandle(1, &mesh_)); + EXPECT_EQ(smart_vertices[0], OpenMesh::VertexHandle(1)); + EXPECT_EQ(smart_vertices[0], OpenMesh::SmartVertexHandle(1, &mesh_)); + + std::replace(vertices.begin(), vertices.end(), OpenMesh::SmartVertexHandle(1, &mesh_), OpenMesh::SmartVertexHandle(2, &mesh_)); + EXPECT_EQ(vertices[0], OpenMesh::VertexHandle(2)); + +} + + } From a3fbdcb93728015fe70eece01a1076db8d6b5d04 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 17 Oct 2019 14:27:58 +0200 Subject: [PATCH 27/60] let add_vertex and add_face return smart handles --- src/OpenMesh/Core/Mesh/PolyConnectivity.cc | 24 ++++++++++++++-------- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 22 ++++++++++++++------ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc index 1be2a823..b3d2d483 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.cc +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.cc @@ -113,7 +113,7 @@ void PolyConnectivity::adjust_outgoing_halfedge(VertexHandle _vh) //----------------------------------------------------------------------------- -PolyConnectivity::FaceHandle +SmartFaceHandle PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size) { VertexHandle vh; @@ -142,7 +142,7 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size if ( !is_boundary(_vertex_handles[i]) ) { omerr() << "PolyMeshT::add_face: complex vertex\n"; - return InvalidFaceHandle; + return make_smart(InvalidFaceHandle, this); } // Initialise edge attributes @@ -154,7 +154,7 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size if (!edgeData_[i].is_new && !is_boundary(edgeData_[i].halfedge_handle)) { omerr() << "PolyMeshT::add_face: complex edge\n"; - return InvalidFaceHandle; + return make_smart(InvalidFaceHandle, this); } } @@ -186,7 +186,7 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size if (boundary_prev == inner_prev) { omerr() << "PolyMeshT::add_face: patch re-linking failed\n"; - return InvalidFaceHandle; + return make_smart(InvalidFaceHandle, this); } assert(is_boundary(boundary_prev)); @@ -297,12 +297,12 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size if (edgeData_[i].needs_adjust) adjust_outgoing_halfedge(_vertex_handles[i]); - return fh; + return make_smart(fh, this); } //----------------------------------------------------------------------------- -FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3) +SmartFaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3) { VertexHandle vhs[4] = { _vh0, _vh1, _vh2, _vh3 }; return add_face(vhs, 4); @@ -310,7 +310,7 @@ FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, Vert //----------------------------------------------------------------------------- -FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) +SmartFaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) { VertexHandle vhs[3] = { _vh0, _vh1, _vh2 }; return add_face(vhs, 3); @@ -318,9 +318,17 @@ FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, Vert //----------------------------------------------------------------------------- -FaceHandle PolyConnectivity::add_face(const std::vector& _vhandles) +SmartFaceHandle PolyConnectivity::add_face(const std::vector& _vhandles) { return add_face(&_vhandles.front(), _vhandles.size()); } +//----------------------------------------------------------------------------- + +SmartFaceHandle PolyConnectivity::add_face(const std::vector& _vhandles) +{ + std::vector vhandles(_vhandles.begin(), _vhandles.end()); + return add_face(&vhandles.front(), vhandles.size()); +} + //----------------------------------------------------------------------------- bool PolyConnectivity::is_collapse_ok(HalfedgeHandle v0v1) diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index 24918df2..37746368 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -481,8 +481,7 @@ public: //@{ /// Add a new vertex - inline VertexHandle add_vertex() - { return new_vertex(); } + inline SmartVertexHandle add_vertex(); /** \brief Add and connect a new face * @@ -491,7 +490,16 @@ public: * * @param _vhandles sorted list of vertex handles (also defines order in which the vertices are added to the face) */ - FaceHandle add_face(const std::vector& _vhandles); + SmartFaceHandle add_face(const std::vector& _vhandles); + + /** \brief Add and connect a new face + * + * Create a new face consisting of the vertices provided by the vertex handle vector. + * (The vertices have to be already added to the mesh by add_vertex) + * + * @param _vhandles sorted list of vertex handles (also defines order in which the vertices are added to the face) + */ + SmartFaceHandle add_face(const std::vector& _vhandles); /** \brief Add and connect a new face @@ -503,7 +511,7 @@ public: * @param _vh1 Second vertex handle * @param _vh2 Third vertex handle */ - FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); + SmartFaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); /** \brief Add and connect a new face * @@ -515,7 +523,7 @@ public: * @param _vh2 Third vertex handle * @param _vh3 Fourth vertex handle */ - FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3); + SmartFaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3); /** \brief Add and connect a new face * @@ -525,7 +533,7 @@ public: * @param _vhandles pointer to a sorted list of vertex handles (also defines order in which the vertices are added to the face) * @param _vhs_size number of vertex handles in the array */ - FaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); + SmartFaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); //@} @@ -1526,6 +1534,8 @@ private: // Working storage for add_face() namespace OpenMesh { +inline SmartVertexHandle PolyConnectivity::add_vertex() { return make_smart(new_vertex(), *this); } + inline SmartHalfedgeHandle PolyConnectivity::next_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(next_halfedge_handle(HalfedgeHandle(_heh)), *this); } inline SmartHalfedgeHandle PolyConnectivity::prev_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(prev_halfedge_handle(HalfedgeHandle(_heh)), *this); } inline SmartHalfedgeHandle PolyConnectivity::opposite_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(opposite_halfedge_handle(HalfedgeHandle(_heh)), *this); } From 56c13484933c895557c12bb50015837ad38f94a4 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 17 Oct 2019 14:55:25 +0200 Subject: [PATCH 28/60] make more functions return smart handles --- src/OpenMesh/Core/Mesh/PolyMeshT.hh | 18 +++---- src/OpenMesh/Core/Mesh/TriConnectivity.cc | 18 +++++-- src/OpenMesh/Core/Mesh/TriConnectivity.hh | 18 +++++-- src/OpenMesh/Core/Mesh/TriMeshT.hh | 16 +++--- src/Unittests/unittests_smart_handles.cc | 60 +++++++++++++++++++++++ 5 files changed, 104 insertions(+), 26 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/PolyMeshT.hh b/src/OpenMesh/Core/Mesh/PolyMeshT.hh index 33e89c31..0ffb4691 100644 --- a/src/OpenMesh/Core/Mesh/PolyMeshT.hh +++ b/src/OpenMesh/Core/Mesh/PolyMeshT.hh @@ -198,19 +198,19 @@ public: * * \sa new_vertex(const Point&), new_vertex_dirty() */ - inline VertexHandle new_vertex() - { return Kernel::new_vertex(); } + inline SmartVertexHandle new_vertex() + { return make_smart(Kernel::new_vertex(), this); } /** * \brief Adds a new vertex initialized to a custom position. * * \sa new_vertex(), new_vertex_dirty() */ - inline VertexHandle new_vertex(const Point& _p) + inline SmartVertexHandle new_vertex(const Point& _p) { VertexHandle vh(Kernel::new_vertex()); this->set_point(vh, _p); - return vh; + return make_smart(vh, this); } /** @@ -224,20 +224,20 @@ public: * * \sa new_vertex(const Point &) */ - inline VertexHandle new_vertex_dirty(const Point& _p) + inline SmartVertexHandle new_vertex_dirty(const Point& _p) { VertexHandle vh(Kernel::new_vertex_dirty()); this->set_point(vh, _p); - return vh; + return make_smart(vh, this); } /// Alias for new_vertex(const Point&). - inline VertexHandle add_vertex(const Point& _p) + inline SmartVertexHandle add_vertex(const Point& _p) { return new_vertex(_p); } /// Alias for new_vertex_dirty(). - inline VertexHandle add_vertex_dirty(const Point& _p) - { return new_vertex_dirty(_p); } + inline SmartVertexHandle add_vertex_dirty(const Point& _p) + { return make_smart(new_vertex_dirty(_p), this); } // --- normal vectors --- diff --git a/src/OpenMesh/Core/Mesh/TriConnectivity.cc b/src/OpenMesh/Core/Mesh/TriConnectivity.cc index 5bb7c24b..c0ec6d45 100644 --- a/src/OpenMesh/Core/Mesh/TriConnectivity.cc +++ b/src/OpenMesh/Core/Mesh/TriConnectivity.cc @@ -49,11 +49,11 @@ namespace OpenMesh { -TriConnectivity::FaceHandle +SmartFaceHandle TriConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size) { // need at least 3 vertices - if (_vhs_size < 3) return InvalidFaceHandle; + if (_vhs_size < 3) return make_smart(InvalidFaceHandle, this); /// face is triangle -> ok if (_vhs_size == 3) @@ -78,21 +78,29 @@ TriConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size) fh = PolyConnectivity::add_face(vhandles, 3); } - return fh; + return make_smart(fh, this); } } //----------------------------------------------------------------------------- -FaceHandle TriConnectivity::add_face(const std::vector& _vhandles) +SmartFaceHandle TriConnectivity::add_face(const std::vector& _vhandles) { return add_face(&_vhandles.front(), _vhandles.size()); } //----------------------------------------------------------------------------- +SmartFaceHandle TriConnectivity::add_face(const std::vector& _vhandles) +{ + std::vector vhandles(_vhandles.begin(), _vhandles.end()); + return add_face(&vhandles.front(), vhandles.size()); +} -FaceHandle TriConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) +//----------------------------------------------------------------------------- + + +SmartFaceHandle TriConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) { VertexHandle vhs[3] = { _vh0, _vh1, _vh2 }; return PolyConnectivity::add_face(vhs, 3); diff --git a/src/OpenMesh/Core/Mesh/TriConnectivity.hh b/src/OpenMesh/Core/Mesh/TriConnectivity.hh index f0c948d6..f9c84751 100644 --- a/src/OpenMesh/Core/Mesh/TriConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/TriConnectivity.hh @@ -85,8 +85,8 @@ public: * * * */ - FaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); - + SmartFaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size); + /** \brief Add a face with arbitrary valence to the triangle mesh * * Override OpenMesh::Mesh::PolyMeshT::add_face(). Faces that aren't @@ -95,7 +95,17 @@ public: * * * */ - FaceHandle add_face(const std::vector& _vhandles); + SmartFaceHandle add_face(const std::vector& _vhandles); + + /** \brief Add a face with arbitrary valence to the triangle mesh + * + * Override OpenMesh::Mesh::PolyMeshT::add_face(). Faces that aren't + * triangles will be triangulated and added. In this case an + * invalid face handle will be returned. + * + * + * */ + SmartFaceHandle add_face(const std::vector& _vhandles); /** \brief Add a face to the mesh (triangle) * @@ -107,7 +117,7 @@ public: * @param _vh2 VertexHandle 3 * @return FaceHandle of the added face (invalid, if the operation failed) */ - FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); + SmartFaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2); //@} diff --git a/src/OpenMesh/Core/Mesh/TriMeshT.hh b/src/OpenMesh/Core/Mesh/TriMeshT.hh index f7992b48..2b108e7d 100644 --- a/src/OpenMesh/Core/Mesh/TriMeshT.hh +++ b/src/OpenMesh/Core/Mesh/TriMeshT.hh @@ -264,10 +264,10 @@ public: * @param _p New point position that will be inserted at the edge * @return Vertex handle of the newly added vertex */ - inline VertexHandle split(EdgeHandle _eh, const Point& _p) + inline SmartVertexHandle split(EdgeHandle _eh, const Point& _p) { //Do not call PolyMeshT function below as this does the wrong operation - const VertexHandle vh = this->add_vertex(_p); Kernel::split(_eh, vh); return vh; + const SmartVertexHandle vh = this->add_vertex(_p); Kernel::split(_eh, vh); return vh; } /** \brief Edge split (= 2-to-4 split) @@ -278,10 +278,10 @@ public: * @param _p New point position that will be inserted at the edge * @return Vertex handle of the newly added vertex */ - inline VertexHandle split_copy(EdgeHandle _eh, const Point& _p) + inline SmartVertexHandle split_copy(EdgeHandle _eh, const Point& _p) { //Do not call PolyMeshT function below as this does the wrong operation - const VertexHandle vh = this->add_vertex(_p); Kernel::split_copy(_eh, vh); return vh; + const SmartVertexHandle vh = this->add_vertex(_p); Kernel::split_copy(_eh, vh); return vh; } /** \brief Edge split (= 2-to-4 split) @@ -319,8 +319,8 @@ public: * * @return Vertex handle of the new vertex */ - inline VertexHandle split(FaceHandle _fh, const Point& _p) - { const VertexHandle vh = this->add_vertex(_p); PolyMesh::split(_fh, vh); return vh; } + inline SmartVertexHandle split(FaceHandle _fh, const Point& _p) + { const SmartVertexHandle vh = this->add_vertex(_p); PolyMesh::split(_fh, vh); return vh; } /** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function). * @@ -331,8 +331,8 @@ public: * * @return Vertex handle of the new vertex */ - inline VertexHandle split_copy(FaceHandle _fh, const Point& _p) - { const VertexHandle vh = this->add_vertex(_p); PolyMesh::split_copy(_fh, vh); return vh; } + inline SmartVertexHandle split_copy(FaceHandle _fh, const Point& _p) + { const SmartVertexHandle vh = this->add_vertex(_p); PolyMesh::split_copy(_fh, vh); return vh; } /** \brief Face split (= 1-to-4) split, splits edges at midpoints and adds 4 new faces in the interior). diff --git a/src/Unittests/unittests_smart_handles.cc b/src/Unittests/unittests_smart_handles.cc index 8d63d024..21296caf 100644 --- a/src/Unittests/unittests_smart_handles.cc +++ b/src/Unittests/unittests_smart_handles.cc @@ -501,5 +501,65 @@ TEST_F(OpenMeshSmartHandles, ComparisionBetweenSmartHandleAndNormalHandles) } +TEST(OpenMeshSmartHandlesNoFixture, AddingFacesPolyMesh) +{ + using MyMesh = OpenMesh::PolyMesh_ArrayKernelT<>; + + MyMesh mesh; + + std::vector vertices; + for (int i = 0; i < 4; ++i) + vertices.push_back(mesh.add_vertex(MyMesh::Point())); + + auto fh = mesh.add_face(vertices); + + for (auto heh : fh.halfedges()) + { + heh = heh.next(); + } +} + +TEST(OpenMeshSmartHandlesNoFixture, AddingFacesTriMesh) +{ + using MyMesh = OpenMesh::TriMesh_ArrayKernelT<>; + + MyMesh mesh; + + std::vector vertices; + for (int i = 0; i < 4; ++i) + vertices.push_back(mesh.add_vertex(MyMesh::Point())); + + auto fh = mesh.add_face(vertices); + + for (auto heh : fh.halfedges()) + { + heh = heh.next(); + } +} + +TEST(OpenMeshSmartHandlesNoFixture, SplitTriMesh) +{ + using MyMesh = OpenMesh::TriMesh_ArrayKernelT<>; + + MyMesh mesh; + + std::vector vertices; + for (int i = 0; i < 3; ++i) + vertices.push_back(mesh.add_vertex(MyMesh::Point())); + + auto fh = mesh.add_face(vertices); + + auto p = (MyMesh::Point()); + + OpenMesh::SmartVertexHandle vh = mesh.split(fh, p); + + OpenMesh::SmartEdgeHandle eh = fh.halfedge().edge(); + OpenMesh::SmartVertexHandle vh2 = mesh.split(eh, p); + +} + + + + } From 660e46db24827509205c44d0a278f1d25172c0e2 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Fri, 18 Oct 2019 14:29:52 +0200 Subject: [PATCH 29/60] fix iterator type --- src/OpenMesh/Core/Mesh/SmartRange.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index 9ccc3a36..a373b74a 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -123,7 +123,7 @@ struct SmartRangeT { auto range = static_cast(this); std::vector()))>::type> res; - for (auto e : *range) + for (const auto& e : *range) res.push_back(f(e)); return res; } From 34b2e958e13731ee8594733e067602ef835e93e4 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 13:59:54 +0100 Subject: [PATCH 30/60] add convenience function n_elements returning n_vertices, n_halfedges, n_edges, or n_faces depending on the template argument --- src/OpenMesh/Core/Mesh/BaseKernel.hh | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/BaseKernel.hh b/src/OpenMesh/Core/Mesh/BaseKernel.hh index 0a0fee1a..0270a580 100644 --- a/src/OpenMesh/Core/Mesh/BaseKernel.hh +++ b/src/OpenMesh/Core/Mesh/BaseKernel.hh @@ -516,7 +516,7 @@ public: // Copy all properties, if build in is true // Otherwise, copy only properties without build in specifier if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "v:" ) ) - (*p_it)->copy(_vh_from.idx(), _vh_to.idx()); + (*p_it)->copy(static_cast(_vh_from.idx()), static_cast(_vh_to.idx())); } } @@ -690,6 +690,9 @@ public: //----------------------------------------------------- element numbers virtual size_t n_edges() const { return 0; } virtual size_t n_faces() const { return 0; } + template + size_t n_elements() const; + protected: //------------------------------------------- synchronize properties @@ -814,6 +817,16 @@ private: }; +template <> +inline size_t BaseKernel::n_elements() const { return n_vertices(); } +template <> +inline size_t BaseKernel::n_elements() const { return n_halfedges(); } +template <> +inline size_t BaseKernel::n_elements() const { return n_edges(); } +template <> +inline size_t BaseKernel::n_elements() const { return n_faces(); } + + //============================================================================= } // namespace OpenMesh //============================================================================= From 3d648b23b30b7e4fba12d8fb2e71ef927a84389d Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 14:01:50 +0100 Subject: [PATCH 31/60] add elements and all_elements methods that return the range corresponding to the template argument --- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index 78e8a3f9..6973f614 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -1169,6 +1169,9 @@ public: &PolyConnectivity::faces_sbegin, &PolyConnectivity::faces_end> ConstFaceRangeSkipping; + template + struct ElementRange; + /** * @return The vertices as a range object suitable * for C++11 range based for loops. Will skip deleted vertices. @@ -1217,6 +1220,21 @@ public: */ ConstFaceRange all_faces() const { return ConstFaceRange(*this); } + /** + * @return The elements corresponding to the template type as a range object suitable + * for C++11 range based for loops. Will skip deleted faces. + */ + template + typename ElementRange::RangeSkipping elements() const; + + /** + * @return The elements corresponding to the template type as a range object suitable + * for C++11 range based for loops. Will include deleted faces. + */ + template + typename ElementRange::Range all_elements() const; + + /// Generic class for iterator ranges. template< typename CONTAINER_TYPE, @@ -1241,6 +1259,7 @@ public: CENTER_ENTITY_TYPE center_; }; + typedef CirculatorRange< PolyConnectivity, ConstVertexVertexCWIter, @@ -1625,6 +1644,52 @@ private: // Working storage for add_face() }; +template <> +struct PolyConnectivity::ElementRange +{ + using Range = ConstVertexRange; + using RangeSkipping = ConstVertexRangeSkipping; +}; + +template <> +struct PolyConnectivity::ElementRange +{ + using Range = ConstHalfedgeRange; + using RangeSkipping = ConstHalfedgeRangeSkipping; +}; + +template <> +struct PolyConnectivity::ElementRange +{ + using Range = ConstEdgeRange; + using RangeSkipping = ConstEdgeRangeSkipping; +}; + +template <> +struct PolyConnectivity::ElementRange +{ + using Range = ConstFaceRange; + using RangeSkipping = ConstFaceRangeSkipping; +}; + + +template <> +inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::elements() const { return ConstVertexRangeSkipping(*this); } +template <> +inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_elements() const { return ConstVertexRange(*this); } +template <> +inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::elements() const { return ConstHalfedgeRangeSkipping(*this); } +template <> +inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_elements() const { return ConstHalfedgeRange(*this); } +template <> +inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::elements() const { return ConstEdgeRangeSkipping(*this); } +template <> +inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_elements() const { return ConstEdgeRange(*this); } +template <> +inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::elements() const { return ConstFaceRangeSkipping(*this); } +template <> +inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_elements() const { return ConstFaceRange(*this); } + }//namespace OpenMesh #endif//OPENMESH_POLYCONNECTIVITY_HH From 8bc5491c5cd623e7908f13d71ba4f56bcbcd5a3c Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 14:02:43 +0100 Subject: [PATCH 32/60] add Handle typedef to PropHandleT that specifies the corresponding element handle type --- src/OpenMesh/Core/Utils/Property.hh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/OpenMesh/Core/Utils/Property.hh b/src/OpenMesh/Core/Utils/Property.hh index 7f913ec1..cf2fdf5c 100644 --- a/src/OpenMesh/Core/Utils/Property.hh +++ b/src/OpenMesh/Core/Utils/Property.hh @@ -485,6 +485,7 @@ struct VPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef VertexHandle Handle; explicit VPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit VPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} @@ -499,6 +500,7 @@ struct HPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef HalfedgeHandle Handle; explicit HPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit HPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} @@ -513,6 +515,7 @@ struct EPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef EdgeHandle Handle; explicit EPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit EPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} @@ -527,6 +530,7 @@ struct FPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef FaceHandle Handle; explicit FPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit FPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} From de529269b508acf6638b2892435608f159640d77 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 14:09:08 +0100 Subject: [PATCH 33/60] remove second template argument off PropertyManager --- src/OpenMesh/Core/Utils/PropertyManager.hh | 124 ++++++++++++--------- 1 file changed, 70 insertions(+), 54 deletions(-) diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index fb3860f5..9319184d 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -59,6 +60,8 @@ namespace OpenMesh { * makeTemporaryProperty(), getProperty(), and getOrMakeProperty() * to construct a PropertyManager, e.g. * + * Note that the second template parameter is depcretated. + * * \code * { * TriMesh mesh; @@ -73,7 +76,7 @@ namespace OpenMesh { * } * \endcode */ -template +template class PropertyManager { #if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) public: @@ -110,7 +113,7 @@ class PropertyManager { * @see PropertyManager::createIfNotExists, makePropertyManagerFromNew, * makePropertyManagerFromExisting, makePropertyManagerFromExistingOrNew */ - PropertyManager(MeshT &mesh, const char *propname, bool existing = false) : mesh_(&mesh), retain_(existing), name_(propname) { + PropertyManager(PolyConnectivity& mesh, const char *propname, bool existing = false) : mesh_(&mesh), retain_(existing), name_(propname) { if (existing) { if (!mesh_->get_property_handle(prop_, propname)) { std::ostringstream oss; @@ -136,24 +139,40 @@ class PropertyManager { std::swap(name_, rhs.name_); } - static bool propertyExists(MeshT &mesh, const char *propname) { + static bool propertyExists(PolyConnectivity &mesh, const char *propname) { PROPTYPE dummy; return mesh.get_property_handle(dummy, propname); } - bool isValid() const { return mesh_ != 0; } + bool isValid() const { return prop_.is_valid(); } operator bool() const { return isValid(); } const PROPTYPE &getRawProperty() const { return prop_; } const std::string &getName() const { return name_; } - MeshT &getMesh() const { return *mesh_; } + /** + * Get the mesh corresponding to the property. + * + * If you use PropertyManager without second template parameter (recommended) + * you need to specify the actual mesh type when using this function, e.g.: + * \code + * { + * TriMesh mesh; + * auto visited = VProp(mesh); + * TriMesh& mesh_ref = visited.getMesh(); + * } + * + */ + template + MeshType& getMesh() const { return dynamic_cast(mesh_); } + + MeshT& getMesh() const { return dynamic_cast(mesh_); } #if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) /// Only for pre C++11 compatibility. - typedef PropertyManager Proxy; + typedef PropertyManager Proxy; /** * Move constructor. Transfers ownership (delete responsibility). @@ -184,7 +203,7 @@ class PropertyManager { * * @see makePropertyManagerFromExistingOrNew */ - static PropertyManager createIfNotExists(MeshT &mesh, const char *propname) { + static PropertyManager createIfNotExists(PolyConnectivity &mesh, const char *propname) { PROPTYPE dummy_prop; PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname)); pm.retain(); @@ -201,7 +220,7 @@ class PropertyManager { * @see makePropertyManagerFromExistingOrNew */ template - static PropertyManager createIfNotExists(MeshT &mesh, const char *propname, + static PropertyManager createIfNotExists(PolyConnectivity &mesh, const char *propname, const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end, const PROP_VALUE &init_value) { const bool exists = propertyExists(mesh, propname); @@ -222,7 +241,7 @@ class PropertyManager { * @see makePropertyManagerFromExistingOrNew */ template - static PropertyManager createIfNotExists(MeshT &mesh, const char *propname, + static PropertyManager createIfNotExists(PolyConnectivity &mesh, const char *propname, const ITERATOR_RANGE &range, const PROP_VALUE &init_value) { return createIfNotExists( mesh, propname, range.begin(), range.end(), init_value); @@ -244,9 +263,9 @@ class PropertyManager { #else class Proxy { private: - Proxy(MeshT *mesh_, PROPTYPE prop_, bool retain_, const std::string &name_) : + Proxy(PolyConnectivity *mesh_, PROPTYPE prop_, bool retain_, const std::string &name_) : mesh_(mesh_), prop_(prop_), retain_(retain_), name_(name_) {} - MeshT *mesh_; + PolyConnectivity *mesh_; PROPTYPE prop_; bool retain_; std::string name_; @@ -279,7 +298,7 @@ class PropertyManager { * * @see makePropertyManagerFromExistingOrNew */ - static Proxy createIfNotExists(MeshT &mesh, const char *propname) { + static Proxy createIfNotExists(PolyConnectivity &mesh, const char *propname) { PROPTYPE dummy_prop; PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname)); pm.retain(); @@ -296,7 +315,7 @@ class PropertyManager { * @see makePropertyManagerFromExistingOrNew */ template - static Proxy createIfNotExists(MeshT &mesh, const char *propname, + static Proxy createIfNotExists(PolyConnectivity &mesh, const char *propname, const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end, const PROP_VALUE &init_value) { const bool exists = propertyExists(mesh, propname); @@ -386,7 +405,7 @@ class PropertyManager { * Examples: * \code * MeshT mesh; - * PropertyManager, MeshT> distance( + * PropertyManager> distance( * mesh, "distance.plugin-example.i8.informatik.rwth-aachen.de"); * distance.set_range( * mesh.vertices_begin(), mesh.vertices_end(), @@ -434,9 +453,9 @@ class PropertyManager { * Will be used with dst_propmanager. Used to double check the bounds. */ template + typename HandleTypeIterator_2> void copy_to(HandleTypeIterator begin, HandleTypeIterator end, - PropertyManager &dst_propmanager, + PropertyManager &dst_propmanager, HandleTypeIterator_2 dst_begin, HandleTypeIterator_2 dst_end) const { for (; begin != end && dst_begin != dst_end; ++begin, ++dst_begin) { @@ -445,9 +464,9 @@ class PropertyManager { } template + typename RangeType_2> void copy_to(const RangeType &range, - PropertyManager &dst_propmanager, + PropertyManager &dst_propmanager, const RangeType_2 &dst_range) const { copy_to(range.begin(), range.end(), dst_propmanager, dst_range.begin(), dst_range.end()); @@ -467,15 +486,15 @@ class PropertyManager { * @param dst_mesh Destination mesh on which to copy. * @param dst_range Destination range. */ - template + template static void copy(const char *prop_name, - MeshT &src_mesh, const RangeType &src_range, - MeshT_2 &dst_mesh, const RangeType_2 &dst_range) { + PolyConnectivity &src_mesh, const RangeType &src_range, + PolyConnectivity &dst_mesh, const RangeType_2 &dst_range) { - typedef OpenMesh::PropertyManager DstPM; + typedef OpenMesh::PropertyManager DstPM; DstPM dst(DstPM::createIfNotExists(dst_mesh, prop_name)); - typedef OpenMesh::PropertyManager SrcPM; + typedef OpenMesh::PropertyManager SrcPM; SrcPM src(src_mesh, prop_name, true); src.copy_to(src_range, dst, dst_range); @@ -488,7 +507,7 @@ class PropertyManager { } private: - MeshT *mesh_; + PolyConnectivity* mesh_; PROPTYPE prop_; bool retain_; std::string name_; @@ -517,13 +536,12 @@ class PropertyManager { * @param propname (optional) The name of the created property * @tparam ElementT Element type of the created property, e.g. VertexHandle, HalfedgeHandle, etc. * @tparam T Value type of the created property, e.g., \p double, \p int, etc. - * @tparam MeshT Type of the mesh. Can often be inferred from \p mesh * @returns A PropertyManager handling the lifecycle of the property */ -template -PropertyManager::type, MeshT> -makeTemporaryProperty(MeshT &mesh, const char *propname = "") { - return PropertyManager::type, MeshT>(mesh, propname, false); +template +PropertyManager::type> +makeTemporaryProperty(PolyConnectivity &mesh, const char *propname = "") { + return PropertyManager::type>(mesh, propname, false); } /** @relates PropertyManager @@ -551,13 +569,12 @@ makeTemporaryProperty(MeshT &mesh, const char *propname = "") { * @param propname The name of the created property * @tparam ElementT Element type of the created property, e.g. VertexHandle, HalfedgeHandle, etc. * @tparam T Value type of the created property, e.g., \p double, \p int, etc. - * @tparam MeshT Type of the mesh. Can often be inferred from \p mesh * @returns A PropertyManager wrapping the property */ -template -PropertyManager::type, MeshT> -getProperty(MeshT &mesh, const char *propname) { - return PropertyManager::type, MeshT>(mesh, propname, true); +template +PropertyManager::type> +getProperty(PolyConnectivity &mesh, const char *propname) { + return PropertyManager::type>(mesh, propname, true); } /** @relates PropertyManager @@ -587,13 +604,12 @@ getProperty(MeshT &mesh, const char *propname) { * @param propname The name of the created property * @tparam ElementT Element type of the created property, e.g. VertexHandle, HalfedgeHandle, etc. * @tparam T Value type of the created property, e.g., \p double, \p int, etc. - * @tparam MeshT Type of the mesh. Can often be inferred from \p mesh * @returns A PropertyManager wrapping the property */ -template -PropertyManager::type, MeshT> -getOrMakeProperty(MeshT &mesh, const char *propname) { - return PropertyManager::type, MeshT>::createIfNotExists(mesh, propname); +template +PropertyManager::type> +getOrMakeProperty(PolyConnectivity &mesh, const char *propname) { + return PropertyManager::type>::createIfNotExists(mesh, propname); } /** @relates PropertyManager @@ -617,9 +633,9 @@ getOrMakeProperty(MeshT &mesh, const char *propname) { * @tparam T Value type of the expected property, e.g., \p double, \p int, etc. * @tparam MeshT Type of the mesh. Can often be inferred from \p mesh */ -template +template bool -hasProperty(const MeshT &mesh, const char *propname) { +hasProperty(const PolyConnectivity &mesh, const char *propname) { typename HandleToPropHandle::type ph; return mesh.get_property_handle(ph, propname); } @@ -633,11 +649,11 @@ hasProperty(const MeshT &mesh, const char *propname) { * Intended for temporary properties. Shadows any existing properties of * matching name and type. */ -template +template OM_DEPRECATED("Use makeTemporaryProperty instead.") -PropertyManager makePropertyManagerFromNew(MeshT &mesh, const char *propname) +PropertyManager makePropertyManagerFromNew(PolyConnectivity &mesh, const char *propname) { - return PropertyManager(mesh, propname, false); + return PropertyManager(mesh, propname, false); } /** \relates PropertyManager @@ -652,11 +668,11 @@ PropertyManager makePropertyManagerFromNew(MeshT &mesh, const c * @throws std::runtime_error if no property with the name \p propname of * matching type exists. */ -template +template OM_DEPRECATED("Use getProperty instead.") -PropertyManager makePropertyManagerFromExisting(MeshT &mesh, const char *propname) +PropertyManager makePropertyManagerFromExisting(PolyConnectivity &mesh, const char *propname) { - return PropertyManager(mesh, propname, true); + return PropertyManager(mesh, propname, true); } /** @relates PropertyManager @@ -667,11 +683,11 @@ PropertyManager makePropertyManagerFromExisting(MeshT &mesh, co * * Intended for creating or accessing persistent properties. */ -template +template OM_DEPRECATED("Use getOrMakeProperty instead.") -PropertyManager makePropertyManagerFromExistingOrNew(MeshT &mesh, const char *propname) +PropertyManager makePropertyManagerFromExistingOrNew(PolyConnectivity &mesh, const char *propname) { - return PropertyManager::createIfNotExists(mesh, propname); + return PropertyManager::createIfNotExists(mesh, propname); } /** @relates PropertyManager @@ -707,14 +723,14 @@ PropertyManager makePropertyManagerFromExistingOrNew( * * Intended for creating or accessing persistent properties. */ -template OM_DEPRECATED("Use getOrMakeProperty instead.") -PropertyManager makePropertyManagerFromExistingOrNew( - MeshT &mesh, const char *propname, +PropertyManager makePropertyManagerFromExistingOrNew( + PolyConnectivity &mesh, const char *propname, const ITERATOR_RANGE &range, const PROP_VALUE &init_value) { - return makePropertyManagerFromExistingOrNew( + return makePropertyManagerFromExistingOrNew( mesh, propname, range.begin(), range.end(), init_value); } From 8a8aab33e01176221696f11c6cab29f70ceb015b Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 14:31:00 +0100 Subject: [PATCH 34/60] remove second template argument of property manager in unittests --- src/Unittests/unittests_propertymanager.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Unittests/unittests_propertymanager.cc b/src/Unittests/unittests_propertymanager.cc index 2fe59654..d8f8668e 100644 --- a/src/Unittests/unittests_propertymanager.cc +++ b/src/Unittests/unittests_propertymanager.cc @@ -62,7 +62,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { { OpenMesh::PropertyManager< - OpenMesh::VPropHandleT, Mesh> pm_v_bool(mesh_, "pm_v_bool"); + OpenMesh::VPropHandleT> pm_v_bool(mesh_, "pm_v_bool"); pm_v_bool.set_range(mesh_.vertices_begin(), mesh_.vertices_end(), false); for (int i = 0; i < 4; ++i) ASSERT_FALSE(pm_v_bool[vhandle[i]]); @@ -71,7 +71,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { ASSERT_TRUE(pm_v_bool[vhandle[i]]); OpenMesh::PropertyManager< - OpenMesh::EPropHandleT, Mesh> pm_e_bool(mesh_, "pm_e_bool"); + OpenMesh::EPropHandleT> pm_e_bool(mesh_, "pm_e_bool"); pm_e_bool.set_range(mesh_.edges_begin(), mesh_.edges_end(), false); for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end(); e_it != f_end; ++e_it) @@ -82,7 +82,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { ASSERT_TRUE(pm_e_bool[*e_it]); OpenMesh::PropertyManager< - OpenMesh::FPropHandleT, Mesh> pm_f_bool(mesh_, "pm_f_bool"); + OpenMesh::FPropHandleT> pm_f_bool(mesh_, "pm_f_bool"); pm_f_bool.set_range(mesh_.faces_begin(), mesh_.faces_end(), false); for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end(); f_it != f_end; ++f_it) @@ -98,7 +98,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { */ { OpenMesh::PropertyManager< - OpenMesh::VPropHandleT, Mesh> pm_v_bool(mesh_, "pm_v_bool2"); + OpenMesh::VPropHandleT> pm_v_bool(mesh_, "pm_v_bool2"); pm_v_bool.set_range(mesh_.vertices(), false); for (int i = 0; i < 4; ++i) ASSERT_FALSE(pm_v_bool[vhandle[i]]); @@ -107,7 +107,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { ASSERT_TRUE(pm_v_bool[vhandle[i]]); OpenMesh::PropertyManager< - OpenMesh::EPropHandleT, Mesh> pm_e_bool(mesh_, "pm_e_bool2"); + OpenMesh::EPropHandleT> pm_e_bool(mesh_, "pm_e_bool2"); pm_e_bool.set_range(mesh_.edges(), false); for (Mesh::EdgeIter e_it = mesh_.edges_begin(), f_end = mesh_.edges_end(); e_it != f_end; ++e_it) @@ -118,7 +118,7 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { ASSERT_TRUE(pm_e_bool[*e_it]); OpenMesh::PropertyManager< - OpenMesh::FPropHandleT, Mesh> pm_f_bool(mesh_, "pm_f_bool2"); + OpenMesh::FPropHandleT> pm_f_bool(mesh_, "pm_f_bool2"); pm_f_bool.set_range(mesh_.faces(), false); for (Mesh::FaceIter f_it = mesh_.faces_begin(), f_end = mesh_.faces_end(); f_it != f_end; ++f_it) From 99632809d8c14ea54667600dbb741d09a6dbc049 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 14:31:55 +0100 Subject: [PATCH 35/60] in unittest replace has_property check with the one implemented in property manager --- src/Unittests/unittests_propertymanager.cc | 26 ++++++++-------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/Unittests/unittests_propertymanager.cc b/src/Unittests/unittests_propertymanager.cc index d8f8668e..ece51b6b 100644 --- a/src/Unittests/unittests_propertymanager.cc +++ b/src/Unittests/unittests_propertymanager.cc @@ -136,27 +136,21 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { * ==================================================================== */ -template -bool has_property(const Mesh& _mesh, const std::string& _name) { - auto dummy_handle = PropHandle{}; - return _mesh.get_property_handle(dummy_handle, _name); -} - /* * Temporary property */ TEST_F(OpenMeshPropertyManager, cpp11_temp_property) { using handle_type = OpenMesh::VPropHandleT; const auto prop_name = "pm_v_test_property"; - ASSERT_FALSE(has_property(mesh_, prop_name)); + ASSERT_FALSE((OpenMesh::hasProperty(mesh_, prop_name))); { auto vprop = OpenMesh::makeTemporaryProperty(mesh_, prop_name); static_cast(vprop); // Unused variable - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); } - ASSERT_FALSE(has_property(mesh_, prop_name)); + ASSERT_FALSE((OpenMesh::hasProperty(mesh_, prop_name))); } /* @@ -166,7 +160,6 @@ TEST_F(OpenMeshPropertyManager, cpp11_temp_property) { TEST_F(OpenMeshPropertyManager, cpp11_temp_property_shadowing) { auto vh = mesh_.add_vertex({0,0,0}); // Dummy vertex to attach properties to - using handle_type = OpenMesh::VPropHandleT; const auto prop_name = "pm_v_test_property"; auto outer_prop = OpenMesh::makeTemporaryProperty(mesh_, prop_name); @@ -182,7 +175,7 @@ TEST_F(OpenMeshPropertyManager, cpp11_temp_property_shadowing) { } // Ensure outer_prop still exists and its data has not been overwritten by inner_prop - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); ASSERT_EQ(100, outer_prop[vh]); } @@ -196,10 +189,9 @@ TEST_F(OpenMeshPropertyManager, cpp11_temp_property_shadowing) { TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) { auto vh = mesh_.add_vertex({0,0,0}); // Dummy vertex to attach properties to - using handle_type = OpenMesh::VPropHandleT; const auto prop_name = "pm_v_test_property"; - ASSERT_FALSE(has_property(mesh_, prop_name)); + ASSERT_FALSE((OpenMesh::hasProperty(mesh_, prop_name))); { auto prop = OpenMesh::getOrMakeProperty(mesh_, prop_name); @@ -207,7 +199,7 @@ TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) { // End of scope, property persists } - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); { // Since a property of the same name and type already exists, this refers to the existing property. @@ -217,7 +209,7 @@ TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) { // End of scope, property persists } - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); { // Acquire non-owning handle to the property, knowing it exists @@ -225,7 +217,7 @@ TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) { ASSERT_EQ(200, prop[vh]); } - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); { // Attempt to acquire non-owning handle for a non-existing property @@ -235,7 +227,7 @@ TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) { ASSERT_THROW(code_that_throws(), std::runtime_error); } - ASSERT_TRUE(has_property(mesh_, prop_name)); + ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); } } From c861a0e84da3006243abc097f9ef86c93f132c7d Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 14:32:24 +0100 Subject: [PATCH 36/60] add method to get points property handle in AttribKernel --- src/OpenMesh/Core/Mesh/AttribKernelT.hh | 45 +++++++++++++------------ 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/src/OpenMesh/Core/Mesh/AttribKernelT.hh b/src/OpenMesh/Core/Mesh/AttribKernelT.hh index 90b10fe0..3d4d2046 100644 --- a/src/OpenMesh/Core/Mesh/AttribKernelT.hh +++ b/src/OpenMesh/Core/Mesh/AttribKernelT.hh @@ -105,10 +105,26 @@ public: FAttribs = MeshItems::FAttribs }; - typedef VPropHandleT DataVPropHandle; - typedef HPropHandleT DataHPropHandle; - typedef EPropHandleT DataEPropHandle; - typedef FPropHandleT DataFPropHandle; + typedef VPropHandleT DataVPropHandle; + typedef HPropHandleT DataHPropHandle; + typedef EPropHandleT DataEPropHandle; + typedef FPropHandleT DataFPropHandle; + + typedef VPropHandleT PointsPropertyHandle; + typedef VPropHandleT VertexNormalsPropertyHandle; + typedef VPropHandleT VertexColorsPropertyHandle; + typedef VPropHandleT VertexTexCoords1DPropertyHandle; + typedef VPropHandleT VertexTexCoords2DPropertyHandle; + typedef VPropHandleT VertexTexCoords3DPropertyHandle; + typedef HPropHandleT HalfedgeTexCoords1DPropertyHandle; + typedef HPropHandleT HalfedgeTexCoords2DPropertyHandle; + typedef HPropHandleT HalfedgeTexCoords3DPropertyHandle; + typedef EPropHandleT EdgeColorsPropertyHandle; + typedef HPropHandleT HalfedgeNormalsPropertyHandle; + typedef HPropHandleT HalfedgeColorsPropertyHandle; + typedef FPropHandleT FaceNormalsPropertyHandle; + typedef FPropHandleT FaceColorsPropertyHandle; + typedef FPropHandleT FaceTextureIndexPropertyHandle; public: @@ -240,6 +256,9 @@ public: void set_point(VertexHandle _vh, const Point& _p) { this->property(points_, _vh) = _p; } + PointsPropertyHandle& points_property_handle() + { return points_; } + //------------------------------------------------------------ vertex normals @@ -592,24 +611,6 @@ public: bool has_face_colors() const { return face_colors_.is_valid(); } bool has_face_texture_index() const { return face_texture_index_.is_valid(); } -public: - - typedef VPropHandleT PointsPropertyHandle; - typedef VPropHandleT VertexNormalsPropertyHandle; - typedef VPropHandleT VertexColorsPropertyHandle; - typedef VPropHandleT VertexTexCoords1DPropertyHandle; - typedef VPropHandleT VertexTexCoords2DPropertyHandle; - typedef VPropHandleT VertexTexCoords3DPropertyHandle; - typedef HPropHandleT HalfedgeTexCoords1DPropertyHandle; - typedef HPropHandleT HalfedgeTexCoords2DPropertyHandle; - typedef HPropHandleT HalfedgeTexCoords3DPropertyHandle; - typedef EPropHandleT EdgeColorsPropertyHandle; - typedef HPropHandleT HalfedgeNormalsPropertyHandle; - typedef HPropHandleT HalfedgeColorsPropertyHandle; - typedef FPropHandleT FaceNormalsPropertyHandle; - typedef FPropHandleT FaceColorsPropertyHandle; - typedef FPropHandleT FaceTextureIndexPropertyHandle; - public: //standard vertex properties PointsPropertyHandle points_pph() const From c79d85c3a0d14b4770cf03aaba7fa4dd0c8f94ea Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 15:24:42 +0100 Subject: [PATCH 37/60] remove second template argument of propertymanager in subdivider --- src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh b/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh index 3014449c..b22b7782 100644 --- a/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh +++ b/src/OpenMesh/Tools/Subdivider/Uniform/MidpointT.hh @@ -51,8 +51,8 @@ protected: // SubdividerT interface _m.request_edge_status(); _m.request_vertex_status(); _m.request_face_status(); - PropertyManager, mesh_t> edge_midpoint(_m, "edge_midpoint"); - PropertyManager, mesh_t> is_original_vertex(_m, "is_original_vertex"); + PropertyManager> edge_midpoint(_m, "edge_midpoint"); + PropertyManager> is_original_vertex(_m, "is_original_vertex"); for (size_t iteration = 0; iteration < _n; ++iteration) { is_original_vertex.set_range(_m.vertices_begin(), _m.vertices_end(), true); From 3c52a276150574aca2e883be6e06cfb0eb37d7cb Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 15:27:34 +0100 Subject: [PATCH 38/60] rework property manager --- src/OpenMesh/Core/Utils/PropertyManager.hh | 253 +++++++-- src/Unittests/unittests_propertymanager.cc | 610 +++++++++++++++++++++ 2 files changed, 803 insertions(+), 60 deletions(-) diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index 9319184d..183a77f5 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -78,25 +78,15 @@ namespace OpenMesh { */ template class PropertyManager { -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) - public: - PropertyManager(const PropertyManager&) = delete; - PropertyManager& operator=(const PropertyManager&) = delete; -#else - private: - /** - * Noncopyable because there aren't no straightforward copy semantics. - */ - PropertyManager(const PropertyManager&); - - /** - * Noncopyable because there aren't no straightforward copy semantics. - */ - PropertyManager& operator=(const PropertyManager&); -#endif public: + using Value = typename PROPTYPE::Value; + using value_type = typename PROPTYPE::value_type; + using Handle = typename PROPTYPE::Handle; + /** + * @deprecated Use a constructor without \p existing and check existance with hasProperty() instead. + * * Constructor. * * Throws an \p std::runtime_error if \p existing is true and @@ -110,22 +100,114 @@ class PropertyManager { * the instance merely acts as a convenience wrapper around an existing property with no * lifecycle management whatsoever. * - * @see PropertyManager::createIfNotExists, makePropertyManagerFromNew, - * makePropertyManagerFromExisting, makePropertyManagerFromExistingOrNew + * @see PropertyManager::getOrMakeProperty, PropertyManager::getProperty, + * PropertyManager::makeTemporaryProperty */ - PropertyManager(PolyConnectivity& mesh, const char *propname, bool existing = false) : mesh_(&mesh), retain_(existing), name_(propname) { + OM_DEPRECATED("Use the constructor without parameter 'existing' instead. Check for existance with hasProperty") + PropertyManager(PolyConnectivity& mesh, const char *propname, bool existing) : mesh_(mesh), retain_(existing), name_(propname) { if (existing) { - if (!mesh_->get_property_handle(prop_, propname)) { + if (!mesh_.get_property_handle(prop_, propname)) { std::ostringstream oss; oss << "Requested property handle \"" << propname << "\" does not exist."; throw std::runtime_error(oss.str()); } } else { - mesh_->add_property(prop_, propname); + mesh_.add_property(prop_, propname); } } - PropertyManager() : mesh_(0), retain_(false) { + /** + * Constructor. + * + * Asks for a property with name propname and creates one if none exists. Lifetime is not managed. + * + * @param mesh The mesh on which to create the property. + * @param propname The name of the property. + */ + PropertyManager(PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { + if (!mesh_.get_property_handle(prop_, propname)) { + mesh_.add_property(prop_, propname); + } + } + + /** + * Constructor. + * + * Asks for a property with name propname and creates one if none exists. Lifetime is not managed. + * If the property is created it is initialized with \p initial_value + * + * @param mesh The mesh on which to create the property. + * @param initial_value + * @param propname The name of the property. + */ + PropertyManager(const Value& intial_value, PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { + if (!mesh_.get_property_handle(prop_, propname)) { + mesh_.add_property(prop_, propname); + set_range(mesh_.all_elements(), intial_value); + } + } + + /** + * Constructor. + * + * Create an anonymous property. Lifetime is managed. + * + * @param mesh The mesh on which to create the property. + */ + PropertyManager(PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { + mesh_.add_property(prop_, name_); + } + + /** + * Constructor. + * + * Create an anonymous property. Lifetime is managed. + * If the property is created it is initialized with \p initial_value + * + * @param mesh The mesh on which to create the property. + */ + PropertyManager(const Value& intial_value, PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { + mesh_.add_property(prop_, name_); + set_range(mesh_.all_elements(), intial_value); + } + + /** + * Constructor. + * + * Create a wrapper around an existing property. Lifetime is not managed. + * + * @param mesh The mesh on which to create the property. + */ + PropertyManager(PolyConnectivity& mesh, PROPTYPE property_handle) : mesh_(mesh), prop_(property_handle), retain_(true), name_() { + } + + PropertyManager() = delete; + + PropertyManager(const PropertyManager& rhs) + : + mesh_(rhs.mesh_), + prop_(), + retain_(rhs.retain_), + name_(rhs.name_) + { + if (rhs.retain_) // named property -> create a property manager referring to the same + { + prop_ = rhs.prop_; + } + else // unnamed property -> create a property manager refering to a new property and copy the contents + { + mesh_.add_property(prop_, name_); + rhs.copy_to(rhs.mesh_.template all_elements(), *this, mesh_.all_elements()); + } + } + + PropertyManager& operator=(const PropertyManager& rhs) + { + if (&mesh_ == &rhs.mesh_ && prop_ == rhs.prop_) + ; // nothing to do + else + rhs.copy_to(rhs.mesh_.template all_elements(), *this, mesh_.all_elements()); + return *this; } ~PropertyManager() { @@ -177,21 +259,40 @@ class PropertyManager { /** * Move constructor. Transfers ownership (delete responsibility). */ - PropertyManager(PropertyManager &&rhs) : mesh_(rhs.mesh_), prop_(rhs.prop_), retain_(rhs.retain_), name_(rhs.name_) { - rhs.retain_ = true; + PropertyManager(PropertyManager &&rhs) + : + mesh_(rhs.mesh_), + prop_(rhs.prop_), + retain_(rhs.retain_), + name_(rhs.name_) + { + if (!rhs.retain_) + rhs.prop_.invalidate(); // only invalidate unnamed properties } /** * Move assignment. Transfers ownership (delete responsibility). */ - PropertyManager &operator=(PropertyManager &&rhs) { - if (&rhs != this) { - deleteProperty(); - mesh_ = rhs.mesh_; - prop_ = rhs.prop_; - retain_ = rhs.retain_; - name_ = rhs.name_; - rhs.retain_ = true; + PropertyManager& operator=(PropertyManager&& rhs) + { + if ((&mesh_ != &rhs.mesh_) || (prop_ != rhs.prop_)) + { + if (rhs.retain_) + { + // retained properties cannot be invalidated. Copy instead + rhs.copy_to(rhs.mesh_.template all_elements(), *this, mesh_.all_elements()); + } + else + { + // switch the data stored in the properties + std::swap(mesh_.property(prop_).data_vector(), rhs.mesh_.property(rhs.prop_).data_vector()); + // resize the property to the correct size + mesh_.property(prop_).resize(mesh_.n_elements()); + // remove the property from rhs + rhs.mesh_.remove_property(rhs.prop_); + // invalidate prop_ + rhs.prop_.invalidate(); + } } return *this; } @@ -204,10 +305,7 @@ class PropertyManager { * @see makePropertyManagerFromExistingOrNew */ static PropertyManager createIfNotExists(PolyConnectivity &mesh, const char *propname) { - PROPTYPE dummy_prop; - PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname)); - pm.retain(); - return std::move(pm); + return PropertyManager(mesh, propname); } /** @@ -248,8 +346,8 @@ class PropertyManager { } PropertyManager duplicate(const char *clone_name) { - PropertyManager pm(*mesh_, clone_name, false); - pm.mesh_->property(pm.prop_) = mesh_->property(prop_); + PropertyManager pm(mesh_, clone_name, false); + pm.mesh_.property(pm.prop_) = mesh_.property(prop_); return pm; } @@ -328,21 +426,11 @@ class PropertyManager { Proxy duplicate(const char *clone_name) { PropertyManager pm(*mesh_, clone_name, false); - pm.mesh_->property(pm.prop_) = mesh_->property(prop_); + pm.mesh_.property(pm.prop_) = mesh_.property(prop_); return (Proxy)pm; } #endif - /** - * \brief Disable lifecycle management for this property. - * - * If this method is called, the encapsulated property will not be deleted - * upon destruction of the PropertyManager instance. - */ - inline void retain(bool doRetain = true) { - retain_ = doRetain; - } - /** * Access the value of the encapsulated mesh property. * @@ -356,7 +444,7 @@ class PropertyManager { * @note This method is only used for mesh properties. */ typename PROPTYPE::reference& operator*() { - return mesh_->mproperty(prop_)[0]; + return mesh_.mproperty(prop_)[0]; } /** @@ -372,7 +460,7 @@ class PropertyManager { * @note This method is only used for mesh properties. */ typename PROPTYPE::const_reference& operator*() const { - return mesh_->mproperty(prop_)[0]; + return mesh_.mproperty(prop_)[0]; } /** @@ -384,7 +472,7 @@ class PropertyManager { */ template inline typename PROPTYPE::reference operator[] (const HandleType &handle) { - return mesh_->property(prop_, handle); + return mesh_.property(prop_, handle); } /** @@ -396,7 +484,7 @@ class PropertyManager { */ template inline typename PROPTYPE::const_reference operator[] (const HandleType &handle) const { - return mesh_->property(prop_, handle); + return mesh_.property(prop_, handle); } /** @@ -502,12 +590,12 @@ class PropertyManager { private: void deleteProperty() { - if (!retain_) - mesh_->remove_property(prop_); + if (!retain_ && prop_.is_valid()) + mesh_.remove_property(prop_); } private: - PolyConnectivity* mesh_; + PolyConnectivity& mesh_; PROPTYPE prop_; bool retain_; std::string name_; @@ -544,6 +632,27 @@ makeTemporaryProperty(PolyConnectivity &mesh, const char *propname = "") { return PropertyManager::type>(mesh, propname, false); } +///// shortcut or makeTemporaryrProperty +//template +//PropertyManager::type, MeshT> +//makeTemporaryVertexProperty(MeshT &mesh, const char *propname) { return makeTemporaryProperty(mesh, propname); } + +///// shortcut or makeTemporaryrProperty +//template +//PropertyManager::type, MeshT> +//makeTemporaryHalfedgeProperty(MeshT &mesh, const char *propname) { return makeTemporaryProperty(mesh, propname); } + +///// shortcut or makeTemporaryrProperty +//template +//PropertyManager::type, MeshT> +//makeTemporaryEdgeProperty(MeshT &mesh, const char *propname) { return makeTemporaryProperty(mesh, propname); } + +///// shortcut or makeTemporaryrProperty +//template +//PropertyManager::type, MeshT> +//makeTemporaryFaceProperty(MeshT &mesh, const char *propname) { return makeTemporaryProperty(mesh, propname); } + + /** @relates PropertyManager * * Obtains a handle to a named property. @@ -701,14 +810,14 @@ PropertyManager makePropertyManagerFromExistingOrNew(PolyConnectivity * * Intended for creating or accessing persistent properties. */ -template OM_DEPRECATED("Use getOrMakeProperty instead.") -PropertyManager makePropertyManagerFromExistingOrNew( - MeshT &mesh, const char *propname, +PropertyManager makePropertyManagerFromExistingOrNew( + PolyConnectivity &mesh, const char *propname, const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end, const PROP_VALUE &init_value) { - return PropertyManager::createIfNotExists( + return PropertyManager::createIfNotExists( mesh, propname, begin, end, init_value); } @@ -734,5 +843,29 @@ PropertyManager makePropertyManagerFromExistingOrNew( mesh, propname, range.begin(), range.end(), init_value); } + +/** @relates PropertyManager + * Returns a convenience wrapper around the points property of a mesh. + */ +template +PropertyManager> +getPointsProperty(MeshT &mesh) { + return PropertyManager>(mesh, mesh.points_property_handle()); +} + + +template +using VProp = PropertyManager>; + +template +using HProp = PropertyManager>; + +template +using EProp = PropertyManager>; + +template +using FProp = PropertyManager>; + + } /* namespace OpenMesh */ #endif /* PROPERTYMANAGER_HH_ */ diff --git a/src/Unittests/unittests_propertymanager.cc b/src/Unittests/unittests_propertymanager.cc index ece51b6b..e5046194 100644 --- a/src/Unittests/unittests_propertymanager.cc +++ b/src/Unittests/unittests_propertymanager.cc @@ -230,4 +230,614 @@ TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) { ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); } + +TEST_F(OpenMeshPropertyManager, property_copy_construction) { + for (int i = 0; i < 1000000; ++i) + mesh_.add_vertex(Mesh::Point()); + + // unnamed + { + auto prop1 = OpenMesh::VProp(mesh_); + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto prop2 = prop1; // prop1 and prop2 should be two different properties with the same content + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13); + } + + // named + { + auto prop1 = OpenMesh::VProp(mesh_, "ids"); + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto prop2 = prop1; // prop1 and prop2 should refere to the same property + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13); + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0); + } +} + +TEST_F(OpenMeshPropertyManager, property_move_construction) { + for (int i = 0; i < 1000000; ++i) + mesh_.add_vertex(Mesh::Point()); + + // unnamed + { + auto prop1 = OpenMesh::VProp(mesh_); + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto t_start = std::chrono::high_resolution_clock::now(); + auto prop2 = std::move(prop1); + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "move constructing property from temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_FALSE(prop1.isValid()) << "prop1 should have been invalidated"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13); + } + + // named + { + auto prop1 = OpenMesh::VProp(mesh_, "ids"); + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto t_start = std::chrono::high_resolution_clock::now(); + auto prop2 = std::move(prop1); // prop1 and prop2 should refere to the same property + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "move constructing from named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_TRUE(prop1.isValid()) << "named properties cannot be invalidated"; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "property is not valid anymore"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "did not copy property correctly"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0); + } +} + + +TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { + + for (int i = 0; i < 1000000; ++i) + mesh_.add_vertex(Mesh::Point()); + + // unnamed to unnamed + { + auto prop1 = OpenMesh::VProp(3, mesh_); + auto prop2 = OpenMesh::VProp(0, mesh_); + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 3) << "Property not initialized correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // unnamed to named + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(0, mesh_, "ids"); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], -13) << "property with name 'ids' was not correctly changed"; + } + + // named to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_, "ids2"); + auto prop2 = OpenMesh::VProp(mesh_); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + } + + // named to named (different names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids3"); + auto prop2 = OpenMesh::VProp(mesh_, "ids4"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // named to named (same names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids5"); + auto prop2 = OpenMesh::VProp(mesh_, "ids5"); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; // this should be a no op + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + prop1.set_range(mesh_.vertices(), 42); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids5"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + } +} + + +TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) { + + for (int i = 0; i < 1000000; ++i) + mesh_.add_vertex(Mesh::Point()); + + // unnamed to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(mesh_); + prop2.set_range(mesh_.vertices(), 0); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); // this should be cheap + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // unnamed to named + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(mesh_, "ids"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], -13) << "property with name 'ids' was not correctly changed"; + } + + // named to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_, "ids2"); + auto prop2 = OpenMesh::VProp(mesh_); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + } + + // named to named (different names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids3"); + auto prop2 = OpenMesh::VProp(mesh_, "ids4"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // named to named (same names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids5"); + auto prop2 = OpenMesh::VProp(mesh_, "ids5"); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); // this should be a no op + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids5"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + } +} + + + +TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { + + for (int i = 0; i < 1000000; ++i) + mesh_.add_vertex(Mesh::Point()); + + auto copy = mesh_; + for (int i = 0; i < 10; ++i) + copy.add_vertex(Mesh::Point()); + + // unnamed to unnamed + { + auto prop1 = OpenMesh::VProp(3, mesh_); + auto prop2 = OpenMesh::VProp(0, copy); + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 3) << "Property not initialized correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_NO_FATAL_FAILURE(prop2[OpenMesh::VertexHandle(copy.n_vertices()-1)]) << "Property not correctly resized"; + } + + // unnamed to named + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(0, copy, "ids"); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(copy, "ids"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], -13) << "property with name 'ids' was not correctly changed"; + } + + // named to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_, "ids2"); + auto prop2 = OpenMesh::VProp(copy); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + } + + // named to named (different names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids3"); + auto prop2 = OpenMesh::VProp(copy, "ids4"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // named to named (same names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids5"); + auto prop2 = OpenMesh::VProp(copy, "ids5"); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = prop1; // this should be a no op + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "copying property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + prop1.set_range(mesh_.vertices(), 42); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids5"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + auto prop4 = OpenMesh::VProp(copy, "ids5"); + EXPECT_EQ(prop4[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } +} + + +TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { + + for (int i = 0; i < 1000000; ++i) + mesh_.add_vertex(Mesh::Point()); + + auto copy = mesh_; + for (int i = 0; i < 10; ++i) + copy.add_vertex(Mesh::Point()); + + // unnamed to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(copy); + prop2.set_range(mesh_.vertices(), 0); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); // this should be cheap + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_NO_FATAL_FAILURE(prop2[OpenMesh::VertexHandle(copy.n_vertices()-1)]) << "Property not correctly resized"; + } + + // unnamed to named + { + auto prop1 = OpenMesh::VProp(mesh_); + auto prop2 = OpenMesh::VProp(copy, "ids"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(copy, "ids"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], -13) << "property with name 'ids' was not correctly changed"; + } + + // named to unnamed + { + auto prop1 = OpenMesh::VProp(mesh_, "ids2"); + auto prop2 = OpenMesh::VProp(copy); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + } + + // named to named (different names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids3"); + auto prop2 = OpenMesh::VProp(copy, "ids4"); + prop2.set_range(mesh_.vertices(), 0); + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + prop1.set_range(mesh_.vertices(), 0); + + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } + + // named to named (same names) + { + auto prop1 = OpenMesh::VProp(mesh_, "ids5"); + auto prop2 = OpenMesh::VProp(copy, "ids5"); + + for (auto vh : mesh_.vertices()) + prop1[vh] = vh.idx()*2-13; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto t_start = std::chrono::high_resolution_clock::now(); + prop2 = std::move(prop1); // should copy + auto t_end = std::chrono::high_resolution_clock::now(); + std::cout << "moving property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + + EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + prop1.set_range(mesh_.vertices(), 42); + + EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + + auto prop3 = OpenMesh::VProp(mesh_, "ids5"); + EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; + auto prop4 = OpenMesh::VProp(copy, "ids5"); + EXPECT_EQ(prop4[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; + } +} + + + } From 9b14efaa6dc6c36ad654e27711df30a82227b13a Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 31 Oct 2019 17:56:37 +0100 Subject: [PATCH 39/60] fix property manager for mesh properties --- src/OpenMesh/Core/Utils/Property.hh | 28 ++++ src/OpenMesh/Core/Utils/PropertyManager.hh | 172 ++++++++++++++------- src/Unittests/unittests_propertymanager.cc | 65 +------- 3 files changed, 152 insertions(+), 113 deletions(-) diff --git a/src/OpenMesh/Core/Utils/Property.hh b/src/OpenMesh/Core/Utils/Property.hh index cf2fdf5c..fb97f81c 100644 --- a/src/OpenMesh/Core/Utils/Property.hh +++ b/src/OpenMesh/Core/Utils/Property.hh @@ -545,11 +545,39 @@ struct MPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; + typedef void Handle; explicit MPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit MPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} }; +template +struct PropHandle; + +template <> +struct PropHandle { + template + using type = VPropHandleT; +}; + +template <> +struct PropHandle { + template + using type = HPropHandleT; +}; + +template <> +struct PropHandle { + template + using type = EPropHandleT; +}; + +template <> +struct PropHandle { + template + using type = FPropHandleT; +}; + } // namespace OpenMesh //============================================================================= #endif // OPENMESH_PROPERTY_HH defined diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index 183a77f5..cc462fd5 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -83,6 +83,43 @@ class PropertyManager { using Value = typename PROPTYPE::Value; using value_type = typename PROPTYPE::value_type; using Handle = typename PROPTYPE::Handle; + using Self = PropertyManager; + + private: + // Mesh properties (MPropHandleT<...>) are stored differently than the other properties. + // This class implements different behavior when copying or swapping data from one + // property manager to a another one. + template + struct StorageT; + + // specialization for Mesh Properties + template + struct StorageT> { + static void copy(const PropertyManager& from, PropertyManager2& to) { + *to = *from; + } + static void swap(PropertyManager& from, PropertyManager2& to) { + std::swap(*to, *from); + } + }; + + // definition for other Mesh Properties + template + struct StorageT { + static void copy(const PropertyManager& from, PropertyManager2& to) { + from.copy_to(from.mesh_.template all_elements(), to, to.mesh_.template all_elements()); + } + static void swap(PropertyManager& lhs, PropertyManager2& rhs) { + std::swap(lhs.mesh_.property(lhs.prop_).data_vector(), rhs.mesh_.property(rhs.prop_).data_vector()); + // resize the property to the correct size + lhs.mesh_.property(lhs.prop_).resize(lhs.mesh_.template n_elements()); + rhs.mesh_.property(rhs.prop_).resize(rhs.mesh_.template n_elements()); + } + }; + + using Storage = StorageT; + + public: /** * @deprecated Use a constructor without \p existing and check existance with hasProperty() instead. @@ -140,7 +177,7 @@ class PropertyManager { * @param initial_value * @param propname The name of the property. */ - PropertyManager(const Value& intial_value, PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { + PropertyManager(PolyConnectivity& mesh, const char *propname, const Value& intial_value) : mesh_(mesh), retain_(true), name_(propname) { if (!mesh_.get_property_handle(prop_, propname)) { mesh_.add_property(prop_, propname); set_range(mesh_.all_elements(), intial_value); @@ -166,7 +203,7 @@ class PropertyManager { * * @param mesh The mesh on which to create the property. */ - PropertyManager(const Value& intial_value, PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { + PropertyManager(PolyConnectivity& mesh, const Value& intial_value) : mesh_(mesh), retain_(false), name_("") { mesh_.add_property(prop_, name_); set_range(mesh_.all_elements(), intial_value); } @@ -197,7 +234,7 @@ class PropertyManager { else // unnamed property -> create a property manager refering to a new property and copy the contents { mesh_.add_property(prop_, name_); - rhs.copy_to(rhs.mesh_.template all_elements(), *this, mesh_.all_elements()); + Storage::copy(rhs, *this); } } @@ -206,7 +243,7 @@ class PropertyManager { if (&mesh_ == &rhs.mesh_ && prop_ == rhs.prop_) ; // nothing to do else - rhs.copy_to(rhs.mesh_.template all_elements(), *this, mesh_.all_elements()); + Storage::copy(rhs, *this); return *this; } @@ -280,14 +317,12 @@ class PropertyManager { if (rhs.retain_) { // retained properties cannot be invalidated. Copy instead - rhs.copy_to(rhs.mesh_.template all_elements(), *this, mesh_.all_elements()); + Storage::copy(rhs, *this); } else { // switch the data stored in the properties - std::swap(mesh_.property(prop_).data_vector(), rhs.mesh_.property(rhs.prop_).data_vector()); - // resize the property to the correct size - mesh_.property(prop_).resize(mesh_.n_elements()); + Storage::swap(rhs, *this); // remove the property from rhs rhs.mesh_.remove_property(rhs.prop_); // invalidate prop_ @@ -560,6 +595,7 @@ class PropertyManager { dst_range.begin(), dst_range.end()); } + /** * Copy the values of a property from a source range to * a target range. The source range must not be smaller than the @@ -602,6 +638,8 @@ class PropertyManager { }; /** @relates PropertyManager + * + * @deprecated Temporary properties should not have a name. * * Creates a new property whose lifetime is limited to the current scope. * @@ -628,30 +666,69 @@ class PropertyManager { */ template PropertyManager::type> -makeTemporaryProperty(PolyConnectivity &mesh, const char *propname = "") { +OM_DEPRECATED("Named temporary properties are deprecated. Either create a temporary without name or a non-temporary with name") +makeTemporaryProperty(PolyConnectivity &mesh, const char *propname) { return PropertyManager::type>(mesh, propname, false); } -///// shortcut or makeTemporaryrProperty -//template -//PropertyManager::type, MeshT> -//makeTemporaryVertexProperty(MeshT &mesh, const char *propname) { return makeTemporaryProperty(mesh, propname); } +/** @relates PropertyManager + * + * Creates a new property whose lifetime is limited to the current scope. + * + * Used for temporary properties. Shadows any existing properties of + * matching name and type. + * + * Example: + * @code + * PolyMesh m; + * { + * auto is_quad = makeTemporaryProperty(m); + * for (auto& fh : m.faces()) { + * is_quad[fh] = (m.valence(fh) == 4); + * } + * // The property is automatically removed from the mesh at the end of the scope. + * } + * @endcode + * + * @param mesh The mesh on which the property is created + * @tparam ElementT Element type of the created property, e.g. VertexHandle, HalfedgeHandle, etc. + * @tparam T Value type of the created property, e.g., \p double, \p int, etc. + * @returns A PropertyManager handling the lifecycle of the property + */ +template +PropertyManager::type> +makeTemporaryProperty(PolyConnectivity &mesh) { + return PropertyManager::type>(mesh); +} -///// shortcut or makeTemporaryrProperty -//template -//PropertyManager::type, MeshT> -//makeTemporaryHalfedgeProperty(MeshT &mesh, const char *propname) { return makeTemporaryProperty(mesh, propname); } - -///// shortcut or makeTemporaryrProperty -//template -//PropertyManager::type, MeshT> -//makeTemporaryEdgeProperty(MeshT &mesh, const char *propname) { return makeTemporaryProperty(mesh, propname); } - -///// shortcut or makeTemporaryrProperty -//template -//PropertyManager::type, MeshT> -//makeTemporaryFaceProperty(MeshT &mesh, const char *propname) { return makeTemporaryProperty(mesh, propname); } +/** @relates PropertyManager + * + * Tests whether a property with the given element type, value type, and name is + * present on the given mesh. + * + * * Example: + * @code + * PolyMesh m; + * if (hasProperty(m, "is_quad")) { + * // We now know the property exists: getProperty won't throw. + * auto is_quad = getProperty(m, "is_quad"); + * // Use is_quad here. + * } + * @endcode + * + * @param mesh The mesh in question + * @param propname The property name of the expected property + * @tparam ElementT Element type of the expected property, e.g. VertexHandle, HalfedgeHandle, etc. + * @tparam T Value type of the expected property, e.g., \p double, \p int, etc. + * @tparam MeshT Type of the mesh. Can often be inferred from \p mesh + */ +template +bool +hasProperty(const PolyConnectivity &mesh, const char *propname) { + typename HandleToPropHandle::type ph; + return mesh.get_property_handle(ph, propname); +} /** @relates PropertyManager * @@ -683,7 +760,13 @@ makeTemporaryProperty(PolyConnectivity &mesh, const char *propname = "") { template PropertyManager::type> getProperty(PolyConnectivity &mesh, const char *propname) { - return PropertyManager::type>(mesh, propname, true); + if (!hasProperty(mesh, propname)) + { + std::ostringstream oss; + oss << "Requested property handle \"" << propname << "\" does not exist."; + throw std::runtime_error(oss.str()); + } + return PropertyManager::type>(mesh, propname); } /** @relates PropertyManager @@ -721,34 +804,6 @@ getOrMakeProperty(PolyConnectivity &mesh, const char *propname) { return PropertyManager::type>::createIfNotExists(mesh, propname); } -/** @relates PropertyManager - * - * Tests whether a property with the given element type, value type, and name is - * present on the given mesh. - * - * * Example: - * @code - * PolyMesh m; - * if (hasProperty(m, "is_quad")) { - * // We now know the property exists: getProperty won't throw. - * auto is_quad = getProperty(m, "is_quad"); - * // Use is_quad here. - * } - * @endcode - * - * @param mesh The mesh in question - * @param propname The property name of the expected property - * @tparam ElementT Element type of the expected property, e.g. VertexHandle, HalfedgeHandle, etc. - * @tparam T Value type of the expected property, e.g., \p double, \p int, etc. - * @tparam MeshT Type of the mesh. Can often be inferred from \p mesh - */ -template -bool -hasProperty(const PolyConnectivity &mesh, const char *propname) { - typename HandleToPropHandle::type ph; - return mesh.get_property_handle(ph, propname); -} - /** @relates PropertyManager * @deprecated Use makeTemporaryProperty() instead. * @@ -853,6 +908,8 @@ getPointsProperty(MeshT &mesh) { return PropertyManager>(mesh, mesh.points_property_handle()); } +template +using Prop = PropertyManager::template type>; template using VProp = PropertyManager>; @@ -866,6 +923,9 @@ using EProp = PropertyManager>; template using FProp = PropertyManager>; +template +using MProp = PropertyManager>; + } /* namespace OpenMesh */ #endif /* PROPERTYMANAGER_HH_ */ diff --git a/src/Unittests/unittests_propertymanager.cc b/src/Unittests/unittests_propertymanager.cc index e5046194..8263fcd5 100644 --- a/src/Unittests/unittests_propertymanager.cc +++ b/src/Unittests/unittests_propertymanager.cc @@ -130,55 +130,6 @@ TEST_F(OpenMeshPropertyManager, set_range_bool) { } } -/* - * ==================================================================== - * Factory Functions - * ==================================================================== - */ - -/* - * Temporary property - */ -TEST_F(OpenMeshPropertyManager, cpp11_temp_property) { - using handle_type = OpenMesh::VPropHandleT; - const auto prop_name = "pm_v_test_property"; - ASSERT_FALSE((OpenMesh::hasProperty(mesh_, prop_name))); - - { - auto vprop = OpenMesh::makeTemporaryProperty(mesh_, prop_name); - static_cast(vprop); // Unused variable - ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); - } - - ASSERT_FALSE((OpenMesh::hasProperty(mesh_, prop_name))); -} - -/* - * Two temporary properties on a mesh using the same name and type. The second - * (inner) one shadows the first (outer) one instead of aliasing. - */ -TEST_F(OpenMeshPropertyManager, cpp11_temp_property_shadowing) { - auto vh = mesh_.add_vertex({0,0,0}); // Dummy vertex to attach properties to - - const auto prop_name = "pm_v_test_property"; - - auto outer_prop = OpenMesh::makeTemporaryProperty(mesh_, prop_name); - outer_prop[vh] = 100; - ASSERT_EQ(100, outer_prop[vh]); - - { - // inner_prop uses same type and name as outer_prop - auto inner_prop = OpenMesh::makeTemporaryProperty(mesh_, prop_name); - inner_prop[vh] = 200; - ASSERT_EQ(200, inner_prop[vh]); - // End of scope: inner_prop is removed from mesh_ - } - - // Ensure outer_prop still exists and its data has not been overwritten by inner_prop - ASSERT_TRUE((OpenMesh::hasProperty(mesh_, prop_name))); - ASSERT_EQ(100, outer_prop[vh]); -} - /* * In sequence: * - add a persistent property to a mesh @@ -315,8 +266,8 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { // unnamed to unnamed { - auto prop1 = OpenMesh::VProp(3, mesh_); - auto prop2 = OpenMesh::VProp(0, mesh_); + auto prop1 = OpenMesh::VProp(mesh_, 3); + auto prop2 = OpenMesh::VProp(mesh_, 0); EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 3) << "Property not initialized correctly"; EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; @@ -341,7 +292,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { // unnamed to named { auto prop1 = OpenMesh::VProp(mesh_); - auto prop2 = OpenMesh::VProp(0, mesh_, "ids"); + auto prop2 = OpenMesh::VProp(mesh_, "ids", 0); EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; for (auto vh : mesh_.vertices()) @@ -579,8 +530,8 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { // unnamed to unnamed { - auto prop1 = OpenMesh::VProp(3, mesh_); - auto prop2 = OpenMesh::VProp(0, copy); + auto prop1 = OpenMesh::VProp(mesh_, 3); + auto prop2 = OpenMesh::VProp(copy, 0); EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 3) << "Property not initialized correctly"; EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; @@ -600,13 +551,13 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 0) << "Property not copied correctly"; EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; - EXPECT_NO_FATAL_FAILURE(prop2[OpenMesh::VertexHandle(copy.n_vertices()-1)]) << "Property not correctly resized"; + EXPECT_NO_FATAL_FAILURE(prop2[OpenMesh::VertexHandle(static_cast(copy.n_vertices())-1)]) << "Property not correctly resized"; } // unnamed to named { auto prop1 = OpenMesh::VProp(mesh_); - auto prop2 = OpenMesh::VProp(0, copy, "ids"); + auto prop2 = OpenMesh::VProp(copy, "ids", 0); EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; for (auto vh : mesh_.vertices()) @@ -731,7 +682,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; - EXPECT_NO_FATAL_FAILURE(prop2[OpenMesh::VertexHandle(copy.n_vertices()-1)]) << "Property not correctly resized"; + EXPECT_NO_FATAL_FAILURE(prop2[OpenMesh::VertexHandle(static_cast(copy.n_vertices())-1)]) << "Property not correctly resized"; } // unnamed to named From fb91dead5bfa3357ab8e59600b308d2fec7ed9d2 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 09:40:48 +0100 Subject: [PATCH 40/60] move propertymanager initial_value back to front to fix bool properties --- src/OpenMesh/Core/Utils/PropertyManager.hh | 12 +++++------ src/Unittests/unittests_propertymanager.cc | 25 ++++++++++++++++------ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index cc462fd5..1ec4a6af 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -140,7 +140,7 @@ class PropertyManager { * @see PropertyManager::getOrMakeProperty, PropertyManager::getProperty, * PropertyManager::makeTemporaryProperty */ - OM_DEPRECATED("Use the constructor without parameter 'existing' instead. Check for existance with hasProperty") + OM_DEPRECATED("Use the constructor without parameter 'existing' instead. Check for existance with hasProperty") // As long as this overload exists, initial value must be first parameter due to ambiguity for properties of type bool PropertyManager(PolyConnectivity& mesh, const char *propname, bool existing) : mesh_(mesh), retain_(existing), name_(propname) { if (existing) { if (!mesh_.get_property_handle(prop_, propname)) { @@ -171,13 +171,13 @@ class PropertyManager { * Constructor. * * Asks for a property with name propname and creates one if none exists. Lifetime is not managed. - * If the property is created it is initialized with \p initial_value * + * @param initial_value If the proeprty is newly created, it will be initialized with intial_value. + * If the property already existed, nothing is changes. * @param mesh The mesh on which to create the property. - * @param initial_value * @param propname The name of the property. */ - PropertyManager(PolyConnectivity& mesh, const char *propname, const Value& intial_value) : mesh_(mesh), retain_(true), name_(propname) { + PropertyManager(const Value& intial_value, PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { if (!mesh_.get_property_handle(prop_, propname)) { mesh_.add_property(prop_, propname); set_range(mesh_.all_elements(), intial_value); @@ -199,11 +199,11 @@ class PropertyManager { * Constructor. * * Create an anonymous property. Lifetime is managed. - * If the property is created it is initialized with \p initial_value * + * @param initial_value The property will be initialized with intial_value. * @param mesh The mesh on which to create the property. */ - PropertyManager(PolyConnectivity& mesh, const Value& intial_value) : mesh_(mesh), retain_(false), name_("") { + PropertyManager(const Value& intial_value, PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { mesh_.add_property(prop_, name_); set_range(mesh_.all_elements(), intial_value); } diff --git a/src/Unittests/unittests_propertymanager.cc b/src/Unittests/unittests_propertymanager.cc index 8263fcd5..ea7e82f7 100644 --- a/src/Unittests/unittests_propertymanager.cc +++ b/src/Unittests/unittests_propertymanager.cc @@ -266,8 +266,8 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { // unnamed to unnamed { - auto prop1 = OpenMesh::VProp(mesh_, 3); - auto prop2 = OpenMesh::VProp(mesh_, 0); + auto prop1 = OpenMesh::VProp(3, mesh_); + auto prop2 = OpenMesh::VProp(0, mesh_); EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 3) << "Property not initialized correctly"; EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; @@ -292,7 +292,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { // unnamed to named { auto prop1 = OpenMesh::VProp(mesh_); - auto prop2 = OpenMesh::VProp(mesh_, "ids", 0); + auto prop2 = OpenMesh::VProp(0, mesh_, "ids"); EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; for (auto vh : mesh_.vertices()) @@ -385,6 +385,16 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { auto prop3 = OpenMesh::VProp(mesh_, "ids5"); EXPECT_EQ(prop3[OpenMesh::VertexHandle(0)], 42) << "Property not copied correctly"; } + + { + auto prop1 = OpenMesh::MProp(mesh_); + *prop1 = 43; + auto prop2 = prop1; + + prop2 = prop1; + + prop2 = std::move(prop1); + } } @@ -530,8 +540,8 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { // unnamed to unnamed { - auto prop1 = OpenMesh::VProp(mesh_, 3); - auto prop2 = OpenMesh::VProp(copy, 0); + auto prop1 = OpenMesh::VProp(3, mesh_); + auto prop2 = OpenMesh::VProp(0, copy); EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], 3) << "Property not initialized correctly"; EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; @@ -557,7 +567,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { // unnamed to named { auto prop1 = OpenMesh::VProp(mesh_); - auto prop2 = OpenMesh::VProp(copy, "ids", 0); + auto prop2 = OpenMesh::VProp(0, copy, "ids"); EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], 0) << "Property not initialized correctly"; for (auto vh : mesh_.vertices()) @@ -762,6 +772,9 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { auto prop1 = OpenMesh::VProp(mesh_, "ids5"); auto prop2 = OpenMesh::VProp(copy, "ids5"); + auto prop6 = OpenMesh::Prop(mesh_); + prop6 = prop1; + for (auto vh : mesh_.vertices()) prop1[vh] = vh.idx()*2-13; From b813fffe8bd69c7150b235b396a9f3138cf60956 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 09:40:57 +0100 Subject: [PATCH 41/60] remove pre c++11 code --- src/OpenMesh/Core/Utils/PropertyManager.hh | 78 ---------------------- 1 file changed, 78 deletions(-) diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index 1ec4a6af..dbfba226 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -288,11 +288,6 @@ class PropertyManager { MeshT& getMesh() const { return dynamic_cast(mesh_); } -#if (defined(_MSC_VER) && (_MSC_VER >= 1800)) || __cplusplus > 199711L || defined(__GXX_EXPERIMENTAL_CXX0X__) - /// Only for pre C++11 compatibility. - - typedef PropertyManager Proxy; - /** * Move constructor. Transfers ownership (delete responsibility). */ @@ -393,79 +388,6 @@ class PropertyManager { return std::move(*this); } -#else - class Proxy { - private: - Proxy(PolyConnectivity *mesh_, PROPTYPE prop_, bool retain_, const std::string &name_) : - mesh_(mesh_), prop_(prop_), retain_(retain_), name_(name_) {} - PolyConnectivity *mesh_; - PROPTYPE prop_; - bool retain_; - std::string name_; - - friend class PropertyManager; - }; - - operator Proxy() { - Proxy p(mesh_, prop_, retain_, name_); - mesh_ = 0; - retain_ = true; - return p; - } - - Proxy move() { - return (Proxy)*this; - } - - PropertyManager(Proxy p) : mesh_(p.mesh_), prop_(p.prop_), retain_(p.retain_), name_(p.name_) {} - - PropertyManager &operator=(Proxy p) { - PropertyManager(p).swap(*this); - return *this; - } - - /** - * Create a property manager for the supplied property and mesh. - * If the property doesn't exist, it is created. In any case, - * lifecycle management is disabled. - * - * @see makePropertyManagerFromExistingOrNew - */ - static Proxy createIfNotExists(PolyConnectivity &mesh, const char *propname) { - PROPTYPE dummy_prop; - PropertyManager pm(mesh, propname, mesh.get_property_handle(dummy_prop, propname)); - pm.retain(); - return (Proxy)pm; - } - - /** - * Like createIfNotExists() with two parameters except, if the property - * doesn't exist, it is initialized with the supplied value over - * the supplied range after creation. If the property already exists, - * this method has the exact same effect as the two parameter version. - * Lifecycle management is disabled in any case. - * - * @see makePropertyManagerFromExistingOrNew - */ - template - static Proxy createIfNotExists(PolyConnectivity &mesh, const char *propname, - const ITERATOR_TYPE &begin, const ITERATOR_TYPE &end, - const PROP_VALUE &init_value) { - const bool exists = propertyExists(mesh, propname); - PropertyManager pm(mesh, propname, exists); - pm.retain(); - if (!exists) - pm.set_range(begin, end, init_value); - return (Proxy)pm; - } - - Proxy duplicate(const char *clone_name) { - PropertyManager pm(*mesh_, clone_name, false); - pm.mesh_.property(pm.prop_) = mesh_.property(prop_); - return (Proxy)pm; - } -#endif - /** * Access the value of the encapsulated mesh property. * From 6e81f6c2db50936d2472249a5fc84403f02cf37d Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 10:20:47 +0100 Subject: [PATCH 42/60] update documentation of new property manager --- Doc/Tutorial/03-properties/smooth.cc | 6 +++--- Doc/changelog.docu | 2 ++ Doc/tutorial_03.docu | 27 +++++++++++++-------------- Doc/tutorial_09.docu | 6 ++++-- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/Doc/Tutorial/03-properties/smooth.cc b/Doc/Tutorial/03-properties/smooth.cc index 37833017..41d7ab60 100644 --- a/Doc/Tutorial/03-properties/smooth.cc +++ b/Doc/Tutorial/03-properties/smooth.cc @@ -1,11 +1,11 @@ #include -#include +#include #include #include #include -using MyMesh = OpenMesh::TriMesh_ArrayKernelT<>; +using MyMesh = OpenMesh::TriMesh; int main(int argc, char** argv) { @@ -27,7 +27,7 @@ int main(int argc, char** argv) { // Add a vertex property storing the computed centers of gravity - auto cog = OpenMesh::makeTemporaryProperty(mesh); + auto cog = OpenMesh::VProp(mesh); // Smooth the mesh several times for (int i = 0; i < iterations; ++i) { diff --git a/Doc/changelog.docu b/Doc/changelog.docu index ff45eb22..716ce284 100644 --- a/Doc/changelog.docu +++ b/Doc/changelog.docu @@ -13,6 +13,7 @@
  • Property System: Get rid of the OM_FORCE_STATIC_CAST defines. We use the type ids to check if the cast is valid or not. This will add more type safety.
  • Default Traits: Added DefaultTraitsDouble as a version of the default traits that uses double precision for positions and normals as well as float for colors.
  • Default Mesh Types: Added typdefs for a Triangle Mesh and a PolyMesh which use DefaultTraitsDouble and can be used as default mesh type be the user.
  • +
  • Template Programming Convenience: Added n_elements which returns the number of elements corresponding to the handle type given as template argument. Also added elements and all_elements methods returning ranges of the elements corresponding to the handle type given as template argument. @@ -27,6 +28,7 @@
    • Change PropertyManager::operator* to access the property value for mesh properties
    • PropertyManager: add hasProperty function
    • +
    • PropertyManager rework: The behavior of the PropertyManager has been changed, hoepfully making it more usable. See tutoial.
    IO diff --git a/Doc/tutorial_03.docu b/Doc/tutorial_03.docu index ba76515c..01f8c6e3 100644 --- a/Doc/tutorial_03.docu +++ b/Doc/tutorial_03.docu @@ -11,34 +11,33 @@ let %OpenMesh manage the data. It would be even more helpful if we could attach such properties dynamically to the mesh. -Custom properties can be conveniently created and attached to meshes with the following functions: -- makeTemporaryProperty() creates a property that is temporary to the current scope. -- getOrMakeProperty() is used for creating and accessing permanent named properties on a mesh. -- getProperty() is used for accessing an existing permanent named property on a mesh. +Custom properties can be conveniently created and attached to meshes by creating an object of type OpenMesh::PropertyManager. A PropertyManager manages the lifetime of the property and provides read / write access to its values. -All three functions take two template arguments: -- First, the type of the mesh element that the property is attached to (i.e. OpenMesh::VertexHandle, OpenMesh::HalfedgeHandle, OpenMesh::EdgeHandle, or OpenMesh::FaceHandle). Mesh properties (i.e. singleton properties that are attached to an entire mesh instead of individual elements) are accessed by passing \c void instead of a handle type. -- Second, the type of the property value that is attached to each element (e.g., \p int, \p double, etc.). +You can use the typedefs VProp, HProp, EProp, FProp, and MProp in order to create a PropertyManager attached to vertices, halfedge, edges, faces and the mesh respectively. Each of these takes as template argument the type of the property value that is attached to each element (e.g., \p int, \p double, etc.). + +We differentiate between two kinds of properties. Named and temporary properties. Temporary properties are created by just providing the constructor with a mesh on which the property should be created. These properties will be removed as soon as the PropertyManager goes out of scope. If in addition to the mesh a property name is provided, a named property will be created which will stay alive even after the PropertyManager goes out of scope. If a PropertyManager is given a name of an already existing property, it will provide read and write access to the same property. + +Finally, an optional first parameter can be given containing a value that will be used to initialize the property for all elements if the property is freshly created (i.e. always for temporary properties, and only the first time a specific name is used). -All three functions return a handle object (of type OpenMesh::PropertyManager) that manages the lifetime of the property and provides read / write access to its values. Here are a few examples of how to create and access mesh properties: \code // Add a temporary mesh property that stores a double value for every vertex -auto temperature = OpenMesh::getOrMakeProperty(mesh, "temperature"); +auto temperature = OpenMesh::VProp(mesh); OpenMesh::VertexHandle vh = ...; temperature[vh] = 1.0; // The temperature property will be removed from the mesh when the handle reaches the end of the scope. -// Obtain an existing mesh property that stores a 2D vector for every halfedge -// (Beware: the next line might throw if the expected property doesn't exist.) -auto uv = OpenMesh::getProperty(mesh, "uv"); +// Obtain an existing property that stores a 2D vector for every halfedge +// (or create that property if it does not exist already) and initilize it with the Vector(1,1)) +auto uv = OpenMesh::HProp(mesh, "uv", OpenMesh::Vec2d(1,1)); OpenMesh::VertexHandle heh = ...; std::cout << temperature[heh][0] << " " << temperature[heh][1] << std::endl; -// Add a permanent mesh property containing a description string -auto desc = OpenMesh::getOrMakeProperty(mesh, "desc"); +// Obtain an existing mesh property (or create that property if it does not exist already) +// containing a description string +auto desc = OpenMesh::MProp(mesh, "desc"); *desc = "This is a very nice mesh."; \endcode diff --git a/Doc/tutorial_09.docu b/Doc/tutorial_09.docu index 3e0a6d8a..1b2d4f09 100644 --- a/Doc/tutorial_09.docu +++ b/Doc/tutorial_09.docu @@ -1,6 +1,8 @@ -/** \page tutorial_09 Using custom properties +/** \page tutorial_09 Using custom properties (old style) -This small code example shows how to attach andaccess additional properties on a mesh. +This small code example shows how to attach and access additional properties on a mesh. + +Note that this is an old style of using properties. Nowadays you should use the OpenMesh::PropertyManager instead. When you want to add an additional properties you have to attach it to a primitive of the mesh. You can attach to verticies, halfedges, edges, faces or to the mesh itself. Use the From 794b49976b57f4c26cd66c4c6aa018ae48998e98 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 10:21:09 +0100 Subject: [PATCH 43/60] fix swap of property managers --- src/OpenMesh/Core/Utils/PropertyManager.hh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index dbfba226..a48bc8b8 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -252,10 +252,8 @@ class PropertyManager { } void swap(PropertyManager &rhs) { - std::swap(mesh_, rhs.mesh_); - std::swap(prop_, rhs.prop_); - std::swap(retain_, rhs.retain_); - std::swap(name_, rhs.name_); + // swap the data stored in the properties + Storage::swap(rhs, *this); } static bool propertyExists(PolyConnectivity &mesh, const char *propname) { @@ -316,7 +314,7 @@ class PropertyManager { } else { - // switch the data stored in the properties + // swap the data stored in the properties Storage::swap(rhs, *this); // remove the property from rhs rhs.mesh_.remove_property(rhs.prop_); From c6daa6bcb2a7f798268040d17038f915cbb7813d Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 13:29:08 +0100 Subject: [PATCH 44/60] move inline implementation of polyconnectivity into its own file --- src/OpenMesh/Core/Mesh/PolyConnectivity.hh | 731 +--------------- .../Core/Mesh/PolyConnectivity_inline_impl.hh | 777 ++++++++++++++++++ 2 files changed, 778 insertions(+), 730 deletions(-) create mode 100644 src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh index c84392b7..544ee6c6 100644 --- a/src/OpenMesh/Core/Mesh/PolyConnectivity.hh +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity.hh @@ -1571,735 +1571,6 @@ struct PolyConnectivity::ElementRange }//namespace OpenMesh - -#include -#include -#include - -namespace OpenMesh { - - -inline SmartVertexHandle PolyConnectivity::add_vertex() { return make_smart(new_vertex(), *this); } - -inline SmartHalfedgeHandle PolyConnectivity::next_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(next_halfedge_handle(HalfedgeHandle(_heh)), *this); } -inline SmartHalfedgeHandle PolyConnectivity::prev_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(prev_halfedge_handle(HalfedgeHandle(_heh)), *this); } -inline SmartHalfedgeHandle PolyConnectivity::opposite_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(opposite_halfedge_handle(HalfedgeHandle(_heh)), *this); } -inline SmartHalfedgeHandle PolyConnectivity::ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(ccw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } -inline SmartHalfedgeHandle PolyConnectivity::cw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(cw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } - -inline SmartHalfedgeHandle PolyConnectivity::s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) { return make_smart(ArrayKernel::s_halfedge_handle(EdgeHandle(_eh), _i), _eh.mesh()); } -inline SmartEdgeHandle PolyConnectivity::s_edge_handle(SmartHalfedgeHandle _heh) { return make_smart(ArrayKernel::s_edge_handle(HalfedgeHandle(_heh)), _heh.mesh()); } - -inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const { return make_smart(halfedge_handle(EdgeHandle(_eh), _i), *this); } -inline SmartEdgeHandle PolyConnectivity::edge_handle(SmartHalfedgeHandle _heh) const { return make_smart(edge_handle(HalfedgeHandle(_heh)), *this); } -inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartFaceHandle _fh) const { return make_smart(halfedge_handle(FaceHandle(_fh)), *this); } -inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartVertexHandle _vh) const { return make_smart(halfedge_handle(VertexHandle(_vh)), *this); } - -inline SmartFaceHandle PolyConnectivity::face_handle(SmartHalfedgeHandle _heh) const { return make_smart(face_handle(HalfedgeHandle(_heh)), *this); } - - - -/// Generic class for vertex/halfedge/edge/face ranges. -template -class EntityRange : public SmartRangeT, typename RangeTraitT::ITER_TYPE::SmartHandle> { - public: - typedef typename RangeTraitT::ITER_TYPE iterator; - typedef typename RangeTraitT::ITER_TYPE const_iterator; - - explicit EntityRange(typename RangeTraitT::CONTAINER_TYPE &container) : container_(container) {} - typename RangeTraitT::ITER_TYPE begin() const { return RangeTraitT::begin(container_); } - typename RangeTraitT::ITER_TYPE end() const { return RangeTraitT::end(container_); } - - private: - typename RangeTraitT::CONTAINER_TYPE &container_; -}; - - -/// Generic class for iterator ranges. -template -//class CirculatorRange : public SmartRangeT, decltype (make_smart(std::declval(), std::declval()))>{ -class CirculatorRange : public SmartRangeT, typename SmartHandle::type>{ - public: - typedef typename CirculatorRangeTraitT::ITER_TYPE ITER_TYPE; - typedef typename CirculatorRangeTraitT::CENTER_ENTITY_TYPE CENTER_ENTITY_TYPE; - typedef typename CirculatorRangeTraitT::CONTAINER_TYPE CONTAINER_TYPE; - typedef ITER_TYPE iterator; - typedef ITER_TYPE const_iterator; - - CirculatorRange( - const CONTAINER_TYPE &container, - CENTER_ENTITY_TYPE center) : - container_(container), center_(center) {} - ITER_TYPE begin() const { return CirculatorRangeTraitT::begin(container_, center_); } - ITER_TYPE end() const { return CirculatorRangeTraitT::end(container_, center_); } - - private: - const CONTAINER_TYPE &container_; - CENTER_ENTITY_TYPE center_; -}; - -inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::vertices() const { return ConstVertexRangeSkipping(*this); } -inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_vertices() const { return ConstVertexRange(*this); } -inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::halfedges() const { return ConstHalfedgeRangeSkipping(*this); } -inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_halfedges() const { return ConstHalfedgeRange(*this); } -inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::edges() const { return ConstEdgeRangeSkipping(*this); } -inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_edges() const { return ConstEdgeRange(*this); } -inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::faces() const { return ConstFaceRangeSkipping(*this); } -inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_faces() const { return ConstFaceRange(*this); } - -template <> inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::elements() const { return vertices(); } -template <> inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_elements() const { return all_vertices(); } -template <> inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::elements() const { return halfedges(); } -template <> inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_elements() const { return all_halfedges(); } -template <> inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::elements() const { return edges(); } -template <> inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_elements() const { return all_edges(); } -template <> inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::elements() const { return faces(); } -template <> inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_elements() const { return all_faces(); } - -inline PolyConnectivity::ConstVertexVertexRange PolyConnectivity::vv_range(VertexHandle _vh) const { - return ConstVertexVertexRange(*this, _vh); -} - -inline PolyConnectivity::ConstVertexIHalfedgeRange PolyConnectivity::vih_range(VertexHandle _vh) const { - return ConstVertexIHalfedgeRange(*this, _vh); -} - -inline PolyConnectivity::ConstVertexOHalfedgeRange PolyConnectivity::voh_range(VertexHandle _vh) const { - return ConstVertexOHalfedgeRange(*this, _vh); -} - -inline PolyConnectivity::ConstVertexEdgeRange PolyConnectivity::ve_range(VertexHandle _vh) const { - return ConstVertexEdgeRange(*this, _vh); -} - -inline PolyConnectivity::ConstVertexFaceRange PolyConnectivity::vf_range(VertexHandle _vh) const { - return ConstVertexFaceRange(*this, _vh); -} - -inline PolyConnectivity::ConstFaceVertexRange PolyConnectivity::fv_range(FaceHandle _fh) const { - return ConstFaceVertexRange(*this, _fh); -} - -inline PolyConnectivity::ConstFaceHalfedgeRange PolyConnectivity::fh_range(FaceHandle _fh) const { - return ConstFaceHalfedgeRange(*this, _fh); -} - -inline PolyConnectivity::ConstFaceEdgeRange PolyConnectivity::fe_range(FaceHandle _fh) const { - return ConstFaceEdgeRange(*this, _fh); -} - -inline PolyConnectivity::ConstFaceFaceRange PolyConnectivity::ff_range(FaceHandle _fh) const { - return ConstFaceFaceRange(*this, _fh); -} - - - -inline PolyConnectivity::VertexIter PolyConnectivity::vertices_begin() -{ return VertexIter(*this, VertexHandle(0)); } - -inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_begin() const -{ return ConstVertexIter(*this, VertexHandle(0)); } - -inline PolyConnectivity::VertexIter PolyConnectivity::vertices_end() -{ return VertexIter(*this, VertexHandle( int(n_vertices() ) )); } - -inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_end() const -{ return ConstVertexIter(*this, VertexHandle( int(n_vertices()) )); } - -inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_begin() -{ return HalfedgeIter(*this, HalfedgeHandle(0)); } - -inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_begin() const -{ return ConstHalfedgeIter(*this, HalfedgeHandle(0)); } - -inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_end() -{ return HalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); } - -inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_end() const -{ return ConstHalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); } - -inline PolyConnectivity::EdgeIter PolyConnectivity::edges_begin() -{ return EdgeIter(*this, EdgeHandle(0)); } - -inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_begin() const -{ return ConstEdgeIter(*this, EdgeHandle(0)); } - -inline PolyConnectivity::EdgeIter PolyConnectivity::edges_end() -{ return EdgeIter(*this, EdgeHandle(int(n_edges()))); } - -inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_end() const -{ return ConstEdgeIter(*this, EdgeHandle(int(n_edges()))); } - -inline PolyConnectivity::FaceIter PolyConnectivity::faces_begin() -{ return FaceIter(*this, FaceHandle(0)); } - -inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_begin() const -{ return ConstFaceIter(*this, FaceHandle(0)); } - -inline PolyConnectivity::FaceIter PolyConnectivity::faces_end() -{ return FaceIter(*this, FaceHandle(int(n_faces()))); } - - -inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const -{ return ConstFaceIter(*this, FaceHandle(int(n_faces()))); } - -inline PolyConnectivity::VertexIter PolyConnectivity::vertices_sbegin() -{ return VertexIter(*this, VertexHandle(0), true); } - -inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_sbegin() const -{ return ConstVertexIter(*this, VertexHandle(0), true); } - -inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_sbegin() -{ return HalfedgeIter(*this, HalfedgeHandle(0), true); } - -inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_sbegin() const -{ return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); } - -inline PolyConnectivity::EdgeIter PolyConnectivity::edges_sbegin() -{ return EdgeIter(*this, EdgeHandle(0), true); } - -inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_sbegin() const -{ return ConstEdgeIter(*this, EdgeHandle(0), true); } - -inline PolyConnectivity::FaceIter PolyConnectivity::faces_sbegin() -{ return FaceIter(*this, FaceHandle(0), true); } - -inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_sbegin() const -{ return ConstFaceIter(*this, FaceHandle(0), true); } - -inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_iter(ArrayKernel::VertexHandle _vh) -{ return VertexVertexIter(*this, _vh); } - -inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwiter(ArrayKernel::VertexHandle _vh) -{ return VertexVertexCWIter(*this, _vh); } - -inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwiter(ArrayKernel::VertexHandle _vh) -{ return VertexVertexCCWIter(*this, _vh); } - -inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_iter(ArrayKernel::VertexHandle _vh) -{ return VertexIHalfedgeIter(*this, _vh); } - -inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwiter(ArrayKernel::VertexHandle _vh) -{ return VertexIHalfedgeCWIter(*this, _vh); } - -inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwiter(ArrayKernel::VertexHandle _vh) -{ return VertexIHalfedgeCCWIter(*this, _vh); } - -inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_iter(ArrayKernel::VertexHandle _vh) -{ return VertexOHalfedgeIter(*this, _vh); } - -inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwiter(ArrayKernel::VertexHandle _vh) -{ return VertexOHalfedgeCWIter(*this, _vh); } - -inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwiter(ArrayKernel::VertexHandle _vh) -{ return VertexOHalfedgeCCWIter(*this, _vh); } - -inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_iter(ArrayKernel::VertexHandle _vh) -{ return VertexEdgeIter(*this, _vh); } - -inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwiter(ArrayKernel::VertexHandle _vh) -{ return VertexEdgeCWIter(*this, _vh); } - -inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwiter(ArrayKernel::VertexHandle _vh) -{ return VertexEdgeCCWIter(*this, _vh); } - -inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_iter(ArrayKernel::VertexHandle _vh) -{ return VertexFaceIter(*this, _vh); } - -inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwiter(ArrayKernel::VertexHandle _vh) -{ return VertexFaceCWIter(*this, _vh); } - -inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwiter(ArrayKernel::VertexHandle _vh) -{ return VertexFaceCCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_iter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexVertexIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexVertexCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexVertexCCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_iter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexIHalfedgeIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexIHalfedgeCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexIHalfedgeCCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_iter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexOHalfedgeIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexOHalfedgeCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexOHalfedgeCCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_iter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexEdgeIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexEdgeCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexEdgeCCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_iter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexFaceIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexFaceCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwiter(ArrayKernel::VertexHandle _vh) const -{ return ConstVertexFaceCCWIter(*this, _vh); } - -inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_iter(ArrayKernel::FaceHandle _fh) -{ return FaceVertexIter(*this, _fh); } - -inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwiter(ArrayKernel::FaceHandle _fh) -{ return FaceVertexCWIter(*this, _fh); } - -inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwiter(ArrayKernel::FaceHandle _fh) -{ return FaceVertexCCWIter(*this, _fh); } - -inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_iter(ArrayKernel::FaceHandle _fh) -{ return FaceHalfedgeIter(*this, _fh); } - -inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwiter(ArrayKernel::FaceHandle _fh) -{ return FaceHalfedgeCWIter(*this, _fh); } - -inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwiter(ArrayKernel::FaceHandle _fh) -{ return FaceHalfedgeCCWIter(*this, _fh); } - -inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_iter(ArrayKernel::FaceHandle _fh) -{ return FaceEdgeIter(*this, _fh); } - -inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwiter(ArrayKernel::FaceHandle _fh) -{ return FaceEdgeCWIter(*this, _fh); } - -inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwiter(ArrayKernel::FaceHandle _fh) -{ return FaceEdgeCCWIter(*this, _fh); } - -inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_iter(ArrayKernel::FaceHandle _fh) -{ return FaceFaceIter(*this, _fh); } - -inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwiter(ArrayKernel::FaceHandle _fh) -{ return FaceFaceCWIter(*this, _fh); } - -inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwiter(ArrayKernel::FaceHandle _fh) -{ return FaceFaceCCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_iter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceVertexIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwiter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceVertexCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwiter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceVertexCCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_iter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceHalfedgeIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwiter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceHalfedgeCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwiter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceHalfedgeCCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_iter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceEdgeIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwiter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceEdgeCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwiter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceEdgeCCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_iter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceFaceIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwiter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceFaceCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwiter(ArrayKernel::FaceHandle _fh) const -{ return ConstFaceFaceCCWIter(*this, _fh); } - - -inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_begin(VertexHandle _vh) -{ return VertexVertexIter(*this, _vh); } - -inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwbegin(VertexHandle _vh) -{ return VertexVertexCWIter(*this, _vh); } - -inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwbegin(VertexHandle _vh) -{ return VertexVertexCCWIter(*this, _vh); } - -inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_begin(VertexHandle _vh) -{ return VertexIHalfedgeIter(*this, _vh); } - -inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwbegin(VertexHandle _vh) -{ return VertexIHalfedgeCWIter(*this, _vh); } - -inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwbegin(VertexHandle _vh) -{ return VertexIHalfedgeCCWIter(*this, _vh); } - -inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_begin(VertexHandle _vh) -{ return VertexOHalfedgeIter(*this, _vh); } - -inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwbegin(VertexHandle _vh) -{ return VertexOHalfedgeCWIter(*this, _vh); } - -inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwbegin(VertexHandle _vh) -{ return VertexOHalfedgeCCWIter(*this, _vh); } - -inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_begin(VertexHandle _vh) -{ return VertexEdgeIter(*this, _vh); } - -inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwbegin(VertexHandle _vh) -{ return VertexEdgeCWIter(*this, _vh); } - -inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwbegin(VertexHandle _vh) -{ return VertexEdgeCCWIter(*this, _vh); } - -inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_begin(VertexHandle _vh) -{ return VertexFaceIter(*this, _vh); } - -inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwbegin(VertexHandle _vh) -{ return VertexFaceCWIter(*this, _vh); } - -inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwbegin(VertexHandle _vh) -{ return VertexFaceCCWIter(*this, _vh); } - - -inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_begin(VertexHandle _vh) const -{ return ConstVertexVertexIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwbegin(VertexHandle _vh) const -{ return ConstVertexVertexCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwbegin(VertexHandle _vh) const -{ return ConstVertexVertexCCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_begin(VertexHandle _vh) const -{ return ConstVertexIHalfedgeIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwbegin(VertexHandle _vh) const -{ return ConstVertexIHalfedgeCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwbegin(VertexHandle _vh) const -{ return ConstVertexIHalfedgeCCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_begin(VertexHandle _vh) const -{ return ConstVertexOHalfedgeIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwbegin(VertexHandle _vh) const -{ return ConstVertexOHalfedgeCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwbegin(VertexHandle _vh) const -{ return ConstVertexOHalfedgeCCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_begin(VertexHandle _vh) const -{ return ConstVertexEdgeIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwbegin(VertexHandle _vh) const -{ return ConstVertexEdgeCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwbegin(VertexHandle _vh) const -{ return ConstVertexEdgeCCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_begin(VertexHandle _vh) const -{ return ConstVertexFaceIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwbegin(VertexHandle _vh) const -{ return ConstVertexFaceCWIter(*this, _vh); } - -inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwbegin(VertexHandle _vh) const -{ return ConstVertexFaceCCWIter(*this, _vh); } - - -inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_begin(FaceHandle _fh) -{ return FaceVertexIter(*this, _fh); } - -inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwbegin(FaceHandle _fh) -{ return FaceVertexCWIter(*this, _fh); } - -inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwbegin(FaceHandle _fh) -{ return FaceVertexCCWIter(*this, _fh); } - -inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_begin(FaceHandle _fh) -{ return FaceHalfedgeIter(*this, _fh); } - -inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwbegin(FaceHandle _fh) -{ return FaceHalfedgeCWIter(*this, _fh); } - -inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwbegin(FaceHandle _fh) -{ return FaceHalfedgeCCWIter(*this, _fh); } - -inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_begin(FaceHandle _fh) -{ return FaceEdgeIter(*this, _fh); } - -inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwbegin(FaceHandle _fh) -{ return FaceEdgeCWIter(*this, _fh); } - -inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwbegin(FaceHandle _fh) -{ return FaceEdgeCCWIter(*this, _fh); } - -inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_begin(FaceHandle _fh) -{ return FaceFaceIter(*this, _fh); } - -inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwbegin(FaceHandle _fh) -{ return FaceFaceCWIter(*this, _fh); } - -inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwbegin(FaceHandle _fh) -{ return FaceFaceCCWIter(*this, _fh); } - -inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_begin(HalfedgeHandle _heh) -{ return HalfedgeLoopIter(*this, _heh); } - -inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwbegin(HalfedgeHandle _heh) -{ return HalfedgeLoopCWIter(*this, _heh); } - -inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwbegin(HalfedgeHandle _heh) -{ return HalfedgeLoopCCWIter(*this, _heh); } - - -inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_begin(FaceHandle _fh) const -{ return ConstFaceVertexIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwbegin(FaceHandle _fh) const -{ return ConstFaceVertexCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwbegin(FaceHandle _fh) const -{ return ConstFaceVertexCCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_begin(FaceHandle _fh) const -{ return ConstFaceHalfedgeIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwbegin(FaceHandle _fh) const -{ return ConstFaceHalfedgeCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwbegin(FaceHandle _fh) const -{ return ConstFaceHalfedgeCCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_begin(FaceHandle _fh) const -{ return ConstFaceEdgeIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwbegin(FaceHandle _fh) const -{ return ConstFaceEdgeCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwbegin(FaceHandle _fh) const -{ return ConstFaceEdgeCCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_begin(FaceHandle _fh) const -{ return ConstFaceFaceIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwbegin(FaceHandle _fh) const -{ return ConstFaceFaceCWIter(*this, _fh); } - -inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwbegin(FaceHandle _fh) const -{ return ConstFaceFaceCCWIter(*this, _fh); } - -inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_begin(HalfedgeHandle _heh) const -{ return ConstHalfedgeLoopIter(*this, _heh); } - -inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwbegin(HalfedgeHandle _heh) const -{ return ConstHalfedgeLoopCWIter(*this, _heh); } - -inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwbegin(HalfedgeHandle _heh) const -{ return ConstHalfedgeLoopCCWIter(*this, _heh); } - -// 'end' circulators - -inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_end(VertexHandle _vh) -{ return VertexVertexIter(*this, _vh, true); } - -inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwend(VertexHandle _vh) -{ return VertexVertexCWIter(*this, _vh, true); } - -inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwend(VertexHandle _vh) -{ return VertexVertexCCWIter(*this, _vh, true); } - -inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_end(VertexHandle _vh) -{ return VertexIHalfedgeIter(*this, _vh, true); } - -inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwend(VertexHandle _vh) -{ return VertexIHalfedgeCWIter(*this, _vh, true); } - -inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwend(VertexHandle _vh) -{ return VertexIHalfedgeCCWIter(*this, _vh, true); } - -inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_end(VertexHandle _vh) -{ return VertexOHalfedgeIter(*this, _vh, true); } - -inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwend(VertexHandle _vh) -{ return VertexOHalfedgeCWIter(*this, _vh, true); } - -inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwend(VertexHandle _vh) -{ return VertexOHalfedgeCCWIter(*this, _vh, true); } - -inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_end(VertexHandle _vh) -{ return VertexEdgeIter(*this, _vh, true); } - -inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwend(VertexHandle _vh) -{ return VertexEdgeCWIter(*this, _vh, true); } - -inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwend(VertexHandle _vh) -{ return VertexEdgeCCWIter(*this, _vh, true); } - -inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_end(VertexHandle _vh) -{ return VertexFaceIter(*this, _vh, true); } - -inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwend(VertexHandle _vh) -{ return VertexFaceCWIter(*this, _vh, true); } - -inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwend(VertexHandle _vh) -{ return VertexFaceCCWIter(*this, _vh, true); } - - -inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_end(VertexHandle _vh) const -{ return ConstVertexVertexIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwend(VertexHandle _vh) const -{ return ConstVertexVertexCWIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwend(VertexHandle _vh) const -{ return ConstVertexVertexCCWIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_end(VertexHandle _vh) const -{ return ConstVertexIHalfedgeIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwend(VertexHandle _vh) const -{ return ConstVertexIHalfedgeCWIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwend(VertexHandle _vh) const -{ return ConstVertexIHalfedgeCCWIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_end(VertexHandle _vh) const -{ return ConstVertexOHalfedgeIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwend(VertexHandle _vh) const -{ return ConstVertexOHalfedgeCWIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwend(VertexHandle _vh) const -{ return ConstVertexOHalfedgeCCWIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_end(VertexHandle _vh) const -{ return ConstVertexEdgeIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwend(VertexHandle _vh) const -{ return ConstVertexEdgeCWIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwend(VertexHandle _vh) const -{ return ConstVertexEdgeCCWIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_end(VertexHandle _vh) const -{ return ConstVertexFaceIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwend(VertexHandle _vh) const -{ return ConstVertexFaceCWIter(*this, _vh, true); } - -inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwend(VertexHandle _vh) const -{ return ConstVertexFaceCCWIter(*this, _vh, true); } - - -inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_end(FaceHandle _fh) -{ return FaceVertexIter(*this, _fh, true); } - -inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwend(FaceHandle _fh) -{ return FaceVertexCWIter(*this, _fh, true); } - -inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwend(FaceHandle _fh) -{ return FaceVertexCCWIter(*this, _fh, true); } - -inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_end(FaceHandle _fh) -{ return FaceHalfedgeIter(*this, _fh, true); } - -inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwend(FaceHandle _fh) -{ return FaceHalfedgeCWIter(*this, _fh, true); } - -inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwend(FaceHandle _fh) -{ return FaceHalfedgeCCWIter(*this, _fh, true); } - -inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_end(FaceHandle _fh) -{ return FaceEdgeIter(*this, _fh, true); } - -inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwend(FaceHandle _fh) -{ return FaceEdgeCWIter(*this, _fh, true); } - -inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwend(FaceHandle _fh) -{ return FaceEdgeCCWIter(*this, _fh, true); } - -inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_end(FaceHandle _fh) -{ return FaceFaceIter(*this, _fh, true); } - -inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwend(FaceHandle _fh) -{ return FaceFaceCWIter(*this, _fh, true); } - -inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwend(FaceHandle _fh) -{ return FaceFaceCCWIter(*this, _fh, true); } - -inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_end(HalfedgeHandle _heh) -{ return HalfedgeLoopIter(*this, _heh, true); } - -inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwend(HalfedgeHandle _heh) -{ return HalfedgeLoopCWIter(*this, _heh, true); } - -inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwend(HalfedgeHandle _heh) -{ return HalfedgeLoopCCWIter(*this, _heh, true); } - - -inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_end(FaceHandle _fh) const -{ return ConstFaceVertexIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwend(FaceHandle _fh) const -{ return ConstFaceVertexCWIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwend(FaceHandle _fh) const -{ return ConstFaceVertexCCWIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_end(FaceHandle _fh) const -{ return ConstFaceHalfedgeIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwend(FaceHandle _fh) const -{ return ConstFaceHalfedgeCWIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwend(FaceHandle _fh) const -{ return ConstFaceHalfedgeCCWIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_end(FaceHandle _fh) const -{ return ConstFaceEdgeIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwend(FaceHandle _fh) const -{ return ConstFaceEdgeCWIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwend(FaceHandle _fh) const -{ return ConstFaceEdgeCCWIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_end(FaceHandle _fh) const -{ return ConstFaceFaceIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwend(FaceHandle _fh) const -{ return ConstFaceFaceCWIter(*this, _fh, true); } - -inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwend(FaceHandle _fh) const -{ return ConstFaceFaceCCWIter(*this, _fh, true); } - -inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_end(HalfedgeHandle _heh) const -{ return ConstHalfedgeLoopIter(*this, _heh, true); } - -inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwend(HalfedgeHandle _heh) const -{ return ConstHalfedgeLoopCWIter(*this, _heh, true); } - -inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwend(HalfedgeHandle _heh) const -{ return ConstHalfedgeLoopCCWIter(*this, _heh, true); } - - -}//namespace OpenMesh - +#include #endif//OPENMESH_POLYCONNECTIVITY_HH diff --git a/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh b/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh new file mode 100644 index 00000000..bde8f4cf --- /dev/null +++ b/src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh @@ -0,0 +1,777 @@ +/* ========================================================================= * + * * + * OpenMesh * + * Copyright (c) 2001-2015, RWTH-Aachen University * + * Department of Computer Graphics and Multimedia * + * All rights reserved. * + * www.openmesh.org * + * * + *---------------------------------------------------------------------------* + * This file is part of OpenMesh. * + *---------------------------------------------------------------------------* + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * 1. Redistributions of source code must retain the above copyright notice, * + * this list of conditions and the following disclaimer. * + * * + * 2. Redistributions in binary form must reproduce the above copyright * + * notice, this list of conditions and the following disclaimer in the * + * documentation and/or other materials provided with the distribution. * + * * + * 3. Neither the name of the copyright holder nor the names of its * + * contributors may be used to endorse or promote products derived from * + * this software without specific prior written permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * + * * + * ========================================================================= */ + +#ifndef OPENMESH_POLYCONNECTIVITY_INLINE_IMPL_HH +#define OPENMESH_POLYCONNECTIVITY_INLINE_IMPL_HH + +#include +#include +#include +#include + +namespace OpenMesh { + + +inline SmartVertexHandle PolyConnectivity::add_vertex() { return make_smart(new_vertex(), *this); } + +inline SmartHalfedgeHandle PolyConnectivity::next_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(next_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::prev_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(prev_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::opposite_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(opposite_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(ccw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::cw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(cw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); } + +inline SmartHalfedgeHandle PolyConnectivity::s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) { return make_smart(ArrayKernel::s_halfedge_handle(EdgeHandle(_eh), _i), _eh.mesh()); } +inline SmartEdgeHandle PolyConnectivity::s_edge_handle(SmartHalfedgeHandle _heh) { return make_smart(ArrayKernel::s_edge_handle(HalfedgeHandle(_heh)), _heh.mesh()); } + +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const { return make_smart(halfedge_handle(EdgeHandle(_eh), _i), *this); } +inline SmartEdgeHandle PolyConnectivity::edge_handle(SmartHalfedgeHandle _heh) const { return make_smart(edge_handle(HalfedgeHandle(_heh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartFaceHandle _fh) const { return make_smart(halfedge_handle(FaceHandle(_fh)), *this); } +inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartVertexHandle _vh) const { return make_smart(halfedge_handle(VertexHandle(_vh)), *this); } + +inline SmartFaceHandle PolyConnectivity::face_handle(SmartHalfedgeHandle _heh) const { return make_smart(face_handle(HalfedgeHandle(_heh)), *this); } + + + +/// Generic class for vertex/halfedge/edge/face ranges. +template +class EntityRange : public SmartRangeT, typename RangeTraitT::ITER_TYPE::SmartHandle> { + public: + typedef typename RangeTraitT::ITER_TYPE iterator; + typedef typename RangeTraitT::ITER_TYPE const_iterator; + + explicit EntityRange(typename RangeTraitT::CONTAINER_TYPE &container) : container_(container) {} + typename RangeTraitT::ITER_TYPE begin() const { return RangeTraitT::begin(container_); } + typename RangeTraitT::ITER_TYPE end() const { return RangeTraitT::end(container_); } + + private: + typename RangeTraitT::CONTAINER_TYPE &container_; +}; + +/// Generic class for iterator ranges. +template +//class CirculatorRange : public SmartRangeT, decltype (make_smart(std::declval(), std::declval()))>{ +class CirculatorRange : public SmartRangeT, typename SmartHandle::type>{ + public: + typedef typename CirculatorRangeTraitT::ITER_TYPE ITER_TYPE; + typedef typename CirculatorRangeTraitT::CENTER_ENTITY_TYPE CENTER_ENTITY_TYPE; + typedef typename CirculatorRangeTraitT::CONTAINER_TYPE CONTAINER_TYPE; + typedef ITER_TYPE iterator; + typedef ITER_TYPE const_iterator; + + CirculatorRange( + const CONTAINER_TYPE &container, + CENTER_ENTITY_TYPE center) : + container_(container), center_(center) {} + ITER_TYPE begin() const { return CirculatorRangeTraitT::begin(container_, center_); } + ITER_TYPE end() const { return CirculatorRangeTraitT::end(container_, center_); } + + private: + const CONTAINER_TYPE &container_; + CENTER_ENTITY_TYPE center_; +}; + + +inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::vertices() const { return ConstVertexRangeSkipping(*this); } +inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_vertices() const { return ConstVertexRange(*this); } +inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::halfedges() const { return ConstHalfedgeRangeSkipping(*this); } +inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_halfedges() const { return ConstHalfedgeRange(*this); } +inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::edges() const { return ConstEdgeRangeSkipping(*this); } +inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_edges() const { return ConstEdgeRange(*this); } +inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::faces() const { return ConstFaceRangeSkipping(*this); } +inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_faces() const { return ConstFaceRange(*this); } + +template <> inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::elements() const { return vertices(); } +template <> inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_elements() const { return all_vertices(); } +template <> inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::elements() const { return halfedges(); } +template <> inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_elements() const { return all_halfedges(); } +template <> inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::elements() const { return edges(); } +template <> inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_elements() const { return all_edges(); } +template <> inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::elements() const { return faces(); } +template <> inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_elements() const { return all_faces(); } + + +inline PolyConnectivity::ConstVertexVertexRange PolyConnectivity::vv_range(VertexHandle _vh) const { + return ConstVertexVertexRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexIHalfedgeRange PolyConnectivity::vih_range(VertexHandle _vh) const { + return ConstVertexIHalfedgeRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexOHalfedgeRange PolyConnectivity::voh_range(VertexHandle _vh) const { + return ConstVertexOHalfedgeRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexEdgeRange PolyConnectivity::ve_range(VertexHandle _vh) const { + return ConstVertexEdgeRange(*this, _vh); +} + +inline PolyConnectivity::ConstVertexFaceRange PolyConnectivity::vf_range(VertexHandle _vh) const { + return ConstVertexFaceRange(*this, _vh); +} + +inline PolyConnectivity::ConstFaceVertexRange PolyConnectivity::fv_range(FaceHandle _fh) const { + return ConstFaceVertexRange(*this, _fh); +} + +inline PolyConnectivity::ConstFaceHalfedgeRange PolyConnectivity::fh_range(FaceHandle _fh) const { + return ConstFaceHalfedgeRange(*this, _fh); +} + +inline PolyConnectivity::ConstFaceEdgeRange PolyConnectivity::fe_range(FaceHandle _fh) const { + return ConstFaceEdgeRange(*this, _fh); +} + +inline PolyConnectivity::ConstFaceFaceRange PolyConnectivity::ff_range(FaceHandle _fh) const { + return ConstFaceFaceRange(*this, _fh); +} + + + +inline PolyConnectivity::VertexIter PolyConnectivity::vertices_begin() +{ return VertexIter(*this, VertexHandle(0)); } + +inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_begin() const +{ return ConstVertexIter(*this, VertexHandle(0)); } + +inline PolyConnectivity::VertexIter PolyConnectivity::vertices_end() +{ return VertexIter(*this, VertexHandle( int(n_vertices() ) )); } + +inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_end() const +{ return ConstVertexIter(*this, VertexHandle( int(n_vertices()) )); } + +inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_begin() +{ return HalfedgeIter(*this, HalfedgeHandle(0)); } + +inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_begin() const +{ return ConstHalfedgeIter(*this, HalfedgeHandle(0)); } + +inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_end() +{ return HalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); } + +inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_end() const +{ return ConstHalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); } + +inline PolyConnectivity::EdgeIter PolyConnectivity::edges_begin() +{ return EdgeIter(*this, EdgeHandle(0)); } + +inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_begin() const +{ return ConstEdgeIter(*this, EdgeHandle(0)); } + +inline PolyConnectivity::EdgeIter PolyConnectivity::edges_end() +{ return EdgeIter(*this, EdgeHandle(int(n_edges()))); } + +inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_end() const +{ return ConstEdgeIter(*this, EdgeHandle(int(n_edges()))); } + +inline PolyConnectivity::FaceIter PolyConnectivity::faces_begin() +{ return FaceIter(*this, FaceHandle(0)); } + +inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_begin() const +{ return ConstFaceIter(*this, FaceHandle(0)); } + +inline PolyConnectivity::FaceIter PolyConnectivity::faces_end() +{ return FaceIter(*this, FaceHandle(int(n_faces()))); } + + +inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const +{ return ConstFaceIter(*this, FaceHandle(int(n_faces()))); } + +inline PolyConnectivity::VertexIter PolyConnectivity::vertices_sbegin() +{ return VertexIter(*this, VertexHandle(0), true); } + +inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_sbegin() const +{ return ConstVertexIter(*this, VertexHandle(0), true); } + +inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_sbegin() +{ return HalfedgeIter(*this, HalfedgeHandle(0), true); } + +inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_sbegin() const +{ return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); } + +inline PolyConnectivity::EdgeIter PolyConnectivity::edges_sbegin() +{ return EdgeIter(*this, EdgeHandle(0), true); } + +inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_sbegin() const +{ return ConstEdgeIter(*this, EdgeHandle(0), true); } + +inline PolyConnectivity::FaceIter PolyConnectivity::faces_sbegin() +{ return FaceIter(*this, FaceHandle(0), true); } + +inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_sbegin() const +{ return ConstFaceIter(*this, FaceHandle(0), true); } + +inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_iter(ArrayKernel::VertexHandle _vh) +{ return VertexVertexIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_iter(ArrayKernel::VertexHandle _vh) +{ return VertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_iter(ArrayKernel::VertexHandle _vh) +{ return VertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_iter(ArrayKernel::VertexHandle _vh) +{ return VertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_iter(ArrayKernel::VertexHandle _vh) +{ return VertexFaceIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwiter(ArrayKernel::VertexHandle _vh) +{ return VertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwiter(ArrayKernel::VertexHandle _vh) +{ return VertexFaceCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexVertexIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_iter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexFaceIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwiter(ArrayKernel::VertexHandle _vh) const +{ return ConstVertexFaceCCWIter(*this, _vh); } + +inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_iter(ArrayKernel::FaceHandle _fh) +{ return FaceVertexIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_iter(ArrayKernel::FaceHandle _fh) +{ return FaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_iter(ArrayKernel::FaceHandle _fh) +{ return FaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_iter(ArrayKernel::FaceHandle _fh) +{ return FaceFaceIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwiter(ArrayKernel::FaceHandle _fh) +{ return FaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwiter(ArrayKernel::FaceHandle _fh) +{ return FaceFaceCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceVertexIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_iter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceFaceIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwiter(ArrayKernel::FaceHandle _fh) const +{ return ConstFaceFaceCCWIter(*this, _fh); } + + +inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_begin(VertexHandle _vh) +{ return VertexVertexIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwbegin(VertexHandle _vh) +{ return VertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwbegin(VertexHandle _vh) +{ return VertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_begin(VertexHandle _vh) +{ return VertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwbegin(VertexHandle _vh) +{ return VertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwbegin(VertexHandle _vh) +{ return VertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_begin(VertexHandle _vh) +{ return VertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwbegin(VertexHandle _vh) +{ return VertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwbegin(VertexHandle _vh) +{ return VertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_begin(VertexHandle _vh) +{ return VertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwbegin(VertexHandle _vh) +{ return VertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwbegin(VertexHandle _vh) +{ return VertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_begin(VertexHandle _vh) +{ return VertexFaceIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwbegin(VertexHandle _vh) +{ return VertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwbegin(VertexHandle _vh) +{ return VertexFaceCCWIter(*this, _vh); } + + +inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_begin(VertexHandle _vh) const +{ return ConstVertexVertexIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwbegin(VertexHandle _vh) const +{ return ConstVertexVertexCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwbegin(VertexHandle _vh) const +{ return ConstVertexVertexCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_begin(VertexHandle _vh) const +{ return ConstVertexIHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwbegin(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwbegin(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_begin(VertexHandle _vh) const +{ return ConstVertexOHalfedgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwbegin(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwbegin(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_begin(VertexHandle _vh) const +{ return ConstVertexEdgeIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwbegin(VertexHandle _vh) const +{ return ConstVertexEdgeCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwbegin(VertexHandle _vh) const +{ return ConstVertexEdgeCCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_begin(VertexHandle _vh) const +{ return ConstVertexFaceIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwbegin(VertexHandle _vh) const +{ return ConstVertexFaceCWIter(*this, _vh); } + +inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwbegin(VertexHandle _vh) const +{ return ConstVertexFaceCCWIter(*this, _vh); } + + +inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_begin(FaceHandle _fh) +{ return FaceVertexIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwbegin(FaceHandle _fh) +{ return FaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwbegin(FaceHandle _fh) +{ return FaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_begin(FaceHandle _fh) +{ return FaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwbegin(FaceHandle _fh) +{ return FaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwbegin(FaceHandle _fh) +{ return FaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_begin(FaceHandle _fh) +{ return FaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwbegin(FaceHandle _fh) +{ return FaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwbegin(FaceHandle _fh) +{ return FaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_begin(FaceHandle _fh) +{ return FaceFaceIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwbegin(FaceHandle _fh) +{ return FaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwbegin(FaceHandle _fh) +{ return FaceFaceCCWIter(*this, _fh); } + +inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_begin(HalfedgeHandle _heh) +{ return HalfedgeLoopIter(*this, _heh); } + +inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwbegin(HalfedgeHandle _heh) +{ return HalfedgeLoopCWIter(*this, _heh); } + +inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwbegin(HalfedgeHandle _heh) +{ return HalfedgeLoopCCWIter(*this, _heh); } + + +inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_begin(FaceHandle _fh) const +{ return ConstFaceVertexIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwbegin(FaceHandle _fh) const +{ return ConstFaceVertexCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwbegin(FaceHandle _fh) const +{ return ConstFaceVertexCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_begin(FaceHandle _fh) const +{ return ConstFaceHalfedgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwbegin(FaceHandle _fh) const +{ return ConstFaceHalfedgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwbegin(FaceHandle _fh) const +{ return ConstFaceHalfedgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_begin(FaceHandle _fh) const +{ return ConstFaceEdgeIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwbegin(FaceHandle _fh) const +{ return ConstFaceEdgeCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwbegin(FaceHandle _fh) const +{ return ConstFaceEdgeCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_begin(FaceHandle _fh) const +{ return ConstFaceFaceIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwbegin(FaceHandle _fh) const +{ return ConstFaceFaceCWIter(*this, _fh); } + +inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwbegin(FaceHandle _fh) const +{ return ConstFaceFaceCCWIter(*this, _fh); } + +inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_begin(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopIter(*this, _heh); } + +inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwbegin(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCWIter(*this, _heh); } + +inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwbegin(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCCWIter(*this, _heh); } + +// 'end' circulators + +inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_end(VertexHandle _vh) +{ return VertexVertexIter(*this, _vh, true); } + +inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwend(VertexHandle _vh) +{ return VertexVertexCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwend(VertexHandle _vh) +{ return VertexVertexCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_end(VertexHandle _vh) +{ return VertexIHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwend(VertexHandle _vh) +{ return VertexIHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwend(VertexHandle _vh) +{ return VertexIHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_end(VertexHandle _vh) +{ return VertexOHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwend(VertexHandle _vh) +{ return VertexOHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwend(VertexHandle _vh) +{ return VertexOHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_end(VertexHandle _vh) +{ return VertexEdgeIter(*this, _vh, true); } + +inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwend(VertexHandle _vh) +{ return VertexEdgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwend(VertexHandle _vh) +{ return VertexEdgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_end(VertexHandle _vh) +{ return VertexFaceIter(*this, _vh, true); } + +inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwend(VertexHandle _vh) +{ return VertexFaceCWIter(*this, _vh, true); } + +inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwend(VertexHandle _vh) +{ return VertexFaceCCWIter(*this, _vh, true); } + + +inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_end(VertexHandle _vh) const +{ return ConstVertexVertexIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwend(VertexHandle _vh) const +{ return ConstVertexVertexCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwend(VertexHandle _vh) const +{ return ConstVertexVertexCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_end(VertexHandle _vh) const +{ return ConstVertexIHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwend(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwend(VertexHandle _vh) const +{ return ConstVertexIHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_end(VertexHandle _vh) const +{ return ConstVertexOHalfedgeIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwend(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwend(VertexHandle _vh) const +{ return ConstVertexOHalfedgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_end(VertexHandle _vh) const +{ return ConstVertexEdgeIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwend(VertexHandle _vh) const +{ return ConstVertexEdgeCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwend(VertexHandle _vh) const +{ return ConstVertexEdgeCCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_end(VertexHandle _vh) const +{ return ConstVertexFaceIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwend(VertexHandle _vh) const +{ return ConstVertexFaceCWIter(*this, _vh, true); } + +inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwend(VertexHandle _vh) const +{ return ConstVertexFaceCCWIter(*this, _vh, true); } + + +inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_end(FaceHandle _fh) +{ return FaceVertexIter(*this, _fh, true); } + +inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwend(FaceHandle _fh) +{ return FaceVertexCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwend(FaceHandle _fh) +{ return FaceVertexCCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_end(FaceHandle _fh) +{ return FaceHalfedgeIter(*this, _fh, true); } + +inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwend(FaceHandle _fh) +{ return FaceHalfedgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwend(FaceHandle _fh) +{ return FaceHalfedgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_end(FaceHandle _fh) +{ return FaceEdgeIter(*this, _fh, true); } + +inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwend(FaceHandle _fh) +{ return FaceEdgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwend(FaceHandle _fh) +{ return FaceEdgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_end(FaceHandle _fh) +{ return FaceFaceIter(*this, _fh, true); } + +inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwend(FaceHandle _fh) +{ return FaceFaceCWIter(*this, _fh, true); } + +inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwend(FaceHandle _fh) +{ return FaceFaceCCWIter(*this, _fh, true); } + +inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_end(HalfedgeHandle _heh) +{ return HalfedgeLoopIter(*this, _heh, true); } + +inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwend(HalfedgeHandle _heh) +{ return HalfedgeLoopCWIter(*this, _heh, true); } + +inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwend(HalfedgeHandle _heh) +{ return HalfedgeLoopCCWIter(*this, _heh, true); } + + +inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_end(FaceHandle _fh) const +{ return ConstFaceVertexIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwend(FaceHandle _fh) const +{ return ConstFaceVertexCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwend(FaceHandle _fh) const +{ return ConstFaceVertexCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_end(FaceHandle _fh) const +{ return ConstFaceHalfedgeIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwend(FaceHandle _fh) const +{ return ConstFaceHalfedgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwend(FaceHandle _fh) const +{ return ConstFaceHalfedgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_end(FaceHandle _fh) const +{ return ConstFaceEdgeIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwend(FaceHandle _fh) const +{ return ConstFaceEdgeCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwend(FaceHandle _fh) const +{ return ConstFaceEdgeCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_end(FaceHandle _fh) const +{ return ConstFaceFaceIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwend(FaceHandle _fh) const +{ return ConstFaceFaceCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwend(FaceHandle _fh) const +{ return ConstFaceFaceCCWIter(*this, _fh, true); } + +inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_end(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopIter(*this, _heh, true); } + +inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwend(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCWIter(*this, _heh, true); } + +inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwend(HalfedgeHandle _heh) const +{ return ConstHalfedgeLoopCCWIter(*this, _heh, true); } + + +}//namespace OpenMesh + +#endif // OPENMESH_POLYCONNECTIVITY_INLINE_IMPL_HH + From 3d1ae7d78733120a54213c1ebaa0c9c3b9a5adce Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 15:28:55 +0100 Subject: [PATCH 45/60] return const property handle to points property in AttribKernel --- src/OpenMesh/Core/Mesh/AttribKernelT.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/AttribKernelT.hh b/src/OpenMesh/Core/Mesh/AttribKernelT.hh index 3d4d2046..8dc1a2b8 100644 --- a/src/OpenMesh/Core/Mesh/AttribKernelT.hh +++ b/src/OpenMesh/Core/Mesh/AttribKernelT.hh @@ -256,7 +256,7 @@ public: void set_point(VertexHandle _vh, const Point& _p) { this->property(points_, _vh) = _p; } - PointsPropertyHandle& points_property_handle() + const PointsPropertyHandle& points_property_handle() const { return points_; } From ab353c8dd0a0410cac11c4602b90bb79d6fd8ffe Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 15:29:11 +0100 Subject: [PATCH 46/60] Define a MeshHandle to simplify some template programming --- src/OpenMesh/Core/Mesh/Handles.hh | 9 +++++++++ src/OpenMesh/Core/Utils/Property.hh | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/OpenMesh/Core/Mesh/Handles.hh b/src/OpenMesh/Core/Mesh/Handles.hh index 0c8c21c4..4871996d 100644 --- a/src/OpenMesh/Core/Mesh/Handles.hh +++ b/src/OpenMesh/Core/Mesh/Handles.hh @@ -144,6 +144,15 @@ struct FaceHandle : public BaseHandle }; +/// Handle type for meshes to simplify some template programming +struct MeshHandle : public BaseHandle +{ + explicit MeshHandle(int _idx=-1) : BaseHandle(_idx) {} +}; + + + + //============================================================================= } // namespace OpenMesh //============================================================================= diff --git a/src/OpenMesh/Core/Utils/Property.hh b/src/OpenMesh/Core/Utils/Property.hh index fb97f81c..71e2f86f 100644 --- a/src/OpenMesh/Core/Utils/Property.hh +++ b/src/OpenMesh/Core/Utils/Property.hh @@ -545,7 +545,7 @@ struct MPropHandleT : public BasePropHandleT { typedef T Value; typedef T value_type; - typedef void Handle; + typedef MeshHandle Handle; explicit MPropHandleT(int _idx=-1) : BasePropHandleT(_idx) {} explicit MPropHandleT(const BasePropHandleT& _b) : BasePropHandleT(_b) {} From c4e7125c97f3d19b81739f82f9bd36578f025a04 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 15:30:05 +0100 Subject: [PATCH 47/60] allow adding temporary properties on const meshes --- src/OpenMesh/Core/Utils/PropertyManager.hh | 130 ++++++++++++++------- src/Unittests/unittests_propertymanager.cc | 109 +++++++++++++---- 2 files changed, 173 insertions(+), 66 deletions(-) diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index 207746ae..82db190d 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -101,6 +101,12 @@ class PropertyManager { static void swap(PropertyManager& from, PropertyManager2& to) { std::swap(*to, *from); } + static const Value& access_property_const(PolyConnectivity& mesh, const PROPTYPE& prop_handle, const Handle&) { + return mesh.property(prop_handle); + } + static Value& access_property(PolyConnectivity& mesh, const PROPTYPE& prop_handle, const Handle&) { + return mesh.property(prop_handle); + } }; // definition for other Mesh Properties @@ -110,10 +116,16 @@ class PropertyManager { from.copy_to(from.mesh_.template all_elements(), to, to.mesh_.template all_elements()); } static void swap(PropertyManager& lhs, PropertyManager2& rhs) { - std::swap(lhs.mesh_.property(lhs.prop_).data_vector(), rhs.mesh_.property(rhs.prop_).data_vector()); + std::swap(lhs.mesh().property(lhs.prop_).data_vector(), rhs.mesh().property(rhs.prop_).data_vector()); // resize the property to the correct size - lhs.mesh_.property(lhs.prop_).resize(lhs.mesh_.template n_elements()); - rhs.mesh_.property(rhs.prop_).resize(rhs.mesh_.template n_elements()); + lhs.mesh().property(lhs.prop_).resize(lhs.mesh().template n_elements()); + rhs.mesh().property(rhs.prop_).resize(rhs.mesh().template n_elements()); + } + static const Value& access_property_const(PolyConnectivity& mesh, const PROPTYPE& prop_handle, const Handle& handle) { + return mesh.property(prop_handle, handle); + } + static Value& access_property(PolyConnectivity& mesh, const PROPTYPE& prop_handle, const Handle& handle) { + return mesh.property(prop_handle, handle); } }; @@ -143,13 +155,13 @@ class PropertyManager { OM_DEPRECATED("Use the constructor without parameter 'existing' instead. Check for existance with hasProperty") // As long as this overload exists, initial value must be first parameter due to ambiguity for properties of type bool PropertyManager(PolyConnectivity& mesh, const char *propname, bool existing) : mesh_(mesh), retain_(existing), name_(propname) { if (existing) { - if (!mesh_.get_property_handle(prop_, propname)) { + if (!PropertyManager::mesh().get_property_handle(prop_, propname)) { std::ostringstream oss; oss << "Requested property handle \"" << propname << "\" does not exist."; throw std::runtime_error(oss.str()); } } else { - mesh_.add_property(prop_, propname); + PropertyManager::mesh().add_property(prop_, propname); } } @@ -162,8 +174,8 @@ class PropertyManager { * @param propname The name of the property. */ PropertyManager(PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { - if (!mesh_.get_property_handle(prop_, propname)) { - mesh_.add_property(prop_, propname); + if (!PropertyManager::mesh().get_property_handle(prop_, propname)) { + PropertyManager::mesh().add_property(prop_, propname); } } @@ -179,7 +191,7 @@ class PropertyManager { */ PropertyManager(const Value& intial_value, PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { if (!mesh_.get_property_handle(prop_, propname)) { - mesh_.add_property(prop_, propname); + PropertyManager::mesh().add_property(prop_, propname); set_range(mesh_.all_elements(), intial_value); } } @@ -191,8 +203,8 @@ class PropertyManager { * * @param mesh The mesh on which to create the property. */ - PropertyManager(PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { - mesh_.add_property(prop_, name_); + PropertyManager(const PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { + PropertyManager::mesh().add_property(prop_, name_); } /** @@ -203,8 +215,8 @@ class PropertyManager { * @param initial_value The property will be initialized with intial_value. * @param mesh The mesh on which to create the property. */ - PropertyManager(const Value& intial_value, PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { - mesh_.add_property(prop_, name_); + PropertyManager(const Value& intial_value, const PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { + PropertyManager::mesh().add_property(prop_, name_); set_range(mesh_.all_elements(), intial_value); } @@ -233,7 +245,7 @@ class PropertyManager { } else // unnamed property -> create a property manager refering to a new property and copy the contents { - mesh_.add_property(prop_, name_); + PropertyManager::mesh().add_property(prop_, name_); Storage::copy(rhs, *this); } } @@ -282,9 +294,9 @@ class PropertyManager { * */ template - MeshType& getMesh() const { return dynamic_cast(mesh_); } + const MeshType& getMesh() const { return dynamic_cast(mesh_); } - MeshT& getMesh() const { return dynamic_cast(mesh_); } + const MeshT& getMesh() const { return dynamic_cast(mesh_); } /** * Move constructor. Transfers ownership (delete responsibility). @@ -317,7 +329,7 @@ class PropertyManager { // swap the data stored in the properties Storage::swap(rhs, *this); // remove the property from rhs - rhs.mesh_.remove_property(rhs.prop_); + rhs.mesh().remove_property(rhs.prop_); // invalidate prop_ rhs.prop_.invalidate(); } @@ -373,18 +385,6 @@ class PropertyManager { mesh, propname, range.begin(), range.end(), init_value); } - PropertyManager duplicate(const char *clone_name) { - PropertyManager pm(mesh_, clone_name, false); - pm.mesh_.property(pm.prop_) = mesh_.property(prop_); - return pm; - } - - /** - * Included for backwards compatibility with non-C++11 version. - */ - PropertyManager move() { - return std::move(*this); - } /** * Access the value of the encapsulated mesh property. @@ -399,7 +399,7 @@ class PropertyManager { * @note This method is only used for mesh properties. */ typename PROPTYPE::reference& operator*() { - return mesh_.mproperty(prop_)[0]; + return mesh().mproperty(prop_)[0]; } /** @@ -415,7 +415,7 @@ class PropertyManager { * @note This method is only used for mesh properties. */ typename PROPTYPE::const_reference& operator*() const { - return mesh_.mproperty(prop_)[0]; + return mesh().mproperty(prop_)[0]; } /** @@ -425,9 +425,8 @@ class PropertyManager { * * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) */ - template - inline typename PROPTYPE::reference operator[] (const HandleType &handle) { - return mesh_.property(prop_, handle); + inline typename PROPTYPE::reference operator[] (Handle handle) { + return mesh().property(prop_, handle); } /** @@ -437,9 +436,8 @@ class PropertyManager { * * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) */ - template - inline typename PROPTYPE::const_reference operator[] (const HandleType &handle) const { - return mesh_.property(prop_, handle); + inline typename PROPTYPE::const_reference operator[] (const Handle& handle) const { + return mesh().property(prop_, handle); } /** @@ -449,9 +447,9 @@ class PropertyManager { * * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) */ - template - inline typename PROPTYPE::reference operator() (const HandleType &handle) { - return mesh_.property(prop_, handle); + inline typename PROPTYPE::reference operator() (const Handle& handle = Handle()) { +// return mesh().property(prop_, handle); + return Storage::access_property(mesh(), prop_, handle); } /** @@ -461,9 +459,9 @@ class PropertyManager { * * @param handle A handle of the appropriate handle type. (I.e. \p VertexHandle for \p VPropHandleT, etc.) */ - template - inline typename PROPTYPE::const_reference operator() (const HandleType &handle) const { - return mesh_.property(prop_, handle); + inline typename PROPTYPE::const_reference operator() (const Handle& handle = Handle()) const { +// return mesh().property(prop_, handle); + return Storage::access_property_const(mesh(), prop_, handle); } /** @@ -571,16 +569,50 @@ class PropertyManager { private: void deleteProperty() { if (!retain_ && prop_.is_valid()) - mesh_.remove_property(prop_); + mesh().remove_property(prop_); + } + + PolyConnectivity& mesh() const + { + return const_cast(mesh_); } private: - PolyConnectivity& mesh_; + const PolyConnectivity& mesh_; PROPTYPE prop_; bool retain_; std::string name_; }; +template +class ConstPropertyViewer +{ +public: + using Value = typename PropertyT::Value; + using value_type = typename PropertyT::value_type; + using Handle = typename PropertyT::Handle; + + ConstPropertyViewer(const PolyConnectivity& mesh, PropertyT property_handle) + : + mesh_(mesh), + prop_(property_handle) + {} + + inline const typename PropertyT::const_reference operator() (const Handle& handle) + { + return mesh_.property(prop_, handle); + } + + inline const typename PropertyT::const_reference operator[] (const Handle& handle) + { + return mesh_.property(prop_, handle); + } + +private: + const PolyConnectivity& mesh_; + PropertyT prop_; +}; + /** @relates PropertyManager * * @deprecated Temporary properties should not have a name. @@ -852,6 +884,16 @@ getPointsProperty(MeshT &mesh) { return PropertyManager>(mesh, mesh.points_property_handle()); } +/** @relates PropertyManager + * Returns a convenience wrapper around the points property of a mesh that only allows const access. + */ +template +ConstPropertyViewer> +getPointsProperty(const MeshT &mesh) { + using PropType = OpenMesh::VPropHandleT; + return ConstPropertyViewer(mesh, mesh.points_property_handle()); +} + template using Prop = PropertyManager::template type>; diff --git a/src/Unittests/unittests_propertymanager.cc b/src/Unittests/unittests_propertymanager.cc index ea7e82f7..5ae91071 100644 --- a/src/Unittests/unittests_propertymanager.cc +++ b/src/Unittests/unittests_propertymanager.cc @@ -4,6 +4,13 @@ #include +//#define ENABLE_PROPERTY_TIMING_OUTPUT +#ifdef ENABLE_PROPERTY_TIMING_OUTPUT +#define TIMING_OUTPUT(X) X +#else +#define TIMING_OUTPUT(X) +#endif + namespace { class OpenMeshPropertyManager : public OpenMeshBase { @@ -228,7 +235,7 @@ TEST_F(OpenMeshPropertyManager, property_move_construction) { auto t_start = std::chrono::high_resolution_clock::now(); auto prop2 = std::move(prop1); auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "move constructing property from temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "move constructing property from temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_FALSE(prop1.isValid()) << "prop1 should have been invalidated"; @@ -244,7 +251,7 @@ TEST_F(OpenMeshPropertyManager, property_move_construction) { auto t_start = std::chrono::high_resolution_clock::now(); auto prop2 = std::move(prop1); // prop1 and prop2 should refere to the same property auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "move constructing from named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "move constructing from named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_TRUE(prop1.isValid()) << "named properties cannot be invalidated"; @@ -279,7 +286,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; @@ -303,7 +310,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; @@ -328,7 +335,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) prop1.set_range(mesh_.vertices(), 0); @@ -351,7 +358,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) prop1.set_range(mesh_.vertices(), 0); @@ -372,7 +379,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; // this should be a no op auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; @@ -417,7 +424,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); // this should be cheap auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; @@ -439,7 +446,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; @@ -462,7 +469,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; @@ -487,7 +494,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; @@ -510,7 +517,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); // this should be a no op auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; @@ -553,7 +560,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; @@ -578,7 +585,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Temporary property got destroyed"; @@ -603,7 +610,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) prop1.set_range(mesh_.vertices(), 0); @@ -626,7 +633,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) prop1.set_range(mesh_.vertices(), 0); @@ -646,7 +653,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = prop1; // this should be a no op auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "copying property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "copying property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_EQ(prop1[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; EXPECT_EQ(prop2[OpenMesh::VertexHandle(0)], -13) << "Property not copied correctly"; @@ -687,7 +694,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); // this should be cheap auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property temporary to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; @@ -710,7 +717,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property temporary to named took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_FALSE(prop1.isValid()) << "prop1 not invalidated after moving"; @@ -733,7 +740,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property named to temporary took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; @@ -758,7 +765,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); // moving named properties will not invalidate the property and will copy the data auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property named to named with different name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; @@ -783,7 +790,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { auto t_start = std::chrono::high_resolution_clock::now(); prop2 = std::move(prop1); // should copy auto t_end = std::chrono::high_resolution_clock::now(); - std::cout << "moving property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl; + TIMING_OUTPUT(std::cout << "moving property named to named with same name took " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) EXPECT_TRUE(prop1.isValid()) << "named prop1 should not be invalidated by moving"; @@ -803,5 +810,63 @@ TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { } +TEST_F(OpenMeshPropertyManager, temporary_property_on_const_mesh) { + + const auto& const_ref = mesh_; + + auto cog = OpenMesh::FProp(const_ref); + auto points = OpenMesh::getPointsProperty(const_ref); + + for (auto fh : const_ref.faces()) + cog(fh) = fh.vertices().avg(points); + + auto cog_copy = cog; + + for (auto fh : const_ref.faces()) + { + EXPECT_NE(&cog(fh), &cog_copy(fh)) << "Both properties point to the same memory"; + EXPECT_EQ(cog(fh), cog_copy(fh)) << "Property not copied correctly"; + } + + auto description = OpenMesh::MProp(const_ref); + description() = "Cool Const Mesh"; + + std::cout << description(OpenMesh::MeshHandle(33)) << std::endl; + +} + + +OpenMesh::VProp get_id_prop(const OpenMesh::PolyConnectivity& mesh) +{ + auto t_start = std::chrono::high_resolution_clock::now(); + + auto id_prop = OpenMesh::VProp(mesh); + for (auto vh : mesh.vertices()) + id_prop(vh) = vh.idx(); + + auto t_end = std::chrono::high_resolution_clock::now(); + TIMING_OUTPUT(std::cout << "Time spend in function: " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + return id_prop; +} + +TEST_F(OpenMeshPropertyManager, return_property_from_function) { + + for (int i = 0; i < 1000000; ++i) + mesh_.add_vertex(Mesh::Point()); + + auto t_start = std::chrono::high_resolution_clock::now(); + auto id_p = get_id_prop(mesh_); + auto t_end = std::chrono::high_resolution_clock::now(); + TIMING_OUTPUT(std::cout << "Time spend around function " << std::chrono::duration_cast(t_end-t_start).count() << "ms" << std::endl;) + + for (auto vh : mesh_.vertices()) + { + EXPECT_EQ(id_p(vh), vh.idx()) << "Property not returned correctly" << std::endl; + } + +} + + } From 5a06a63e92a7dcf739879acf7ed2780ecd6f87ed Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 18:12:37 +0100 Subject: [PATCH 48/60] fix typo --- src/OpenMesh/Core/Utils/PropertyManager.hh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index a48bc8b8..c3b90269 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -172,15 +172,15 @@ class PropertyManager { * * Asks for a property with name propname and creates one if none exists. Lifetime is not managed. * - * @param initial_value If the proeprty is newly created, it will be initialized with intial_value. + * @param initial_value If the proeprty is newly created, it will be initialized with initial_value. * If the property already existed, nothing is changes. * @param mesh The mesh on which to create the property. * @param propname The name of the property. */ - PropertyManager(const Value& intial_value, PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { + PropertyManager(const Value& initial_value, PolyConnectivity& mesh, const char *propname) : mesh_(mesh), retain_(true), name_(propname) { if (!mesh_.get_property_handle(prop_, propname)) { mesh_.add_property(prop_, propname); - set_range(mesh_.all_elements(), intial_value); + set_range(mesh_.all_elements(), initial_value); } } @@ -200,12 +200,12 @@ class PropertyManager { * * Create an anonymous property. Lifetime is managed. * - * @param initial_value The property will be initialized with intial_value. + * @param initial_value The property will be initialized with initial_value. * @param mesh The mesh on which to create the property. */ - PropertyManager(const Value& intial_value, PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { + PropertyManager(const Value& initial_value, PolyConnectivity& mesh) : mesh_(mesh), retain_(false), name_("") { mesh_.add_property(prop_, name_); - set_range(mesh_.all_elements(), intial_value); + set_range(mesh_.all_elements(), initial_value); } /** From 0b19876851ee3b8740004900a2ca3cec860ef69b Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 18:13:07 +0100 Subject: [PATCH 49/60] update PropertyManager docu --- Doc/tutorial_03.docu | 27 ++++++++------------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/Doc/tutorial_03.docu b/Doc/tutorial_03.docu index 01f8c6e3..bb9502f8 100644 --- a/Doc/tutorial_03.docu +++ b/Doc/tutorial_03.docu @@ -74,30 +74,19 @@ Below is the complete source code: ## Property Lifetime -In the above example, we chose to use makeTemporaryProperty(). This causes the created property to automatically be removed from the mesh as soon as we leave the scope of the associated handle variable \c cog. +In the above example, we chose to use VProp without a name. This causes the created property to automatically be removed from the mesh as soon as we leave the scope of the associated handle variable \c cog. -If, instead, a property is desired to survive its local scope, it should be created with using getOrMakeProperty(). In that case, the property must be given a name that can later be used to retrieve the property. For example: +If, instead, a property is desired to survive its local scope, it should be created with a name. For example: \code - auto face_area = OpenMesh::makeTemporaryProperty(mesh, "face_area"); + auto face_area = OpenMesh::FProp(mesh, "face_area"); \endcode -At a later time, we can use the getProperty() function to obtain a handle to a property that was previously created by refering to its name: +At a later time, we can access the same property by using the same name. If we want to make sure, that we access a property that has already been created earler, we can use hasProperty() to test whether a mesh has the desired property: \code - try { - auto face_area = OpenMesh::getProperty(mesh, "face_area"); - // Use the face_area property. - } - catch (const std::runtime_error& e) { - // Property not found. Handle the error here. - } -\endcode - -Using hasProperty(), we can test whether a mesh has a certain property: -\code - if (OpenMesh::hasProperty(mesh, "is_valley")) { + if (OpenMesh::hasProperty(mesh, "face_area")) { // Property exists. Do something with it. - auto valley = OpenMesh::getProperty(mesh, "is_valley"); + auto valley = OpenMesh::FProp(mesh, "face_area"); } else { // Property does not exist. Do something else. @@ -108,9 +97,9 @@ Using hasProperty(), we can test whether a mesh has a certain property: ## Low-Level Property API -The functions makeTemporaryProperty(), getOrMakeProperty(), and getProperty() are the convenient high-level interface for creating and accessing mesh properties. +The property managers VProp, HProp, EProp, FProp and MProp are the convenient high-level interface for creating and accessing mesh properties. -Beneath these convenience functions, there is also a low-level property interface where handle and property lifetime must be managed manually. This interface is accessed through a mesh's add_property(), remove_property(), and property() functions and several property handle classes (OpenMesh::VPropHandleT, OpenMesh::HPropHandleT, OpenMesh::EPropHandleT, OpenMesh::FPropHandleT, OpenMesh::MPropHandleT). +Beneath these convenience functions, there is also a low-level property interface where handle and property lifetime must be managed manually. This interface is accessed through a mesh's add_property(), get_property(), remove_property(), and property() functions and several property handle classes (OpenMesh::VPropHandleT, OpenMesh::HPropHandleT, OpenMesh::EPropHandleT, OpenMesh::FPropHandleT, OpenMesh::MPropHandleT). --- From 6b9f6533c2a4d8419a3800f750f54a6d80997852 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Tue, 5 Nov 2019 18:40:30 +0100 Subject: [PATCH 50/60] reduce the number of vertices in property manager tests if you are not interested in timings --- src/Unittests/unittests_propertymanager.cc | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/Unittests/unittests_propertymanager.cc b/src/Unittests/unittests_propertymanager.cc index 5ae91071..5f0a1a1f 100644 --- a/src/Unittests/unittests_propertymanager.cc +++ b/src/Unittests/unittests_propertymanager.cc @@ -6,8 +6,10 @@ //#define ENABLE_PROPERTY_TIMING_OUTPUT #ifdef ENABLE_PROPERTY_TIMING_OUTPUT +#define N_VERTICES_TIMING 1000000 #define TIMING_OUTPUT(X) X #else +#define N_VERTICES_TIMING 10 #define TIMING_OUTPUT(X) #endif @@ -190,7 +192,7 @@ TEST_F(OpenMeshPropertyManager, cpp11_persistent_and_non_owning_properties) { TEST_F(OpenMeshPropertyManager, property_copy_construction) { - for (int i = 0; i < 1000000; ++i) + for (int i = 0; i < N_VERTICES_TIMING; ++i) mesh_.add_vertex(Mesh::Point()); // unnamed @@ -223,7 +225,7 @@ TEST_F(OpenMeshPropertyManager, property_copy_construction) { } TEST_F(OpenMeshPropertyManager, property_move_construction) { - for (int i = 0; i < 1000000; ++i) + for (int i = 0; i < N_VERTICES_TIMING; ++i) mesh_.add_vertex(Mesh::Point()); // unnamed @@ -268,7 +270,7 @@ TEST_F(OpenMeshPropertyManager, property_move_construction) { TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { - for (int i = 0; i < 1000000; ++i) + for (int i = 0; i < N_VERTICES_TIMING; ++i) mesh_.add_vertex(Mesh::Point()); // unnamed to unnamed @@ -407,7 +409,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_same_mesh) { TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) { - for (int i = 0; i < 1000000; ++i) + for (int i = 0; i < N_VERTICES_TIMING; ++i) mesh_.add_vertex(Mesh::Point()); // unnamed to unnamed @@ -538,7 +540,7 @@ TEST_F(OpenMeshPropertyManager, property_moving_same_mesh) { TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { - for (int i = 0; i < 1000000; ++i) + for (int i = 0; i < N_VERTICES_TIMING; ++i) mesh_.add_vertex(Mesh::Point()); auto copy = mesh_; @@ -673,7 +675,7 @@ TEST_F(OpenMeshPropertyManager, property_copying_different_mesh) { TEST_F(OpenMeshPropertyManager, property_moving_different_mesh) { - for (int i = 0; i < 1000000; ++i) + for (int i = 0; i < N_VERTICES_TIMING; ++i) mesh_.add_vertex(Mesh::Point()); auto copy = mesh_; @@ -852,7 +854,7 @@ OpenMesh::VProp get_id_prop(const OpenMesh::PolyConnectivity& mesh) TEST_F(OpenMeshPropertyManager, return_property_from_function) { - for (int i = 0; i < 1000000; ++i) + for (int i = 0; i < N_VERTICES_TIMING; ++i) mesh_.add_vertex(Mesh::Point()); auto t_start = std::chrono::high_resolution_clock::now(); From f47228003e2bd5c8fd1c5e390543a838f8fc33e6 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 6 Nov 2019 09:27:01 +0100 Subject: [PATCH 51/60] fix docu --- Doc/tutorial_03.docu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/tutorial_03.docu b/Doc/tutorial_03.docu index bb9502f8..a21749f6 100644 --- a/Doc/tutorial_03.docu +++ b/Doc/tutorial_03.docu @@ -49,7 +49,7 @@ In this example, we will store the \c cog value (see previous example) in a vert To do so, we first add a (temporary) property of the desired element type (OpenMesh::VertexHandle) and value type (\c %MyMesh::Point) to the mesh: \dontinclude 03-properties/smooth.cc -\skipline makeTemporaryProperty +\skipline VProp Enough memory is allocated to hold as many values of \c %MyMesh::Point as there are vertices. All insert and delete operations on the mesh are synchronized with the attached properties. From 3a2791c43647e16c5394555af518da95f5bb6c10 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 6 Nov 2019 11:41:41 +0100 Subject: [PATCH 52/60] update documentation --- Doc/Tutorial/11-smart_handles/smooth.cc | 62 + Doc/mainpage.docu | 1 + Doc/tutorial_11.docu | 85 + Doc/tutorial_main.docu | 1 + src/OpenMesh/Core/Mesh/SmartRange.hh | 49 +- src/OpenMesh/Core/Utils/PropertyManager.hh | 1 + src/Unittests/TestFiles/cube_noisy.off | 22576 +++++++++++++++++++ src/Unittests/unittests_tutorials.cc | 50 +- 8 files changed, 22818 insertions(+), 7 deletions(-) create mode 100644 Doc/Tutorial/11-smart_handles/smooth.cc create mode 100644 Doc/tutorial_11.docu create mode 100644 src/Unittests/TestFiles/cube_noisy.off diff --git a/Doc/Tutorial/11-smart_handles/smooth.cc b/Doc/Tutorial/11-smart_handles/smooth.cc new file mode 100644 index 00000000..38beb10f --- /dev/null +++ b/Doc/Tutorial/11-smart_handles/smooth.cc @@ -0,0 +1,62 @@ + +#include +#include +#include + +#include +#include + +using MyMesh = OpenMesh::TriMesh; + +int main(int argc, char** argv) +{ + // Read command line options + MyMesh mesh; + if (argc != 4) { + std::cerr << "Usage: " << argv[0] << " #iterations infile outfile" << std::endl; + return 1; + } + const int iterations = argv[1]; + const std::string infile = argv[2]; + const std::string outfile = argv[3]; + + // Read mesh file + if (!OpenMesh::IO::read_mesh(mesh, infile)) { + std::cerr << "Error: Cannot read mesh from " << infile << std::endl; + return 1; + } + + { + // Add a vertex property storing the laplace vector + auto laplace = OpenMesh::VProp(mesh); + + // Add a vertex property storing the laplace of the laplace + auto bi_laplace = OpenMesh::VProp(mesh); + + // Get a propertymanager of the points property of the mesh to use as functor + auto points = OpenMesh::getPointsProperty(mesh); + + // Smooth the mesh several times + for (int i = 0; i < iterations; ++i) { + // Iterate over all vertices to compute laplace vector + for (const auto& vh : mesh.vertices()) + laplace(vh) = vh.vertices().avg(points) - points(vh); + + // Iterate over all vertices to compte update vectors as the negative of the laplace of the laplace damped by 0.5 + for (const auto& vh : mesh.vertices()) + bi_laplace(vh) = (vh.vertices().avg(laplace) - laplace(vh)); + + // update points + for (const auto& vh : mesh.vertices()) + points(vh) += -0.5 * bi_laplace(vh); + } + } // The laplace and update properties are removed is removed from the mesh at the end of this scope. + + + // Write mesh file + if (!OpenMesh::IO::read_mesh(mesh, outfile)) { + std::cerr << "Error: Cannot write mesh to " << outfile << std::endl; + return 1; + } +} + diff --git a/Doc/mainpage.docu b/Doc/mainpage.docu index 5f9ac4b1..63bfee8c 100644 --- a/Doc/mainpage.docu +++ b/Doc/mainpage.docu @@ -82,6 +82,7 @@ repeatedly replacing each vertex' position by the center of gravity \li \ref tutorial_02 \li \ref tutorial_03 \li \ref tutorial_04 +\li \ref tutorial_11 \li \ref tutorial_05 \li \ref tutorial_06 \li \ref tutorial_07 diff --git a/Doc/tutorial_11.docu b/Doc/tutorial_11.docu new file mode 100644 index 00000000..f99724cf --- /dev/null +++ b/Doc/tutorial_11.docu @@ -0,0 +1,85 @@ +/** \page tutorial_11 Using Smart Handles + +This examples shows: +- How to use Smart Handles and ranges to navigate on the mesh +- How to use Smart Ranges + +So far we have used methods such as halfedge_handle(), next_halfedge_handle(), prev_halfedge_handle(), oppopsite_halfedge_handle(), face_handle(), to_vertex_handle(), and some others, to navigate on that mesh. These functions are defined on a mesh and require as input a handle to an element of the mesh, such as VertexHandle or HalfedgeHandle. In the following example we iterate over all vertices of a triangle mesh and for each vertex we create a list of the vertices that lie opposite of the edges in the ring around the vertex: + +\code +// iterate over vertices of the mesh +for (auto vh : mesh.vertices()) +{ + std::vector opposite_vertices; + // iterate over all outgoing halfedges + for (auto heh : mesh.voh_range(vh)) + { + // navigate to the opposite vertex and store it in the vector + opposite_vertices.push_back(mesh.to_vertex_handle(mesh.next_halfedge_handle(mesh.opposite_halfedge_handle(mesh.next_halfedge_handle(heh))))); + } +} +\endcode + +For a more concise way of navigating OpenMesh provides smart handles, OpenMesh::SmartVertexHandle, OpenMesh::SmartHalfedgeHandle, OpenMesh::SmartEdgeHandle, and OpenMesh::SmartFaceHandle. Smart handles are smart, because they know to which mesh they belong. This allows them to provide functions for navigating the mesh allowing us to write the above code much simpler: + +\code +// iterate over vertices of the mesh +for (auto vh : mesh.vertices()) +{ + // iterate over all outgoing halfedges + std::vector opposite_vertices; + for (auto heh : vh.outgoing_halfedges()) + { + // navigate to the opposite vertex and store it in the vector + opposite_vertices.push_back(heh.next().opp().next().to()); + } +} +\endcode + +The ranges of OpenMesh that are returned by functions like voh_range() or outgoing_halfedges() all provide a few methods than can simplify some calculations (see OpenMesh::SmartRangeT). One example is the to_vector() method which convertes the range of elements into a vector containing the elements. All of these methods take a functor as argument (sometimes optional) which is called for each element of the range. With this, the above code can also be implemented like this: + +\code +// iterate over vertices of the mesh +for (auto vh : mesh.vertices()) +{ + // create lambda that returns opposite vertex + auto opposite_vertex = [](OpenMesh::SmartHalfedgeHandle heh) { return heh.next().opp().next().to(); }; + // create vector containing all opposite vertices + auto opposite_vertices = vh.outgoing_halfedges().to_vector(opposite_vertex); +} +\endcode + +--- + +## Code Example + +In this example, we will use bi-laplacian smoothing on a mesh. We store the \c laplace vector which is the vector pointing from a vertex to the center of gravity of its neighboring vertices in a vertex property. + +\dontinclude 11-smart_handles/smooth.cc +\skipline laplace +\skipline laplace + +To compute the center of gravity, i.e. the average position, we use the avg() method of the range of 1-ring vertices and pass in a PropertyManager acting as functor returning the corresponding point of a vertex. + +\skipline points +\until avg(points) + +Similarily we compute the update vector as the laplace of the freshly computed laplace vectors by simply exchanging the points property manager with the laplace property manager. + +\skipline Iterate +\until bi_laplace + +Finally, we apply the update after damping it by a factor of -0.5. + +\skipline udpate points +\until bi_laplace + +Below is the complete source code: + +\include 11-smart_handles/smooth.cc + +--- + + + +*/ diff --git a/Doc/tutorial_main.docu b/Doc/tutorial_main.docu index 13ff26cd..908099dc 100644 --- a/Doc/tutorial_main.docu +++ b/Doc/tutorial_main.docu @@ -33,6 +33,7 @@ repeatedly replacing each vertex' position by the center of gravity
  • \subpage tutorial_02
  • \subpage tutorial_03
  • \subpage tutorial_04 +
  • \subpage tutorial_11
  • \subpage tutorial_05
  • \subpage tutorial_06
  • \subpage tutorial_07 diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index a373b74a..8b40e6e2 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -70,7 +70,12 @@ struct SmartRangeT { // TODO: Someone with better c++ knowledge may improve the code below. - + /** @brief Computes the sum of elements. + * + * Computes the sum of all elements in the range after applying the functor \p f. + * + * @param f Functor that is applied to all elements before computing the sum + */ template auto sum(Functor&& f) -> decltype (f(std::declval())+f(std::declval())) { @@ -86,6 +91,12 @@ struct SmartRangeT return sum; } + /** @brief Computes the average of elements. + * + * Computes the average of all elements in the range after applying the functor \p f. + * + * @param f Functor that is applied to all elements before computing the average. + */ template auto avg(Functor&& f) -> decltype (1.0 * (f(std::declval())+f(std::declval()))) { @@ -105,6 +116,15 @@ struct SmartRangeT return (1.0 / n_elements) * sum; } + /** @brief Convert range to array. + * + * Converts the range of elements into an array of objects returned by functor \p f. + * The size of the array needs to be provided by the user. If the size is larger than the number of + * elements in the range, the remaining entries of the array will be uninitialized. + * + * @param f Functor that is applied to all elements before putting them into the array. If no functor is provided + * the array will contain the handles. + */ template auto to_array(Functor&& f = {}) -> std::array()))>::type, n> { @@ -118,6 +138,13 @@ struct SmartRangeT return res; } + /** @brief Convert range to vector. + * + * Converts the range of elements into a vector of objects returned by functor \p f. + * + * @param f Functor that is applied to all elements before putting them into the vector. If no functor is provided + * the vector will contain the handles. + */ template auto to_vector(Functor&& f = {}) -> std::vector()))>::type> { @@ -128,7 +155,12 @@ struct SmartRangeT return res; } - + /** @brief Compute minimum. + * + * Computes the minimum of all objects returned by functor \p f. + * + * @param f Functor that is applied to all elements before computing minimum. + */ template auto min(Functor&& f) -> typename std::remove_reference()))>::type { @@ -148,6 +180,12 @@ struct SmartRangeT return res; } + /** @brief Compute maximum. + * + * Computes the maximum of all objects returned by functor \p f. + * + * @param f Functor that is applied to all elements before computing maximum. + */ template auto max(Functor&& f) -> typename std::remove_reference()))>::type { @@ -167,6 +205,13 @@ struct SmartRangeT return res; } + /** @brief Computes minimum and maximum. + * + * Computes the minimum and maximum of all objects returned by functor \p f. Result is returned as std::pair + * containing minimum as first and maximum as second element. + * + * @param f Functor that is applied to all elements before computing maximum. + */ template auto minmax(Functor&& f) -> std::pair()))>::type, typename std::remove_reference()))>::type> diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index 9c8bb855..2053b645 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -226,6 +226,7 @@ class PropertyManager { * Create a wrapper around an existing property. Lifetime is not managed. * * @param mesh The mesh on which to create the property. + * @param property_handle Handle to an existing property that should be wrapped. */ PropertyManager(PolyConnectivity& mesh, PROPTYPE property_handle) : mesh_(mesh), prop_(property_handle), retain_(true), name_() { } diff --git a/src/Unittests/TestFiles/cube_noisy.off b/src/Unittests/TestFiles/cube_noisy.off new file mode 100644 index 00000000..682f4545 --- /dev/null +++ b/src/Unittests/TestFiles/cube_noisy.off @@ -0,0 +1,22576 @@ +OFF +7526 15048 22572 +0.514241 0.260794 0.389481 +0.297698 0.497249 0.10116 +0.360255 -0.0847248 0.510251 +0.391241 -0.505697 -0.0913271 +0.391198 -0.513677 -0.189891 +0.350372 0.185531 -0.502437 +-0.30363 -0.241076 -0.499723 +-0.0878174 -0.469778 0.479027 +0.506531 0.314524 -0.315277 +-0.038812 0.491603 0.0330997 +0.196215 0.497778 -0.362234 +0.502636 0.344526 0.172434 +-0.0145036 0.493906 0.0119593 +0.492366 0.116239 -0.236048 +0.133863 0.326282 -0.495219 +-0.501158 -0.228021 -0.383876 +-0.0038548 0.495309 -0.0431288 +-0.511951 -0.287301 0.30909 +-0.11319 -0.473118 0.474236 +-0.376441 -0.498093 0.220531 +0.508925 -0.32517 0.352425 +0.419334 0.0522122 0.500184 +-0.513258 -0.132065 0.388807 +0.506051 0.354572 -0.354276 +0.508415 -0.28378 0.194456 +-0.129719 -0.50238 0.0674791 +-0.509423 0.101175 0.299977 +0.356571 0.496521 -0.0626822 +-0.122238 0.507579 -0.353068 +-0.28295 0.509952 0.403822 +-0.299738 0.511306 0.427376 +0.257826 0.498698 -0.433102 +-0.361595 0.0561925 -0.513503 +-0.374514 -0.255346 -0.510803 +-0.497072 -0.384364 -0.291127 +-0.353911 -0.0543684 -0.511565 +-0.356338 0.220465 -0.498435 +0.491735 0.239681 0.430717 +0.501453 -0.362293 -0.198343 +0.407611 -0.0375049 -0.501424 +0.323903 0.0544111 -0.500885 +-0.50282 0.076916 -0.354627 +0.241551 0.375286 -0.512576 +0.0784178 0.431071 -0.498371 +0.186606 -0.312144 -0.504114 +0.00462675 0.513463 -0.366767 +-0.290036 -0.507806 -0.1207 +0.198986 -0.391277 -0.510329 +0.262313 0.510329 -0.364633 +0.498214 0.23671 0.385754 +0.121234 0.513462 -0.372622 +0.496523 0.279743 0.40296 +-0.167006 0.506901 0.401652 +-0.466733 -0.475328 0.466697 +-0.0692496 -0.498283 -0.41716 +0.150435 0.500147 0.280103 +0.0508637 0.499522 0.127757 +-0.085264 0.303739 -0.497287 +-0.0988902 0.333398 -0.503278 +0.157482 0.28578 -0.494304 +0.453319 0.494224 -0.177755 +-0.349115 -0.504338 0.225545 +0.452947 0.315872 0.492648 +-0.0792462 0.190701 -0.505158 +-0.0959438 0.390866 -0.496378 +0.350816 -0.508004 -0.0637243 +0.377276 -0.507975 -0.054571 +-0.350931 -0.211483 -0.498894 +-0.0394934 0.509301 0.413632 +0.347754 0.518156 -0.359102 +-0.107399 0.417825 0.503022 +0.304604 0.500476 0.263458 +0.163125 0.501441 0.340233 +0.365678 0.503464 0.132535 +0.395444 0.506761 -0.124356 +0.510745 0.397182 0.242204 +-0.39656 -0.47873 0.466738 +0.398499 -0.505877 0.362293 +-0.435175 -0.00644067 -0.497732 +0.510366 0.254923 -0.0698744 +-0.399483 -0.507949 0.349548 +-0.161345 0.498167 0.0552714 +-0.493908 0.412257 0.38658 +-0.49722 0.407777 -0.214376 +-0.498915 -0.285068 -0.0137039 +-0.368457 0.457726 0.488045 +0.29616 0.504235 0.0520809 +-0.509543 -0.305802 -0.422671 +-0.135075 0.457311 -0.491915 +0.491873 0.193846 0.404482 +-0.353373 -0.513171 0.139359 +0.396335 -0.337063 -0.508366 +0.45704 0.467045 0.469633 +-0.364006 -0.143038 -0.504277 +0.461892 -0.479914 -0.0583538 +-0.499518 -0.0152554 -0.429329 +-0.457629 0.467851 0.45455 +0.511935 0.0855908 -0.363309 +-0.015315 0.509135 -0.38202 +0.274379 0.51121 -0.0369229 +-0.107081 0.432794 -0.504824 +0.229172 0.49648 -0.0260922 +0.497739 0.369047 0.161022 +-0.400655 -0.0308557 -0.494597 +-0.503203 0.289622 -0.441392 +-0.377279 0.512899 -0.221777 +0.470121 -0.46804 0.472684 +0.498561 -0.348059 0.402997 +-0.266104 0.502657 0.381322 +0.289553 0.343318 -0.507351 +0.509786 0.146771 0.217466 +0.0504273 0.50967 0.389199 +-0.463253 0.239748 0.494587 +-0.487842 0.381191 -0.476391 +0.490061 0.27197 0.426012 +-0.494082 0.266486 -0.429969 +-0.195843 -0.503327 0.381545 +-0.201337 0.506819 0.394578 +-0.0327119 0.508241 -0.0995204 +0.0324077 -0.218571 -0.510026 +-0.482844 -0.467995 -0.377071 +-0.508444 0.0166795 0.256253 +0.126977 -0.501281 0.280014 +0.165608 0.49663 -0.361152 +-0.313168 -0.504758 0.357503 +0.431967 0.476588 0.473703 +0.505845 0.336948 -0.131871 +0.229054 0.50225 0.261689 +-0.178973 -0.504289 0.303385 +-0.230636 0.495363 -0.0967162 +-0.492019 0.0853994 -0.441676 +0.480142 -0.461699 0.401477 +-0.244922 0.5023 0.101107 +-0.00701702 -0.504917 0.320227 +0.469649 -0.476417 -0.0122012 +0.412506 0.497022 0.114869 +-0.500873 0.328428 -0.0524091 +0.139367 -0.214692 0.495107 +-0.495922 0.416865 -0.143049 +0.0371125 -0.338751 0.506101 +0.194454 0.374311 0.509604 +0.113298 0.0350137 0.495803 +0.500824 0.26324 -0.243624 +-0.346562 0.508945 -0.233398 +0.188248 0.498248 -0.260824 +-0.0417355 0.500218 0.278718 +-0.241036 -0.511338 -0.373496 +-0.330028 0.508771 -0.0690599 +-0.518303 0.324865 0.39429 +-0.125245 -0.504931 -0.411078 +-0.211318 0.503123 0.0931688 +-0.122557 -0.501955 0.236217 +-0.0200276 0.504526 -0.327324 +-0.387127 -0.375608 -0.50007 +0.270515 -0.50508 0.212785 +0.386311 -0.513973 -0.307158 +-0.498964 -0.446609 -0.361398 +-0.262124 0.135083 -0.493979 +-0.466896 -0.442306 0.466455 +-0.161051 -0.501956 -0.353556 +-0.466893 0.200224 -0.482607 +-0.501638 -0.210806 0.129433 +-0.31468 0.462997 0.490164 +-0.493356 0.465367 0.33123 +-0.474615 -0.460055 -0.221128 +-0.513773 -0.382464 -0.0440984 +-0.494433 -0.20239 0.186703 +-0.498693 -0.231418 0.175863 +-0.447764 0.321207 -0.490603 +-0.504636 -0.394999 -0.227966 +0.354899 -0.514221 0.168281 +0.301647 -0.185196 0.512339 +0.430558 0.451463 -0.491663 +-0.100984 0.495744 -0.0537774 +-0.230184 -0.507027 0.341412 +0.388348 -0.239557 -0.49907 +-0.346785 -0.509935 -0.198814 +0.476835 0.464798 -0.140195 +0.513004 0.308586 0.396829 +-0.118841 0.502882 -0.0276163 +-0.332925 0.513439 0.108777 +-0.106253 0.503917 0.327791 +0.500055 -0.349158 -0.171099 +0.0789442 -0.49895 0.241247 +0.0490991 -0.50294 0.255846 +-0.405155 -0.509324 0.127255 +0.420114 -0.0557219 -0.493231 +0.497137 0.226218 -0.162139 +0.518693 0.352898 0.314199 +0.220748 -0.485572 -0.456282 +-0.506515 0.0165253 -0.301694 +0.472621 0.456981 -0.466823 +-0.212888 0.510211 0.0110635 +0.494218 0.136986 0.0570617 +0.501636 0.31085 -0.231084 +-0.284898 0.356745 0.498976 +0.410425 0.497925 0.246248 +-0.355998 0.508624 0.333746 +-0.222348 0.499632 -0.0707468 +0.0652895 0.499446 -0.0155165 +0.3171 -0.495725 0.0442607 +-0.0822301 -0.497587 0.166004 +0.437017 -0.139031 -0.492672 +-0.513914 -0.0553841 -0.371831 +-0.452134 0.379373 -0.496917 +0.00626206 -0.318247 0.513742 +0.497339 -0.344979 -0.219835 +-0.50159 0.0559668 -0.402565 +0.499543 0.373819 0.103436 +0.0826275 -0.511211 -0.292456 +0.089208 -0.496681 -0.32533 +0.112673 0.159834 0.491927 +-0.479738 0.244437 0.467206 +0.0949935 0.176378 0.496336 +0.431744 0.498961 0.229497 +0.0598788 0.230174 0.509295 +0.0673612 0.261452 0.495918 +-0.479914 -0.460424 -0.462345 +-0.504697 0.302984 0.340897 +-0.499504 -0.0487516 0.376941 +0.0700035 0.406206 -0.495078 +-0.509101 0.0863784 0.253126 +0.0606915 0.382991 -0.505412 +0.491209 0.324813 0.435275 +-0.499617 0.258841 -0.372674 +0.495999 0.457064 -0.382384 +-0.081462 0.496853 -0.287092 +-0.0861862 -0.502008 0.346596 +-0.502254 0.0631835 0.324595 +0.371467 -0.509348 -0.213548 +0.511703 0.132211 0.339846 +0.451661 -0.491146 -0.0693436 +0.157789 0.312873 -0.494776 +0.0736673 -0.336442 -0.500217 +-0.0378784 0.352628 0.50389 +-0.267467 -0.50768 -0.110802 +0.272216 -0.497099 0.0501377 +-0.0697181 0.499386 0.022345 +-0.0946568 -0.49532 0.241625 +-0.504941 0.233382 0.297161 +-0.503261 0.259113 0.274077 +-0.495784 0.0824493 0.0884287 +0.469158 0.479769 -0.15799 +-0.323199 -0.200564 -0.509644 +-0.11398 -0.505021 0.26444 +0.493451 0.237002 0.0649826 +0.502997 0.208257 0.0550538 +-0.513277 0.324195 0.207209 +0.515246 0.283247 0.377175 +0.510295 -0.0753759 0.27422 +0.280434 0.499346 -0.339738 +-0.366866 0.294715 0.49797 +0.320787 0.510145 -0.0615488 +-0.169803 -0.50282 0.252639 +-0.496228 -0.292572 -0.106396 +0.0368386 0.336069 0.514221 +0.231529 0.463254 0.479916 +0.382732 0.500888 0.105085 +-0.14028 0.495171 0.196575 +0.506498 0.0263179 -0.0972221 +-0.234732 0.153012 0.510126 +-0.243861 0.126585 0.493271 +0.0927315 0.495787 0.00809219 +-0.0234196 0.490734 0.0936242 +-0.506521 -0.344912 0.290645 +-0.22942 0.507132 0.268952 +-0.0158064 -0.511262 -0.391721 +0.0767868 -0.505508 0.272872 +0.00815185 -0.49927 0.367765 +-0.0664202 0.331186 -0.495671 +-0.114281 0.363778 -0.497399 +-0.203727 0.15766 0.500839 +0.497316 0.1673 -0.0807291 +0.504028 0.178014 -0.132856 +0.496168 0.216953 -0.108007 +-0.477651 -0.45815 0.161519 +-0.511473 -0.091903 0.396989 +0.452748 -0.499278 -0.12164 +-0.0234735 -0.332024 0.513044 +0.51083 -0.0461175 0.34869 +-0.511995 0.0741974 0.351071 +-0.385471 0.0668716 0.514089 +0.504972 -0.0801782 0.116594 +-0.510505 -0.342479 -0.25591 +-0.294025 0.504718 -0.146169 +-0.398087 -0.514353 0.276497 +-0.389752 -0.507745 0.247913 +-0.508069 0.422638 0.422565 +-0.494946 -0.207468 0.157802 +-0.486867 -0.370606 -0.479783 +0.0540012 0.442486 0.501032 +-0.497365 0.27503 -0.0493679 +-0.477882 0.0384307 -0.455996 +0.0764719 -0.0119528 0.492243 +0.467662 -0.452747 0.467938 +-0.0236265 -0.285965 -0.501629 +0.485114 0.285849 -0.476171 +0.146457 0.12941 0.49183 +0.358976 0.013615 -0.497407 +-0.491896 -0.127901 0.261154 +0.197234 -0.493827 -0.189921 +-0.343903 -0.216428 0.50056 +-0.0811629 -0.501583 0.220547 +-0.0528761 -0.332433 -0.506798 +-0.0141544 -0.347455 -0.514425 +-0.40615 0.383575 -0.510442 +-0.246561 0.309177 0.508892 +0.458367 0.475548 -0.470222 +-0.467281 -0.0762531 -0.486882 +-0.511412 0.351998 0.386629 +0.418732 -0.295312 -0.507231 +-0.503668 -0.188664 0.0837569 +0.0655347 0.0170776 0.5008 +-0.279661 -0.504345 -0.27661 +0.0437138 0.276469 -0.499336 +-0.32235 -0.261554 0.498939 +0.0216298 0.496526 0.0220569 +-0.443918 -0.503451 0.266519 +0.459024 -0.475915 0.0107994 +-0.318405 -0.444448 0.497414 +0.312276 0.150216 -0.511128 +-0.347948 -0.269409 0.515575 +0.00432694 -0.510311 0.399983 +0.23513 -0.507959 -0.118503 +-0.251936 -0.308846 -0.515832 +-0.0886175 0.496644 -0.318986 +-0.0408546 0.169192 0.496078 +-0.391471 0.426941 0.506355 +0.359577 0.154584 0.500361 +0.311862 0.0828694 -0.502285 +0.352505 0.0463455 -0.511612 +-0.309903 -0.12229 -0.5028 +-0.508887 -0.34842 0.211692 +-0.498438 0.209761 -0.220848 +-0.469972 0.457153 -0.43966 +0.274942 -0.485471 0.467 +-0.495065 0.206735 -0.198999 +-0.331275 0.260072 0.511344 +-0.177454 -0.480189 -0.467384 +-0.25056 0.341965 0.498221 +0.41707 -0.497078 0.013382 +-0.227862 0.428698 -0.490763 +-0.506772 -0.241597 0.0903982 +0.162367 -0.40394 0.509874 +0.158018 -0.50411 0.32288 +0.189979 -0.495645 0.280568 +0.158128 -0.511239 0.277289 +-0.189749 0.399378 -0.510041 +-0.177094 0.376841 -0.497328 +-0.209332 0.339801 -0.495947 +0.34715 -0.20424 0.502414 +0.314559 -0.245962 0.51463 +0.0263778 -0.151487 -0.507326 +0.457198 -0.479489 0.286666 +-0.239485 -0.50721 -0.101554 +0.264175 -0.509983 0.188075 +0.469221 -0.474137 0.347212 +-0.200431 -0.492748 -0.174615 +-0.29885 0.330374 -0.512406 +0.407125 -0.334544 0.506868 +0.397168 -0.364193 0.507995 +0.272714 -0.0415491 -0.502972 +-0.332361 0.281349 -0.518366 +0.472942 0.464097 -0.24921 +-0.513318 -0.0323707 -0.384076 +-0.490158 -0.156414 -0.0946257 +0.400613 -0.497394 0.456165 +-0.498758 0.377511 0.112161 +-0.50528 -0.0687386 -0.211307 +0.473604 -0.193239 -0.466733 +-0.495597 -0.129273 -0.232848 +-0.291439 -0.495025 0.0227188 +-0.49659 -0.154603 -0.0354937 +-0.0519244 0.490836 0.210173 +-0.402766 -0.511517 -0.413627 +-0.505565 -0.13235 -0.105925 +-0.492202 0.428451 -0.399714 +-0.473057 -0.469147 -0.472681 +-0.477974 -0.455328 0.463307 +-0.0724748 -0.219013 -0.495402 +0.165065 0.48299 0.474059 +0.494207 0.143602 0.46066 +-0.020288 -0.207155 -0.494425 +0.438011 0.23382 -0.502331 +-0.493096 -0.12835 -0.0494443 +0.217843 -0.492794 -0.25142 +-0.129822 -0.505188 -0.269238 +0.0976565 -0.498928 0.0846915 +0.426173 -0.492899 -0.111961 +0.405278 -0.500685 -0.171463 +-0.336592 -0.37002 -0.499913 +-0.357484 -0.408919 -0.512792 +-0.11634 -0.332219 0.512131 +0.514625 -0.324904 -0.420824 +0.517917 -0.265529 -0.339788 +-0.5069 0.202261 0.204463 +-0.494726 -0.269468 0.243882 +0.506063 0.0877241 -0.0435619 +0.266134 -0.511564 -0.194089 +-0.372813 -0.195506 -0.511122 +0.41672 0.209563 -0.49301 +-0.497168 -0.269871 -0.124468 +0.196477 0.204581 0.508175 +0.226294 0.203436 0.499656 +-0.259174 0.14494 0.496845 +-0.458899 -0.49561 -0.280464 +-0.418835 -0.0177665 0.495096 +-0.384779 -0.0628368 0.504001 +-0.390936 0.259433 -0.512746 +0.45385 0.00635432 -0.496728 +0.504004 0.172937 0.0451619 +0.505427 0.411383 0.222336 +0.498093 0.452019 0.250192 +0.508064 -0.164126 0.152395 +-0.503475 -0.328602 0.100428 +-0.102026 0.492223 0.249604 +-0.154312 0.137903 0.508819 +-0.497429 -0.345263 0.15422 +0.158196 -0.446672 0.492782 +-0.306946 -0.218403 -0.498558 +-0.275189 -0.286555 -0.505469 +-0.364699 0.323562 0.50929 +-0.508088 -0.0875654 0.429357 +0.486732 -0.000446275 0.45241 +-0.415045 -0.501709 0.173932 +-0.483047 -0.146269 0.477622 +0.151011 0.180669 0.492531 +-0.50458 0.404834 0.101662 +-0.502405 0.432165 0.152124 +-0.492987 0.418422 0.124769 +-0.498823 -0.183025 -0.22154 +-0.509143 -0.215498 -0.229034 +-0.498691 -0.106252 -0.250779 +-0.49838 -0.192286 -0.25369 +-0.112781 0.501306 -0.32986 +0.505184 -0.413901 0.390091 +-0.491515 -0.379043 -0.441971 +0.072737 -0.383047 0.506939 +-0.306909 0.501634 0.361475 +-0.2124 -0.162716 -0.508301 +-0.169993 -0.169272 -0.498704 +0.514815 0.304519 -0.378476 +0.511334 0.34103 -0.331072 +0.447562 0.486769 -0.141481 +-0.460685 -0.123214 -0.489835 +0.185163 0.427255 0.487892 +0.388086 0.211874 -0.503294 +0.483661 0.16871 0.469251 +-0.0873528 0.178827 0.491939 +0.385109 0.156634 -0.513716 +-0.513265 -0.177967 -0.406761 +0.501565 -0.110412 0.0429362 +-0.489734 -0.248066 -0.457627 +-0.472809 -0.485744 -0.175485 +0.460041 0.496942 -0.0883635 +0.472541 -0.194073 0.464146 +-0.505776 -0.249481 -0.439145 +-0.200354 -0.497689 0.329101 +-0.199982 0.343342 0.508255 +0.507292 0.123316 0.313497 +0.498722 0.201205 -0.289302 +0.491346 -0.223042 -0.162447 +0.501285 -0.241986 -0.140711 +0.0606688 -0.502434 0.159243 +-0.472057 0.325948 0.475065 +-0.502367 0.241179 -0.449031 +0.495605 -0.129621 0.0835068 +-0.501944 -0.225365 0.20649 +0.48162 -0.255134 0.467963 +0.445291 -0.422169 -0.489362 +-0.501853 -0.176752 0.276606 +-0.49115 -0.467358 0.31384 +-0.499186 -0.16649 0.302157 +-0.178722 -0.264883 -0.49269 +-0.460417 0.479057 0.144275 +-0.255347 0.103911 0.49231 +0.389867 -0.474359 -0.464663 +0.356866 -0.508492 0.0157508 +0.506213 -0.0536119 0.170448 +-0.0642113 -0.493422 0.0340411 +0.50544 0.2748 -0.195379 +-0.326083 -0.256018 -0.512941 +0.304941 0.0444245 0.509024 +0.497941 0.246481 -0.292693 +-0.476158 -0.168715 0.478529 +0.131764 0.487378 -0.469842 +0.0926226 0.493419 -0.110172 +0.245142 0.0281594 -0.504175 +-0.512513 -0.0880306 -0.359146 +0.478484 -0.43091 -0.478396 +0.340289 0.0432194 0.500538 +0.387039 0.0281084 0.496655 +-0.101926 0.50816 0.00512465 +0.511527 -0.0187949 -0.33817 +-0.501 0.433185 -0.03043 +0.114316 0.495832 0.207223 +-0.055686 -0.508718 -0.363961 +-0.00579505 -0.497103 -0.337964 +-0.51516 -0.350612 0.374697 +-0.500573 -0.364517 -0.374241 +-0.00303394 0.499869 -0.139116 +0.416265 -0.500232 -0.296664 +0.285325 -0.517853 -0.355671 +0.0732953 -0.505607 0.080185 +0.497198 0.431281 0.316599 +0.0760548 0.342551 0.499829 +0.0365127 0.278354 0.510324 +-0.348243 0.235873 0.504065 +-0.432159 0.504945 0.216018 +-0.276399 -0.512574 -0.355435 +-0.36838 -0.511524 -0.348399 +-0.509384 0.354377 -0.298903 +-0.333539 -0.510107 -0.306858 +-0.438644 0.469379 0.473778 +-0.363355 -0.513246 -0.317284 +0.0846642 -0.49483 0.179069 +0.185573 -0.495079 -0.29213 +0.133044 -0.506544 0.152766 +0.508064 -0.0502524 0.0357212 +0.508663 -0.0514375 0.0998542 +0.504544 -0.0213983 0.0864946 +-0.393625 -0.343069 -0.501942 +-0.314382 -0.0279209 0.496262 +-0.373881 -0.0379732 0.508571 +-0.283832 0.147358 0.493003 +-0.34035 0.0449152 0.512487 +-0.327426 0.170021 0.514052 +-0.332425 0.212113 0.509063 +0.129361 -0.50913 -0.22197 +-0.510441 0.368622 -0.408065 +-0.506452 -0.231673 0.00549911 +0.166065 -0.498964 -0.0736511 +-0.223353 -0.0217606 -0.492887 +0.136522 -0.503944 -0.0732114 +0.149785 -0.494787 -0.0974367 +0.0625942 0.296303 0.50291 +0.323692 -0.518446 -0.352285 +-0.0882905 -0.494549 0.408124 +-0.297591 0.301382 0.514363 +0.290485 -0.292053 0.513443 +0.352818 0.409954 -0.510281 +0.374385 0.503748 -0.4084 +0.0323905 -0.449828 -0.486142 +0.349218 0.439089 -0.492818 +0.0238064 0.506754 -0.416387 +0.478852 -0.0634477 0.453955 +-0.503756 -0.0285109 0.222388 +-0.00191144 0.5041 -0.436101 +0.514016 0.353104 -0.407991 +-0.236566 -0.242693 0.504421 +0.417877 0.504676 -0.423978 +-0.299905 -0.506228 -0.142316 +0.148245 -0.193378 0.504598 +0.195508 0.0970344 0.508065 +0.281288 0.20709 0.499458 +0.254039 0.203167 0.507613 +-0.277349 -0.508168 -0.0424632 +0.375137 -0.485863 -0.458447 +0.0524311 -0.390818 0.504151 +0.505585 0.211675 0.207691 +-0.0198806 -0.402529 0.494308 +0.00276749 -0.38519 0.499023 +0.494229 0.0856818 -0.0127181 +0.493595 0.119145 -0.0853003 +-0.41356 0.251659 -0.514939 +-0.499544 -0.0402019 0.145344 +-0.428315 -0.0471256 0.501035 +0.507155 0.424446 0.13865 +0.454282 0.493663 -0.0657734 +0.50481 -0.120749 -0.323311 +-0.18848 0.270375 -0.507793 +-0.161822 0.330179 -0.50485 +-0.157721 0.274345 -0.511297 +0.492085 0.015894 0.0353255 +0.506494 0.232329 -0.429031 +0.508646 0.309501 -0.0832999 +-0.257915 -0.336113 0.500246 +-0.505099 0.0248725 0.371219 +-0.502887 0.247784 -0.141283 +-0.496375 -0.0726928 0.369748 +0.491371 0.173796 0.00642275 +-0.503194 -0.0241051 0.308383 +-0.509569 -0.0311862 0.359086 +-0.512238 0.0157329 0.342242 +0.471787 -0.470439 0.422066 +-0.0219734 -0.374337 -0.514795 +-0.068638 -0.430012 -0.501377 +-0.0769957 -0.38367 -0.497321 +-0.461599 0.476216 -0.0349651 +-0.0585733 -0.404562 -0.495281 +0.225728 -0.191021 0.507815 +0.370929 0.375981 -0.504386 +-0.497065 -0.19433 -0.169789 +-0.493122 -0.240836 -0.110889 +0.433388 0.499846 0.257801 +0.40191 0.181974 -0.499836 +-0.287349 0.0772254 0.504809 +-0.18568 0.0734693 0.494304 +-0.232759 0.0529959 0.495551 +-0.044531 -0.313203 0.499146 +0.101686 0.260647 0.507118 +0.134304 0.262636 0.51193 +0.0618192 -0.508587 0.40334 +0.480732 0.472212 0.42852 +0.277734 0.0464298 -0.494688 +-0.131393 -0.394828 -0.506288 +-0.0384138 -0.310428 -0.50235 +0.226772 0.399941 -0.498519 +0.165014 0.402944 -0.495615 +0.386671 -0.034251 -0.495324 +0.382302 0.234433 0.501713 +0.385514 0.00980669 -0.499359 +-0.469182 -0.477987 0.402365 +0.343495 0.33035 0.519211 +0.44742 0.185213 0.482389 +0.49812 -0.411619 -0.450466 +-0.225096 0.515254 -0.319519 +0.185447 0.246264 -0.505626 +0.203481 0.208089 -0.50902 +-0.0504921 -0.286778 -0.496794 +-0.0883295 -0.471917 -0.485774 +-0.511108 -0.155171 -0.314819 +-0.313068 0.505514 0.173587 +-0.450008 0.485342 0.0109693 +-0.0936785 -0.272387 -0.510565 +-0.0655314 -0.265541 -0.494663 +-0.48472 -0.460283 -0.0471444 +-0.459561 -0.147164 0.485062 +0.501168 -0.411434 -0.0563679 +0.475159 0.482533 0.406517 +0.50645 -0.196418 -0.228013 +-0.497549 0.322367 -0.158212 +0.281653 0.0755141 -0.508674 +-0.0651342 0.500963 -0.216783 +-0.510558 0.0563903 0.296622 +0.374465 -0.385035 -0.515881 +0.493697 -0.421903 0.067147 +0.501158 0.210905 0.33033 +-0.334733 -0.497973 0.118782 +0.482426 0.373565 0.462212 +0.497537 0.218627 -0.239558 +0.254599 -0.403349 -0.503541 +-0.500815 -0.0206427 0.0895477 +0.257366 0.40006 -0.509966 +0.494348 -0.387063 0.441708 +-0.0436638 -0.506494 -0.298945 +-0.190683 0.464327 0.488259 +-0.0403667 -0.500925 -0.383246 +0.456095 -0.485947 0.167066 +0.10552 -0.502536 -0.413153 +-0.409801 -0.377615 0.505724 +-0.494376 -0.0511464 0.0971602 +0.498357 -0.403736 -0.423557 +0.490604 0.118468 -0.186363 +0.498911 0.118292 -0.209196 +0.495354 0.139511 -0.195538 +0.44639 -0.487066 0.128057 +0.48931 0.168346 0.415579 +0.161359 -0.506041 0.162648 +0.506756 -0.047375 0.316693 +-0.0689524 -0.0633408 -0.506302 +0.323632 0.311689 0.512121 +0.270142 0.513614 0.341896 +-0.34328 -0.509128 0.401932 +-0.346637 -0.440839 -0.491773 +0.508104 -0.0303666 -0.367561 +-0.116621 0.257164 -0.502329 +0.474834 0.467516 -0.405302 +-0.117334 0.228752 -0.508472 +-0.109191 -0.462035 0.490481 +0.386326 -0.507797 0.210456 +-0.49396 -0.0150184 -0.0597907 +0.48043 -0.383354 -0.456833 +-0.0866082 0.22094 -0.494561 +0.472558 -0.473164 -0.463599 +-0.503635 0.0799651 -0.384793 +0.0276425 -0.402224 0.510394 +0.0724055 0.189092 -0.500464 +0.0692612 -0.258092 0.506893 +-0.129628 0.278505 -0.497174 +0.491228 0.112814 0.00467091 +0.501373 0.271626 -0.382229 +-0.0522082 -0.143168 -0.49902 +-0.0319896 -0.161415 -0.498434 +-0.0570496 -0.169521 -0.495663 +-0.355277 0.515402 -0.173667 +-0.424127 -0.504655 -0.403313 +-0.509018 0.291277 -0.334691 +0.508946 0.0396428 0.0933825 +0.501428 0.00677584 0.106789 +0.492486 0.0370457 0.159952 +-0.505396 0.0354482 0.110136 +0.248655 -0.495781 0.425121 +0.262057 -0.502182 0.450451 +0.32748 0.45533 0.488677 +-0.193302 -0.497246 -0.143826 +0.488689 -0.458706 0.358279 +0.475332 0.00571628 -0.484882 +0.50534 -0.123258 -0.248709 +0.504446 -0.215638 -0.381563 +0.174226 -0.15686 0.502547 +-0.497071 -0.208666 0.425235 +-0.398131 0.469445 0.486114 +0.478525 0.412816 -0.481596 +-0.50139 -0.0687663 -0.179494 +0.381275 -0.511398 0.335841 +-0.499175 -0.316644 0.160065 +0.501674 -0.274403 -0.171943 +0.485962 -0.447318 -0.049331 +0.511659 0.0243385 -0.262851 +-0.503596 -0.124288 0.0625537 +0.41739 -0.389767 0.496942 +-0.380568 -0.450582 0.487211 +-0.161048 -0.493735 -0.222606 +-0.251869 -0.505065 -0.15946 +-0.505227 -0.313489 0.0456971 +-0.124285 -0.268221 -0.494176 +-0.50464 0.21341 0.323613 +-0.493217 -0.413837 -0.0856248 +-0.164197 -0.284613 -0.494422 +-0.0976456 -0.358878 -0.495595 +-0.1568 -0.34011 -0.499009 +0.300057 -0.514426 0.267197 +0.496076 0.0189681 -0.238471 +-0.495725 -0.277556 -0.154224 +-0.0226231 -0.499096 -0.279787 +0.319514 -0.512936 0.340872 +-0.503815 0.409791 -0.0958136 +0.495216 0.200029 0.130569 +-0.425997 0.233123 -0.500352 +-0.443996 0.241933 -0.490618 +0.178901 0.376571 -0.513824 +-0.454454 0.269973 -0.499628 +-0.47322 -0.48413 0.306528 +-0.471926 -0.436396 -0.482991 +0.499289 -0.255915 0.118352 +-0.433228 0.468795 -0.470897 +0.512152 -0.265548 0.0725534 +0.510644 -0.29774 0.0771665 +0.317345 -0.315871 -0.510407 +0.336548 0.519112 -0.324699 +-0.378728 -0.508968 0.294238 +-0.387836 -0.514712 0.321638 +-0.411521 -0.498823 0.324053 +0.175776 0.297884 -0.507485 +0.244663 -0.0123873 0.501597 +0.174689 -0.0166377 0.504642 +-0.330768 -0.515594 0.303422 +0.180076 -0.412191 -0.511938 +-0.48388 0.251015 -0.480853 +-0.379844 0.013825 0.513609 +-0.122937 -0.29478 0.493378 +-0.221956 0.328471 0.496403 +-0.271213 0.0917721 -0.508271 +-0.288622 0.133391 -0.49768 +-0.312989 0.0374607 -0.498082 +-0.332855 -0.46122 0.478484 +-0.130747 -0.454643 0.499174 +0.512839 -0.333728 0.0838793 +-0.495548 0.436355 -0.24061 +-0.494554 0.427411 -0.215674 +-0.455553 -0.477085 -0.410732 +0.241303 0.0752598 0.499121 +0.258389 0.0172117 0.492545 +0.203354 0.0413728 0.506464 +0.432436 0.376358 0.490925 +0.260757 0.0660629 0.499968 +0.497359 0.286574 0.0621102 +0.496693 0.310448 0.0483812 +0.465103 0.0763668 0.474212 +-0.511665 -0.353627 0.122884 +-0.291856 -0.482705 0.451535 +-0.505258 0.128046 0.0445934 +0.503518 0.240066 0.0888342 +0.505419 -0.355203 -0.306612 +0.384764 0.485361 0.460995 +-0.49549 0.253873 0.0559785 +-0.491061 0.199394 0.0108215 +0.265115 -0.503136 0.401649 +-0.494707 0.249497 0.0284709 +0.0146278 -0.504642 -0.432428 +0.0424083 -0.500425 -0.388079 +0.493249 -0.182852 0.210567 +0.502015 -0.446083 0.399641 +0.0636965 -0.490578 -0.428219 +-0.501603 0.148723 -0.403564 +0.49304 -0.199038 0.0184961 +0.497573 -0.251213 -0.0559293 +-0.494181 0.189917 -0.437788 +-0.494281 0.218905 -0.411746 +-0.398892 -0.195284 -0.507416 +0.495686 -0.166117 0.446829 +0.420029 -0.375866 -0.495593 +-0.486156 -0.443612 0.0746036 +0.508066 0.113306 -0.34261 +0.100948 -0.174053 0.506794 +0.274954 0.497952 0.0596761 +-0.464385 -0.0138223 0.469935 +0.497644 -0.313767 -0.228424 +0.0292242 -0.498681 0.170827 +0.366784 0.479257 -0.464432 +-0.512778 -0.374487 0.0235289 +-0.0893253 0.0749022 0.500462 +-0.376657 0.429386 -0.491002 +0.483701 -0.120162 -0.465385 +-0.280431 0.240735 -0.512047 +0.142072 -0.346132 -0.5078 +-0.236057 -0.506857 0.206538 +-0.473892 -0.48758 -0.301379 +-0.490893 -0.368173 0.424964 +0.0858705 -0.366598 -0.513164 +0.514021 -0.374386 -0.384799 +-0.482994 -0.459223 0.136412 +0.500036 -0.318149 -0.39342 +-0.508465 0.298321 0.0874822 +-0.501096 -0.40027 0.0431823 +-0.485509 -0.460579 0.0906095 +0.511729 -0.0111376 -0.391324 +0.400497 -0.509486 -0.0454038 +-0.513989 -0.317902 -0.39725 +-0.417011 0.162267 -0.509771 +-0.499758 -0.212195 -0.0940684 +-0.498438 -0.175207 0.00312356 +0.104082 -0.422931 -0.506971 +-0.502676 -0.211954 -0.151301 +0.491137 -0.0562908 -0.121564 +-0.514974 -0.375521 -0.348958 +-0.121924 -0.51373 -0.378547 +-0.498485 0.327773 -0.404003 +0.211654 0.125001 0.508012 +0.502068 0.303003 -0.204562 +-0.49624 0.436387 0.0204303 +0.511517 0.326833 -0.165834 +-0.502401 -0.449401 0.176771 +-0.503311 -0.427377 0.133046 +-0.502607 -0.402288 0.190951 +-0.510627 -0.407991 -0.312085 +0.494405 -0.0725631 -0.145285 +0.481635 0.227793 0.452058 +-0.509717 -0.0245567 -0.355254 +0.496113 0.239463 -0.131632 +0.164797 0.154031 0.491587 +0.241727 -0.153169 -0.500584 +0.285182 -0.126881 -0.503666 +-0.492874 -0.176871 0.426103 +0.254451 -0.126638 -0.495831 +-0.487321 -0.438354 0.267773 +-0.513084 0.389639 0.301045 +0.501958 -0.348065 -0.332927 +0.468822 -0.486889 0.0844608 +0.020874 -0.501605 -0.235572 +0.111053 -0.509329 -0.205189 +-0.18889 0.371565 0.49956 +0.0269083 -0.512815 -0.295207 +0.0719587 -0.50906 -0.235665 +-0.0602856 -0.467745 -0.489372 +0.480143 -0.298477 0.460879 +0.507721 0.169928 0.383946 +-0.339529 0.146232 -0.511361 +-0.353071 0.0847134 -0.499452 +-0.400814 0.505236 0.371562 +-0.495912 0.412136 0.0240677 +-0.413182 -0.505634 0.0687755 +-0.473014 -0.346847 -0.481181 +0.35165 0.437448 0.490277 +-0.389073 -0.500937 0.0790028 +0.388277 0.44625 0.499389 +-0.369302 -0.514626 0.0621066 +-0.501032 -0.173621 -0.191342 +0.375333 -0.292329 -0.500703 +-0.0410981 0.509067 0.369549 +-0.505652 0.154129 -0.129171 +-0.302511 -0.461251 0.479683 +-0.5 -0.394664 0.302097 +0.101254 -0.503109 0.334352 +0.116804 -0.503781 0.375959 +-0.0704575 0.503749 -0.336466 +0.49833 0.0574805 0.000282479 +-0.495698 -0.133591 -0.294303 +-0.501466 -0.237544 0.117601 +0.0652303 -0.499177 0.372994 +0.0544928 -0.441021 0.498379 +0.37909 -0.413467 -0.503453 +-0.497968 -0.138976 0.037772 +0.501253 -0.111066 0.166963 +-0.393822 -0.501206 -0.0976235 +0.489238 0.410337 -0.449995 +-0.505897 0.0386758 -0.279721 +0.102145 -0.266524 -0.494755 +0.477894 0.398741 -0.462772 +-0.487913 -0.222488 -0.470455 +0.127781 -0.312997 -0.509092 +-0.325556 -0.500584 0.173846 +-0.233698 -0.146877 -0.50161 +-0.259197 -0.111266 -0.495899 +-0.499982 0.0309324 -0.247798 +0.294252 0.464676 0.492206 +-0.335525 0.498423 -0.40073 +0.114925 -0.470942 0.473324 +0.393772 0.502367 0.136244 +0.130507 -0.494487 -0.419321 +-0.496571 0.353542 0.159497 +-0.494581 -0.0959122 -0.192341 +0.108751 -0.454168 0.48644 +-0.210772 0.490328 0.440868 +-0.505108 -0.262822 0.131953 +-0.506864 -0.0500956 -0.237704 +0.506128 -0.294087 -0.159719 +0.493664 -0.263849 -0.0870145 +-0.0379708 -0.463528 -0.493789 +-0.0251144 -0.442035 -0.486812 +0.0713277 0.494497 0.170788 +-0.500707 -0.131903 -0.156641 +-0.0369156 0.194294 0.503612 +-0.00712835 -0.421987 -0.502719 +-0.461389 -0.478675 -0.334277 +-0.464477 0.470895 0.334698 +-0.423044 0.299158 0.509885 +-0.3505 -0.514821 -0.398298 +-0.326597 -0.499108 -0.415033 +-0.484216 0.447122 0.30381 +-0.457862 0.489152 0.307753 +0.509037 0.167589 0.0988368 +0.372683 0.00711979 0.501581 +0.0665111 0.50097 -0.345158 +-0.494348 0.207577 0.126226 +0.504425 0.153983 0.154276 +-0.242018 -0.355705 -0.499101 +-0.498746 0.274147 -0.183594 +0.498368 -0.102451 0.345796 +0.418956 0.502342 0.390475 +-0.135179 -0.318511 -0.503901 +-0.0276931 0.204294 -0.493716 +-0.243038 -0.276352 -0.511192 +-0.489377 0.323608 -0.474654 +-0.186742 -0.326934 -0.502284 +0.00261246 0.349768 -0.504982 +0.505484 -0.164349 -0.260562 +0.107171 -0.490205 -0.0766585 +-0.502207 -0.426906 -0.334349 +-0.453452 -0.469255 0.472092 +0.135378 -0.487711 -0.441095 +0.239188 0.512917 0.378668 +0.301292 0.480138 -0.459232 +0.486922 -0.470425 -0.117897 +0.283436 0.476893 0.47037 +0.500522 0.180789 -0.414963 +0.478017 0.242807 -0.486325 +0.503526 0.294142 0.213422 +0.258477 -0.496851 -0.0968609 +-0.197673 0.489913 -0.439817 +0.290636 -0.262016 0.505925 +0.364362 0.103879 -0.514802 +0.260877 -0.226743 0.49717 +0.510452 -0.128789 -0.293831 +-0.0779271 -0.176995 -0.494856 +-0.498176 -0.0614367 -0.150855 +-0.206349 -0.397855 0.507768 +-0.50311 -0.322638 0.0201947 +-0.469246 -0.486584 -0.38601 +-0.0428687 0.486397 -0.471347 +-0.210182 -0.355542 0.496488 +0.311266 -0.0813131 0.498762 +-0.317803 -0.494426 -0.46487 +0.254104 -0.0662496 0.508127 +-0.156985 -0.41417 0.49419 +-0.502667 -0.206134 0.38269 +-0.503276 -0.219635 0.36102 +-0.337457 -0.112748 0.51273 +-0.378803 -0.131036 0.502755 +-0.135306 -0.239523 -0.509241 +-0.195526 -0.238127 -0.501242 +-0.237368 0.473483 0.48109 +-0.256266 -0.254413 0.509846 +-0.0352998 0.326352 -0.508458 +-0.0115156 0.2586 -0.501435 +-0.0468517 0.416625 -0.496599 +-0.043153 0.267851 -0.494601 +0.274073 -0.432334 0.49892 +0.268478 -0.249508 0.508975 +0.197927 -0.179934 0.497645 +0.0641292 -0.504103 0.0524984 +0.485781 0.446895 -0.259796 +-0.448371 0.0277353 0.490561 +-0.509527 0.37647 0.433511 +0.487951 -0.443057 -0.025927 +-0.504385 0.225691 0.0452147 +-0.50268 0.319129 0.114573 +-0.323081 0.344291 -0.51525 +0.492564 -0.120925 0.244413 +-0.497544 0.392782 0.410379 +0.50365 -0.00214382 -0.260687 +-0.492523 -0.425174 0.198503 +0.502458 -0.393746 0.0643569 +0.500877 -0.123931 0.014887 +0.372027 -0.353447 -0.518878 +0.255077 -0.503136 -0.0260753 +0.0652869 0.217464 -0.508557 +0.30973 -0.500215 -0.0166739 +0.483797 -0.22025 -0.459664 +0.401802 -0.140534 0.499049 +0.498686 0.398216 0.195964 +0.0900121 -0.509915 0.418987 +-0.508893 0.216991 -0.0553251 +0.0552168 0.0457512 0.490211 +0.507461 0.312343 0.0209784 +0.500314 0.261988 -0.0102437 +0.497414 0.262437 0.0770312 +0.510256 0.312743 -0.0043595 +-0.514439 -0.236153 -0.322989 +-0.496194 0.0481201 -0.340966 +-0.345062 -0.476495 0.465629 +0.122327 -0.501939 -0.0133257 +-0.505289 0.270336 0.333544 +-0.358514 -0.495542 0.450024 +-0.43067 -0.304321 -0.502498 +0.505255 -0.364689 -0.147063 +-0.495073 0.144009 0.106881 +0.195402 0.514297 0.377523 +0.496542 0.382267 0.431595 +0.498988 0.164667 -0.248137 +-0.137806 -0.491365 -0.119974 +0.387696 0.269018 0.514718 +0.41473 0.280136 0.503498 +0.0845835 -0.500148 0.105027 +-0.49861 -0.0634968 0.147601 +-0.189776 -0.500152 -0.226913 +-0.218586 -0.494076 -0.231904 +-0.26009 -0.501965 -0.253593 +-0.513015 0.277908 -0.315108 +0.190287 -0.501259 0.0818458 +0.113148 -0.501599 -0.433626 +-0.490459 0.195083 -0.065213 +0.332287 -0.493432 -0.455335 +-0.357658 0.120625 0.508126 +-0.41646 -0.490074 -0.115455 +-0.344114 -0.111093 -0.498424 +-0.495141 0.30465 -0.0428723 +-0.497778 0.228699 -0.202841 +-0.470892 0.483602 -0.431982 +-0.508459 0.177528 -0.109859 +0.503383 0.0815848 0.329872 +0.493762 0.0518394 0.028949 +0.505894 -0.156137 0.312085 +0.512366 -0.207481 0.366508 +0.349849 -0.491109 -0.469189 +0.379622 -0.49779 -0.133609 +0.0269564 -0.495258 -0.0882346 +-0.491824 -0.180425 -0.0489517 +-0.491685 -0.177876 -0.0226398 +0.41999 0.0867247 -0.501787 +0.151532 0.297414 0.503745 +0.449324 0.056451 -0.483891 +0.437826 0.098488 -0.495286 +-0.495232 -0.00604451 -0.384184 +0.504975 0.0332467 0.0105998 +0.422921 0.435644 0.500161 +-0.496732 -0.0790995 -0.431566 +0.359006 0.513986 0.220393 +-0.50101 -0.153332 -0.394141 +0.447819 -0.489331 0.352813 +-0.28838 0.198561 0.502405 +-0.492573 -0.0952923 -0.409091 +0.10464 0.380463 0.50091 +0.51485 -0.175414 -0.337662 +0.508893 0.337971 0.199068 +0.504595 0.347015 0.246284 +0.492623 0.103517 -0.163628 +-0.366163 -0.510366 0.0877023 +0.011113 0.506209 -0.259132 +-0.433009 0.139043 -0.491254 +-0.368926 -0.509046 -0.0268241 +-0.346338 -0.498723 0.0486663 +-0.444755 -0.488119 0.144902 +-0.0367563 -0.45888 0.48142 +0.218733 -0.514119 -0.383047 +0.329662 -0.502415 -0.313448 +-0.505863 -0.316701 0.383132 +0.181862 0.477225 -0.462993 +-0.46112 0.46774 -0.449265 +-0.067509 0.503197 0.410968 +0.510851 0.356892 -0.102995 +0.507541 -0.0312414 0.269858 +0.446974 -0.496836 0.058408 +0.153587 0.494072 0.147027 +0.183848 0.505216 0.142885 +-0.506301 0.273466 0.391715 +0.478878 -0.457907 0.1889 +0.495495 -0.208401 -0.134284 +-0.412379 -0.498636 -0.208837 +0.376323 0.500226 -0.432829 +-0.506798 0.291775 0.221158 +0.505251 0.077507 0.0492681 +-0.505327 -0.107011 -0.386393 +0.508897 -0.0726445 0.248012 +0.40782 0.508419 0.0655206 +0.494164 -0.0698091 0.22025 +0.494991 -0.036488 0.145684 +0.507606 -0.0964164 0.184788 +-0.505438 0.433956 0.0966804 +-0.447747 -0.479788 0.0713311 +-0.20463 -0.429128 -0.488598 +0.502308 -0.0354225 -0.180504 +0.143229 -0.495583 -0.2752 +0.497979 -0.424396 -0.261161 +0.288109 -0.324915 0.515909 +0.018013 -0.494582 0.272015 +-0.222423 -0.505218 0.275889 +-0.495224 -0.153081 -0.128425 +0.134773 0.497408 0.405956 +0.412649 -0.482666 -0.474912 +-0.508975 -0.402598 -0.196943 +0.175917 -0.0867915 0.490483 +-0.476684 -0.471195 0.441074 +-0.247846 -0.505393 -0.283244 +-0.171096 -0.497173 -0.249482 +-0.181365 -0.502621 -0.309959 +-0.148708 -0.512652 -0.295596 +-0.0612845 -0.504288 0.325516 +-0.476395 0.446149 0.470899 +0.0722785 0.495467 -0.0477334 +0.108996 -0.509969 0.226815 +0.0935712 -0.501108 0.361631 +0.4158 0.113404 -0.492164 +0.0978864 0.360383 -0.505021 +0.348621 -0.498854 -0.0938444 +0.279135 -0.508967 -0.0220896 +0.349721 -0.509674 0.121479 +0.32561 -0.50354 0.111807 +0.511665 0.365567 -0.243735 +0.0877882 0.452333 -0.495287 +0.123961 0.431589 -0.497446 +0.47152 0.484767 0.287911 +0.205474 -0.300753 0.500297 +-0.471854 -0.477717 -0.0564901 +0.22853 -0.352098 0.501329 +0.498859 0.314811 0.201737 +0.426143 0.501195 -0.165391 +-0.13935 -0.358987 0.511664 +0.502605 0.301142 0.422252 +0.431227 -0.490523 0.330744 +-0.156317 0.216084 0.503869 +0.453379 0.481679 -0.210134 +-0.175855 0.491648 -0.419887 +-0.205029 0.239689 0.497566 +-0.200537 0.211358 0.506888 +0.28873 -0.500328 0.00546794 +0.372296 -0.509801 -0.0107733 +-0.385967 -0.367188 0.515167 +-0.0691056 0.506652 -0.0509191 +-0.503664 0.409125 -0.311392 +-0.497345 0.401086 -0.283781 +0.124732 -0.273793 0.508908 +0.0833372 -0.313447 0.507842 +-0.459356 0.473004 0.43876 +-0.49676 -0.0737752 0.076242 +0.198787 -0.22012 -0.507206 +0.0807392 -0.241666 -0.510612 +-0.474524 0.462365 0.35893 +0.150196 -0.235411 -0.496591 +-0.447112 -0.418376 -0.49871 +-0.506394 0.415956 0.0730864 +-0.482565 -0.472808 -0.248496 +0.179188 -0.241141 -0.501935 +0.497222 0.348844 -0.0500864 +0.500331 -0.0457497 -0.415927 +0.506951 -0.172477 -0.234145 +-0.48639 0.453412 -0.322067 +0.492829 -0.210715 0.119581 +-0.50934 -0.174315 -0.344924 +0.386093 -0.39516 0.511619 +0.495284 0.235457 0.230299 +0.403545 0.374136 -0.502541 +-0.49713 0.305616 0.163762 +0.476385 -0.464019 0.132757 +-0.5089 0.223042 0.402436 +-0.0156228 0.171105 -0.508914 +-0.512083 0.365037 0.306079 +0.502951 0.139607 -0.394865 +0.510544 0.379527 0.0464054 +-0.00373798 0.498382 -0.188492 +0.12406 -0.137363 -0.506036 +0.511875 0.351989 0.0837877 +0.498146 0.290738 0.0922503 +0.504056 0.31166 0.116289 +0.514418 0.330877 0.0645532 +-0.507545 0.339562 -0.134562 +-0.502275 0.376729 -0.156589 +-0.512583 0.401678 0.0487922 +-0.51003 0.351008 0.0974988 +0.406988 -0.422458 -0.503005 +-0.508891 0.372218 0.0444027 +-0.507281 0.267569 -0.341102 +0.498053 0.160634 -0.180251 +0.186002 0.494455 -0.184702 +0.505301 0.00645326 0.302045 +-0.278688 -0.513905 0.310111 +-0.492957 -0.0868182 -0.266175 +-0.508845 -0.133761 -0.263051 +-0.406999 -0.512349 0.224318 +-0.139018 -0.503991 0.186921 +-0.088812 0.340431 0.508141 +0.0363186 0.377115 -0.497465 +0.0442584 0.331783 -0.496996 +-0.510777 -0.112031 -0.335469 +0.496759 -0.140808 0.0412256 +0.511015 -0.101473 0.315523 +0.0554316 -0.166601 -0.504608 +-0.451872 0.480962 -0.46524 +0.10738 -0.499161 -0.307697 +0.496695 -0.438546 0.371057 +0.499566 -0.124393 0.270691 +-0.446727 -0.369784 0.486667 +0.141373 -0.495826 0.104539 +-0.28076 -0.505925 -0.165058 +-0.303715 -0.507701 -0.219284 +0.348075 0.128201 0.50118 +0.382638 0.0753796 0.500142 +0.395773 0.10061 0.493109 +0.226978 0.496818 -0.212511 +0.489358 -0.155908 -0.162716 +0.496282 0.453687 0.384766 +0.513364 0.385672 0.407622 +-0.505153 -0.171782 0.333111 +-0.494018 -0.187095 0.24692 +0.10877 0.485751 0.441461 +0.490698 0.176105 0.141971 +0.508986 0.089578 -0.423145 +0.500104 0.0016782 -0.363678 +0.513979 0.0608479 -0.351725 +0.512807 0.0866654 -0.3939 +-0.306926 -0.513622 0.124464 +-0.277233 -0.50451 0.130522 +-0.447509 0.402571 -0.483139 +-0.301453 -0.496025 0.153732 +0.341803 -0.23419 0.503787 +0.424943 -0.154647 0.497763 +0.508506 -0.073215 0.191586 +0.492337 -0.148598 0.205797 +0.504127 -0.184122 0.382274 +0.434844 0.328867 -0.495127 +-0.450745 0.0885726 -0.493904 +-0.50512 0.189254 -0.132285 +0.498936 0.0977785 0.402584 +0.101137 0.438962 -0.506309 +0.0600237 0.447867 -0.491304 +-0.51437 0.206448 -0.394576 +-0.500722 0.131272 -0.355944 +-0.510567 0.189597 -0.366422 +0.508376 0.151897 0.125016 +0.500146 0.120112 0.123724 +0.510503 -0.0905871 -0.331278 +-0.387557 -0.511054 -0.296138 +0.495515 0.442114 0.407953 +0.495301 -0.0521411 0.124824 +0.505135 -0.172564 0.181767 +0.163905 -0.208309 0.503221 +0.20537 -0.208491 0.49773 +-0.431498 0.107811 -0.503394 +0.11671 -0.371781 -0.513113 +0.182289 -0.25125 0.497833 +-0.512381 0.392064 -0.331372 +-0.477625 0.482398 -0.147924 +0.422861 0.510275 0.302354 +-0.507084 0.157818 0.237635 +0.208728 -0.237206 0.491972 +-0.505595 -0.337302 0.321124 +0.304659 0.288654 0.502867 +-0.0724112 0.488638 -0.474944 +-0.349996 0.337441 -0.508804 +-0.510475 -0.260069 0.345097 +-0.503044 -0.308584 0.329437 +0.497838 -0.104039 0.374882 +0.315689 0.504583 -0.226495 +0.503724 -0.100338 0.28686 +-0.42938 0.483105 0.444439 +0.513611 -0.183161 0.327554 +0.438455 0.0373128 0.495395 +0.498444 0.236489 -0.0505643 +0.503889 0.233291 0.00566522 +0.347791 -0.174895 0.504248 +-0.179193 0.127163 -0.507626 +-0.235269 0.132451 -0.498747 +-0.191129 0.152734 -0.492102 +-0.279278 -0.134446 -0.501048 +0.488567 0.466537 0.331101 +0.514158 -0.251432 -0.395376 +-0.496322 0.305834 -0.184366 +0.0473397 -0.497613 -0.335246 +0.0961798 -0.509108 -0.354895 +0.185039 -0.495313 -0.317423 +0.498647 -0.018943 0.0530925 +0.493532 0.436857 0.169984 +-0.304935 0.51417 0.249553 +-0.495327 -0.203771 -0.436534 +-0.299086 -0.150968 0.498265 +0.371337 -0.0548913 -0.495201 +0.382916 -0.082501 -0.508049 +-0.498697 -0.161977 0.0988135 +-0.509109 -0.141851 0.114074 +0.493213 -0.159048 0.0156675 +0.191625 -0.466167 0.472168 +-0.493415 -0.138319 0.160142 +-0.494728 -0.137841 0.137209 +0.500518 0.0917069 0.130689 +0.504642 0.0883959 0.154194 +0.497438 0.0655163 0.20815 +-0.502382 -0.280996 0.0529321 +0.126233 0.500368 -0.317476 +-0.307673 0.509071 0.10819 +0.492173 0.0942747 0.200735 +-0.504279 0.437176 0.256571 +-0.476441 0.477666 0.185207 +-0.321911 0.356399 0.509546 +0.296223 -0.410346 -0.513406 +-0.345081 0.48389 -0.452436 +-0.31011 0.194346 -0.500483 +-0.510322 0.414691 0.243204 +0.100424 -0.499068 -0.385498 +0.23888 0.411077 0.501762 +0.502264 -0.412712 0.230153 +0.316401 -0.391422 -0.502289 +-0.509065 -0.415347 0.110944 +0.490665 -0.165827 -0.466887 +-0.367245 0.134119 -0.50023 +-0.494024 -0.0152524 0.0619817 +0.0120952 0.281746 -0.495651 +-0.182556 0.443222 -0.489945 +-0.113545 0.507448 0.18931 +-0.508912 -0.237448 0.338306 +0.436585 -0.359836 -0.496088 +0.396737 -0.498666 0.3093 +-0.00103188 0.481417 0.472473 +0.387439 -0.504429 0.244416 +0.417032 -0.500356 0.288715 +0.259496 0.497745 -0.0597839 +0.499311 -0.319954 0.0463437 +0.50717 0.0207211 0.270927 +-0.240829 0.512335 -0.380903 +0.441047 0.495299 0.39226 +0.502577 0.113579 0.287004 +0.510655 0.0552721 0.276348 +-0.496006 -0.336243 0.430745 +0.492948 -0.0578589 -0.1982 +-0.361089 0.264594 0.505977 +-0.31858 -0.415943 0.498984 +-0.0433763 0.454721 -0.485566 +-0.015486 0.418171 -0.505481 +-0.0135359 0.369429 -0.495962 +0.0215454 0.393109 -0.503686 +0.173998 0.492344 0.0219957 +0.029427 0.444496 -0.495258 +-0.149522 0.162109 0.504138 +0.510527 0.422052 -0.304813 +0.48005 0.46634 -0.281191 +-0.273755 0.512382 -0.0930237 +0.161992 -0.0930757 -0.493281 +0.456631 0.340933 -0.497076 +-0.495643 -0.241021 -0.0798033 +-0.376707 0.501103 -0.35019 +-0.495611 -0.428273 0.0894532 +-0.503902 -0.344302 0.0367101 +0.380199 -0.124542 0.498028 +0.398231 -0.482718 -0.453361 +-0.411344 -0.124639 0.509315 +-0.380864 0.237873 0.506289 +-0.474219 0.470988 0.163095 +-0.33856 -0.501519 0.336349 +0.495118 -0.19884 -0.160424 +0.492615 -0.179467 -0.174549 +0.503082 -0.212995 -0.209382 +0.265424 -0.512867 -0.331236 +-0.207315 -0.495356 0.40628 +-0.255229 -0.51539 0.356408 +-0.236387 -0.512876 0.407229 +-0.282952 -0.507737 0.378516 +0.491998 0.0691326 -0.0914691 +-0.128125 0.395603 -0.498116 +-0.0812695 0.418786 -0.496407 +-0.123456 0.418914 -0.495782 +0.164157 -0.508863 -0.370199 +0.500581 -0.255795 0.0502245 +0.214831 -0.501613 -0.437522 +0.146492 -0.501929 -0.407484 +0.499551 -0.39891 0.419103 +-0.286953 0.0182737 0.499761 +0.498455 0.0824416 0.017968 +-0.259864 0.0348649 0.503749 +-0.20361 0.0114492 0.49083 +-0.22789 -0.00884917 0.50391 +-0.422955 -0.502999 0.149275 +-0.488938 -0.445669 -0.241541 +0.491722 -0.152022 -0.215399 +0.506655 -0.137421 -0.175586 +-0.480209 -0.438165 -0.463148 +0.489155 -0.156234 -0.188472 +0.246989 -0.500004 0.0940453 +0.31059 -0.511094 0.147494 +0.160188 -0.498 0.345335 +0.293932 -0.507682 0.0336077 +0.277778 -0.492953 0.108634 +-0.409904 -0.0672219 0.507101 +0.270498 -0.353294 -0.507727 +0.378557 0.428722 -0.48948 +-0.391882 -0.511456 -0.3274 +-0.498109 -0.14632 0.202849 +-0.502736 -0.0889009 0.213802 +-0.314171 -0.100004 0.510133 +0.0227271 0.502699 0.21946 +-0.508884 -0.108051 0.237145 +-0.460514 0.497365 -0.367976 +0.501295 -0.321801 0.0135779 +0.087213 0.474094 -0.473136 +-0.276069 0.274774 -0.510681 +-0.409343 0.3125 -0.510752 +-0.411853 0.279033 -0.510228 +-0.375181 0.213783 -0.498377 +-0.362709 0.27005 -0.502328 +-0.0392246 -0.261629 -0.498043 +0.0381371 -0.279729 -0.494759 +0.374536 -0.512289 -0.10598 +0.0283315 -0.363249 -0.495704 +0.498718 -0.117831 -0.0965471 +0.459292 -0.495972 -0.392627 +0.0999983 0.471131 -0.490813 +0.0246052 -0.310338 -0.512568 +-0.512877 0.045368 -0.310024 +0.41283 -0.443114 -0.488735 +-0.365723 0.510664 0.196442 +-0.314168 0.00239186 0.495724 +0.441371 -0.474869 -0.445796 +-0.507829 0.134732 0.405085 +-0.509074 0.165439 0.403552 +-0.499653 0.151914 0.427787 +0.253555 0.508832 0.0165136 +0.261347 -0.306266 0.505552 +0.355209 -0.435182 -0.508267 +0.492962 0.451106 0.314632 +-0.495823 0.245161 -0.182078 +-0.501641 0.204738 -0.157254 +-0.128342 -0.494088 -0.436583 +-0.472111 0.465676 0.426085 +-0.181908 -0.511004 -0.407563 +-0.509097 -0.0446984 0.400474 +-0.51067 -0.256274 0.195379 +-0.10139 -0.50495 -0.268706 +0.506252 0.404411 0.354003 +-0.497417 -0.0629783 0.461093 +-0.123432 -0.0300233 -0.506328 +-0.500926 -0.406591 -0.446529 +0.142278 0.47296 0.460138 +-0.503233 -0.168683 0.0315735 +-0.465355 -0.320384 0.491802 +-0.236075 -0.50736 -0.309763 +-0.306974 0.328857 0.510538 +0.503959 0.192902 -0.0913627 +0.505751 -0.34068 -0.00739039 +0.502351 0.243753 -0.190113 +-0.497995 -0.359235 0.236179 +0.112382 -0.0890947 0.494842 +0.125698 -0.110179 0.501629 +0.0853063 -0.128355 0.492135 +0.0574764 -0.317635 0.49573 +0.499378 -0.42405 -0.292567 +0.4076 0.506822 0.189282 +0.385327 0.514338 0.204246 +0.474025 0.48487 0.320423 +0.492128 0.46135 0.358908 +0.321811 -0.506311 0.403508 +-0.0298964 0.481066 0.453831 +0.428867 0.49416 0.200297 +0.294189 -0.513377 0.411377 +0.397534 0.448707 -0.486048 +-0.352859 -0.496696 0.422008 +-0.308867 -0.501261 0.435558 +0.301575 -0.503312 -0.383754 +0.25798 -0.51144 -0.409374 +0.275103 -0.482977 -0.44958 +0.157905 0.0951832 0.494469 +0.510433 0.244147 -0.359979 +0.151082 0.0610579 0.506662 +-0.240852 -0.504106 -0.339203 +-0.367167 -0.0834986 -0.502009 +0.512696 -0.304586 -0.369247 +0.0119271 0.48191 -0.479721 +0.500017 -0.114824 0.455328 +-0.483359 -0.159896 0.459224 +-0.502267 -0.266335 0.410243 +-0.0286223 -0.505284 0.381861 +0.164621 -0.465115 0.480502 +-0.497823 -0.281592 0.446725 +0.207263 -0.414322 -0.495561 +-0.50838 -0.268774 0.386074 +0.218661 -0.369038 -0.511437 +0.504583 0.406697 -0.113286 +0.500625 0.387787 -0.0258283 +0.42454 -0.502574 0.0720436 +-0.434018 -0.498578 -0.290855 +-0.0220602 0.0460578 0.509215 +0.332521 -0.448153 -0.486092 +0.339764 0.473306 0.480652 +0.500669 0.292022 0.247291 +-0.105151 0.13937 0.490209 +0.510621 0.24265 0.199741 +0.500385 0.254598 0.13457 +0.503532 0.225295 0.146858 +0.458349 0.481993 -0.0459563 +0.49914 0.2723 0.194293 +-0.30809 0.213831 0.509731 +-0.429245 0.0387146 0.498496 +-0.339626 0.19066 0.495865 +0.471314 0.326534 -0.485033 +-0.0214737 0.117275 0.506229 +0.21251 0.322916 -0.503111 +-0.344136 -0.500829 -0.0430048 +0.381486 0.510043 0.0303522 +0.117693 0.496879 0.180324 +0.167632 -0.153158 -0.502218 +0.489357 0.264823 -0.438722 +0.118652 -0.398222 0.512129 +0.115507 -0.36783 0.49718 +0.415099 -0.258827 0.509869 +0.0993571 -0.339902 0.496205 +-0.121871 -0.489125 0.462119 +0.145304 -0.357298 0.506978 +0.506271 0.396761 0.120716 +-0.474819 -0.251961 0.486159 +-0.472178 -0.464517 -0.445248 +0.496495 0.326223 0.134997 +0.157619 -0.507546 -0.122188 +0.241156 -0.499787 -0.149217 +0.189217 -0.503871 -0.160235 +0.0847495 -0.210507 -0.494104 +0.491975 -0.274467 0.458554 +-0.492695 0.183834 -0.460424 +0.508529 -0.268117 0.415064 +0.496727 -0.215053 0.417495 +0.507478 -0.158993 0.123189 +-0.494928 -0.345174 -0.0316903 +0.288756 0.517699 0.321468 +-0.504616 -0.317892 -0.255126 +0.491426 -0.235522 -0.110188 +-0.341763 -0.506891 0.0929591 +0.212906 0.494513 0.135037 +-0.0688216 -0.502992 0.380092 +-0.159581 -0.510317 0.405326 +0.220103 0.281267 0.513502 +0.0537843 -0.436585 -0.50106 +0.150942 0.23385 0.500931 +0.497779 0.00419287 0.385078 +-0.353167 0.510334 -0.113847 +-0.497975 -0.430736 -0.00535516 +0.511062 -0.0983625 0.258957 +-0.252726 0.507079 -0.101983 +0.382433 -0.501316 -0.0325294 +0.505691 -0.188115 0.293129 +0.462796 -0.292532 -0.483924 +-0.466198 0.475517 -0.379287 +0.508581 -0.146272 0.252735 +-0.507629 0.24288 0.326911 +-0.46204 0.393457 -0.477392 +0.45454 -0.48615 0.322001 +0.494814 0.109289 0.0370453 +-0.295792 0.500915 0.0852716 +0.507995 -0.162621 0.424987 +0.502784 0.449608 -0.102815 +0.283822 0.150911 -0.493165 +-0.205868 -0.480951 0.451625 +0.512405 -0.331061 -0.195871 +0.491739 0.420419 -0.0647681 +0.493528 0.114131 -0.404869 +-0.50043 -0.245115 0.39534 +-0.49335 -0.287842 0.421906 +0.507579 0.391483 0.268694 +0.481836 -0.44971 -0.454339 +0.478086 -0.0132007 0.470595 +0.484421 0.452122 -0.44945 +0.506888 0.384147 0.301899 +0.502224 0.406947 0.32425 +0.50253 0.44682 0.285281 +-0.503896 0.194254 0.231752 +0.186953 -0.0411863 0.490407 +0.145072 -0.0518168 0.500903 +0.501756 -0.151225 0.0671023 +0.0052543 -0.411227 0.50829 +-0.42687 0.502769 0.427403 +-0.399293 0.0335716 -0.497648 +0.373542 -0.178454 -0.499307 +-0.350877 -0.498671 -0.226015 +-0.305838 -0.498775 -0.267967 +-0.466944 -0.41676 -0.490746 +-0.0607074 -0.461972 0.478744 +0.0265103 -0.496122 0.43834 +0.00452558 -0.486234 0.442283 +-0.492992 0.454269 0.254991 +-0.0417115 -0.492668 -0.430809 +0.224524 -0.38536 0.514263 +0.509801 -0.389503 0.333439 +0.505753 -0.329988 0.298056 +-0.483658 -0.4176 -0.477988 +0.513105 -0.315617 0.324083 +-0.0400928 -0.484119 -0.454974 +0.499349 -0.289817 -0.289918 +-0.462029 0.373261 0.489278 +0.511527 0.156804 -0.274841 +0.506306 0.16903 -0.318343 +0.498726 0.123596 -0.311225 +0.339213 -0.472117 0.480071 +-0.488139 -0.0281546 0.431955 +-0.123822 0.388926 0.504795 +-0.422322 0.46581 0.480992 +-0.0247886 0.372459 0.509977 +0.202498 0.504568 0.401859 +-0.512223 0.393291 -0.139528 +-0.503695 0.288444 0.288487 +0.504084 -0.358534 -0.0641014 +0.14934 0.511693 -0.33802 +-0.0231953 -0.447344 0.492186 +0.472324 0.468631 -0.46388 +0.257925 0.512374 0.399933 +0.157712 0.504655 -0.411054 +0.27374 0.421058 -0.499531 +0.497623 -0.314575 -0.0931978 +0.426381 -0.402479 -0.489945 +0.367344 0.50576 -0.250396 +-0.254635 0.508535 0.251173 +-0.094979 0.396034 0.499913 +-0.462954 0.45502 0.472835 +0.289207 -0.501984 -0.209939 +0.340901 -0.50896 -0.205421 +0.162469 0.22541 -0.495171 +0.409486 -0.140019 -0.492457 +0.392473 -0.193779 -0.494667 +0.404277 0.488073 -0.453111 +-0.388986 0.512161 -0.0149927 +-0.360274 0.515746 0.0299096 +-0.363924 0.515294 -0.00674807 +-0.14455 -0.436345 -0.488324 +-0.146091 -0.464331 -0.482019 +0.449491 0.260559 0.482528 +0.418898 -0.307593 0.506652 +0.515602 -0.338938 0.32656 +0.408743 -0.500952 -0.441667 +0.43533 -0.4907 0.240278 +-0.00514465 -0.154407 -0.504369 +-0.381585 0.494743 0.397971 +0.369543 0.507509 -0.0302008 +0.239739 -0.50418 0.258457 +0.25381 -0.505855 0.284908 +-0.501421 0.196432 0.350424 +-0.471427 0.425594 0.472887 +-0.497261 0.165609 0.350318 +-0.507518 0.0872906 0.378608 +0.445608 -0.139279 0.495109 +0.411013 -0.493777 -0.417439 +-0.469152 -0.0898625 -0.467219 +-0.293636 0.500543 0.131345 +-0.246744 0.493503 0.443392 +-0.285121 0.50373 0.158506 +-0.468528 -0.0995539 -0.485359 +0.0119437 -0.495839 -0.314349 +-0.251844 0.507526 0.173763 +-0.284691 0.510457 0.187402 +-0.302534 0.496121 0.228242 +-0.413983 0.496111 0.018839 +0.509919 -0.0183066 0.36787 +-0.374461 0.497553 -0.0356652 +0.496584 -0.403334 0.00379057 +0.313308 0.211949 0.511226 +0.502361 -0.413064 0.0383626 +-0.182962 -0.498215 0.39867 +0.230057 0.50216 0.402228 +0.181006 0.494257 0.421738 +0.0271376 -0.195078 0.508375 +0.215072 0.503225 0.10266 +0.182293 0.490186 0.0936463 +0.203538 0.508249 0.0720423 +-0.408315 0.499816 -0.17732 +0.0563687 0.246036 -0.502594 +-0.252408 -0.504561 0.295033 +-0.380365 0.507908 -0.190871 +-0.492131 -0.0614497 -0.265713 +-0.500788 -0.103767 0.0848873 +0.357177 0.505306 0.336561 +0.208847 -0.461889 0.487242 +-0.128141 -0.468051 0.487055 +0.497543 -0.421425 0.182657 +0.256146 0.51062 -0.145954 +0.241939 0.324335 -0.498189 +0.286944 0.309435 -0.516828 +-0.26644 0.468527 0.488852 +0.494125 -0.234207 0.134104 +0.5122 -0.386003 0.366142 +-0.501774 -0.130046 -0.0799782 +0.453006 -0.46723 -0.459487 +0.316636 -0.275021 0.515735 +-0.488693 -0.428797 -0.444323 +-0.480055 -0.239535 0.462453 +0.345278 -0.34105 0.500988 +-0.472795 0.464679 0.136153 +-0.425665 0.50892 -0.321697 +-0.372913 0.503655 -0.287192 +-0.424535 0.503093 -0.29001 +0.486044 -0.444135 0.282957 +0.0857461 -0.493208 -0.0539359 +0.288907 -0.498784 0.168336 +0.384753 -0.498617 0.173914 +0.319573 -0.202119 -0.496462 +0.315474 -0.128165 -0.505158 +-0.139019 0.420837 0.506324 +-0.471768 -0.47667 0.0832677 +-0.378106 0.376974 0.499075 +0.497601 -0.452728 -0.00217184 +-0.485147 -0.174081 0.446002 +-0.500765 -0.0159808 0.252265 +0.440337 0.286117 0.494371 +0.508385 -0.269545 -0.148988 +-0.367916 -0.511547 -0.113539 +0.03935 -0.467519 -0.47538 +0.507638 -0.17366 -0.0883341 +0.50654 -0.219799 -0.0483303 +0.492426 -0.203622 -0.0999509 +-0.456286 0.440407 0.472828 +0.0393584 0.181359 0.500829 +-0.502921 0.440515 0.328435 +0.481233 0.462709 -0.02346 +0.483117 0.229734 -0.465636 +-0.485284 -0.440328 0.413583 +-0.506119 0.426032 0.355104 +-0.490203 -0.45609 0.346159 +-0.489073 -0.443095 0.380854 +-0.218616 -0.477674 0.472993 +-0.258457 0.511105 0.278864 +0.297261 -0.51622 0.32535 +-0.272052 0.461156 -0.491802 +0.449631 -0.482334 -0.329172 +-0.0181114 -0.103445 -0.492373 +-0.429016 -0.509713 -0.369391 +-0.373097 -0.501107 -0.377653 +0.191451 0.508201 -0.287161 +-0.20025 0.505351 -0.0143677 +-0.404218 0.0626899 -0.506762 +-0.00431746 0.51301 0.344117 +-0.412709 -0.487405 0.461012 +-0.216379 0.493066 -0.461911 +-0.414335 -0.494088 0.426005 +0.496956 0.319904 -0.258552 +-0.163356 0.502362 0.0190275 +0.453106 -0.481308 0.223172 +-0.187658 0.497709 0.00772583 +0.500434 -0.12749 0.0610542 +-0.508853 -0.424831 0.400813 +-0.182008 0.500049 -0.0371441 +-0.1855 0.501645 -0.110731 +-0.40424 0.504583 -0.209897 +0.371608 0.50023 -0.19786 +0.370696 0.513989 -0.116868 +0.374489 0.514539 -0.141261 +0.361095 -0.256681 0.50447 +0.206432 0.503001 0.166209 +-0.433008 -0.387758 0.500757 +-0.373222 -0.321006 0.512548 +-0.324706 0.498817 0.0869738 +0.503982 0.356455 -0.215943 +0.495753 0.434852 -0.239915 +0.451783 0.499351 -0.281608 +0.0651562 0.477928 -0.469339 +0.504776 0.407697 -0.1966 +-0.17053 0.507328 -0.00987827 +-0.263464 0.496801 -0.439243 +-0.428221 -0.360008 0.499179 +0.288116 0.506926 -0.209104 +0.244787 0.495483 -0.190977 +-0.281234 0.503267 0.358715 +0.289902 0.497906 -0.181161 +-0.429878 -0.488192 0.0318155 +0.262978 0.502996 -0.171909 +-0.172137 0.475776 -0.466685 +0.317046 0.507372 -0.161868 +0.283996 0.507233 -0.154488 +0.350688 0.51048 -0.269024 +0.397752 0.496321 -0.152538 +0.34428 0.509571 -0.21111 +0.422497 -0.11094 -0.490674 +-0.506866 0.125736 0.230307 +-0.498975 0.182062 0.322472 +-0.501381 0.132725 0.291336 +-0.509704 0.11867 0.323729 +0.282546 -0.499649 -0.269221 +0.506695 0.0711184 -0.234668 +-0.502001 0.0782029 0.30604 +-0.506854 0.131187 0.257863 +0.4987 0.0704676 -0.205719 +0.357805 0.507279 0.0226915 +0.300635 0.496551 0.010996 +-0.509147 0.216759 -0.0294731 +0.500759 -0.0237715 -0.202838 +0.447977 0.477142 0.466179 +-0.255612 0.507224 0.403109 +-0.467366 -0.0121653 -0.477038 +-0.333615 0.494832 0.422918 +-0.297022 -0.455294 -0.498656 +0.46623 -0.469261 0.206296 +-0.189275 -0.498459 0.276589 +-0.496701 -0.296167 -0.0636844 +0.406099 -0.463625 0.479845 +0.171602 -0.500619 0.395124 +0.142807 -0.508995 0.387144 +-0.180709 0.506833 -0.362805 +0.150155 -0.50412 0.442369 +0.462459 0.4809 0.428147 +0.147421 -0.494987 0.41233 +0.498584 0.0340337 -0.357604 +0.497051 0.19377 -0.316238 +-0.0342101 0.458281 0.484547 +-0.0561821 0.426761 0.490039 +0.250053 -0.497646 -0.0689441 +-0.0304405 0.419659 0.506834 +-0.506421 -0.22459 -0.174437 +0.507438 0.243455 0.334438 +-0.500063 -0.155457 -0.0645615 +-0.480959 0.219403 0.458728 +-0.242872 0.497658 0.0174272 +-0.221367 0.510154 0.0388278 +0.337316 0.377414 -0.514176 +0.272915 0.373545 -0.50691 +-0.507785 -0.0535461 0.168348 +0.321471 -0.165828 0.500673 +-0.193894 0.479666 0.457011 +0.293709 -0.158517 0.502175 +-0.270846 0.51302 0.332394 +-0.0300122 -0.399485 -0.496056 +0.141008 0.0342044 0.497617 +0.283023 0.512872 0.396532 +0.300613 0.507181 0.379408 +0.340875 0.506411 0.409722 +0.121881 0.492344 0.0132412 +0.341449 0.509857 0.0642477 +0.169458 0.496152 0.229071 +-0.509846 0.38768 -0.381525 +0.133807 0.213278 -0.504089 +0.273306 -0.178896 0.505626 +0.265556 -0.0368796 0.508436 +0.135739 0.360132 0.513072 +0.505956 0.0100999 0.178641 +0.492769 -0.00974011 0.196773 +0.509262 0.0166126 0.236874 +0.493565 0.0620269 0.232034 +0.507987 -0.0115679 0.222418 +0.22298 -0.129951 -0.503856 +0.274195 -0.193178 -0.505439 +-0.310473 0.50267 0.0636372 +-0.479719 0.452707 -0.470718 +-0.459552 -0.49464 0.109085 +-0.395299 0.502249 0.0387489 +0.282917 -0.235781 -0.507803 +0.312023 -0.230173 -0.504205 +0.247529 -0.203311 -0.496791 +0.0622902 0.492197 0.246581 +0.041943 0.503683 0.296278 +0.504545 -0.113662 -0.175737 +0.0490741 0.51133 0.361336 +-0.0147748 0.506574 0.293257 +-0.497744 -0.308587 -0.16352 +0.396245 -0.503117 0.433584 +-0.496821 -0.321193 -0.112991 +-0.17573 0.503738 -0.0857785 +0.150425 -0.0770493 0.50544 +0.205123 -0.149226 0.506672 +0.459024 -0.492612 -0.425777 +0.238967 -0.0946248 0.500078 +0.182513 -0.121035 0.501111 +0.505594 0.130073 0.270391 +0.495691 0.197753 0.157568 +0.499363 0.157178 0.1849 +0.499064 0.103266 0.173214 +0.44044 -0.283469 -0.496459 +0.297414 -0.50673 -0.324012 +0.363012 0.507856 -0.0926183 +0.102417 0.496009 0.110646 +0.490717 -0.380784 -0.436041 +-0.477149 0.466317 -0.307348 +0.142218 0.504371 0.0317238 +0.133548 -0.489473 -0.1949 +0.458532 0.0297856 0.481583 +0.123913 0.107993 0.491763 +0.148943 0.503384 0.0906998 +-0.451702 -0.0942301 -0.494535 +-0.399945 -0.504875 0.302023 +-0.367728 -0.51221 0.242782 +-0.386963 0.500101 0.266526 +0.430114 -0.463064 0.473302 +-0.417426 0.502183 0.233761 +-0.395574 0.512506 0.238697 +0.478165 -0.321315 0.473323 +-0.5047 0.377873 0.328981 +-0.339868 -0.0789402 -0.495865 +0.288847 0.494588 -0.0132231 +0.334905 0.495703 -0.087865 +0.394902 -0.452001 0.501301 +0.124524 -0.490994 0.0743251 +0.348833 -0.401926 0.506697 +0.127712 -0.499608 0.0100276 +0.0636833 -0.50505 -0.0301875 +-0.456618 -0.265338 0.496385 +-0.210446 0.267062 0.512434 +0.362352 0.502425 0.253123 +-0.459531 0.422147 -0.478317 +-0.384893 -0.497587 0.429525 +0.509838 0.411884 0.0764504 +0.501856 0.427732 0.0534419 +-0.30273 0.486343 0.465092 +-0.484438 0.396385 -0.451311 +0.497618 0.0463585 -0.0858221 +0.20346 0.498216 -0.435441 +-0.448397 -0.493884 0.353292 +-0.448857 -0.47192 -0.473094 +0.187447 -0.494631 0.205457 +0.47172 -0.274098 -0.471854 +0.244125 0.515921 0.349255 +0.250035 0.51549 0.281442 +0.313895 0.471427 -0.478636 +0.0375401 0.492426 0.195923 +0.0645738 0.501291 0.195647 +-0.372875 0.455405 -0.490043 +0.12759 0.4995 -0.0311487 +0.198527 0.506301 -0.0399881 +0.203731 0.500717 0.01175 +0.160987 0.501402 -0.0353498 +0.500167 -0.246817 0.454424 +0.00294497 0.498942 0.0974771 +0.0212264 0.50351 0.0561875 +0.0541926 0.497232 0.415234 +0.146514 0.508691 -0.00238218 +0.327335 0.436208 0.49838 +0.500162 -0.257576 -0.277529 +0.325143 0.400862 0.517095 +0.165067 0.502727 0.118908 +-0.486522 0.455344 0.435007 +0.481253 0.196334 0.457866 +0.196484 0.502067 0.203323 +0.498263 -0.158461 -0.387417 +0.148184 0.513444 -0.382392 +-0.325638 -0.495824 0.456082 +-0.38035 0.326679 -0.51008 +-0.265712 0.0855356 0.499781 +-0.384878 0.477835 -0.46499 +0.361971 0.295292 -0.50107 +0.315034 0.320942 -0.512199 +0.343832 0.269973 -0.508319 +0.491866 0.229046 -0.215203 +0.505085 0.209386 -0.26402 +0.491282 0.144393 -0.224327 +-0.0258535 0.497926 0.390139 +-0.496188 -0.277107 -0.425956 +0.503087 0.203317 0.242416 +-0.341789 -0.477166 -0.478339 +-0.460072 -0.379455 0.47724 +0.495792 0.167756 0.297169 +-0.49635 -0.224729 0.0403641 +0.513164 0.179549 0.325327 +-0.164005 0.488932 0.462492 +0.174488 0.509166 -0.212356 +0.410987 0.475657 0.465164 +0.272814 0.296475 0.507362 +-0.143993 0.502981 0.378692 +-0.477371 0.473178 0.403198 +-0.0639025 0.505763 0.371145 +0.0195798 0.212657 -0.491429 +-0.491772 -0.0583722 0.12509 +-0.190793 0.508514 0.423421 +-0.152862 0.497313 0.448078 +0.486442 0.451007 0.0584501 +-0.451119 0.495129 -0.0175683 +-0.413017 0.239715 0.499426 +-0.431551 0.212071 0.506405 +-0.352368 -0.446346 0.487961 +-0.289093 -0.34144 0.51139 +-0.157326 0.50866 0.154308 +-0.18944 0.505434 0.116076 +-0.197602 0.492219 0.141617 +0.453141 0.476293 -0.415691 +0.276892 0.501006 -0.132016 +0.193912 0.493629 -0.130731 +0.240106 0.49481 -0.0826624 +-0.50593 0.275697 0.00970348 +0.22662 0.505645 -0.137285 +0.294878 0.516654 0.35219 +0.346031 0.513471 0.306877 +0.0101134 0.510218 -0.282797 +-0.195001 0.497478 0.316028 +0.466109 0.483099 -0.299109 +-0.0798258 0.504333 0.38749 +-0.484654 -0.32994 0.449568 +-0.177175 0.514644 0.372513 +0.241477 0.304196 0.515461 +-0.0663452 -0.47792 -0.468105 +0.0693782 -0.499708 -0.135453 +0.286308 0.234406 0.50388 +-0.199841 0.500741 0.0626043 +-0.291158 0.406566 -0.506206 +-0.502602 0.358947 -0.212983 +0.171184 -0.475106 0.463633 +-0.510331 -0.39916 0.414645 +-0.4968 0.280011 -0.263554 +0.500315 -0.0401007 0.201916 +-0.514377 0.344538 -0.270326 +-0.503235 0.306235 -0.316449 +-0.0137773 -0.493445 -0.416887 +-0.27663 0.513118 -0.272578 +0.468104 0.147417 0.465239 +-0.36894 -0.500543 -0.0836979 +0.114867 -0.22968 -0.507603 +-0.028911 -0.234483 -0.5002 +-0.201144 0.499325 0.162666 +0.0769541 0.367444 0.496377 +0.297947 -0.495801 -0.136451 +0.0211177 0.395053 0.499881 +0.0773645 0.427716 0.507109 +0.0968769 0.508897 -0.413893 +0.013074 0.495481 0.280106 +-0.246311 -0.306673 0.497569 +-0.502436 0.0026872 0.393373 +-0.489541 0.0276592 0.452733 +-0.494307 0.0686956 0.403675 +-0.495144 0.00762588 0.425385 +0.0370899 0.506346 -0.3291 +0.408993 0.505092 0.0874199 +0.043174 0.508027 0.0696624 +-0.391222 -0.417204 0.49435 +-0.280841 0.496796 0.238517 +-0.171157 0.500298 0.202618 +0.0464248 0.501878 -0.394059 +0.477518 -0.299415 -0.468173 +0.0690825 0.505002 -0.374758 +0.504628 0.359151 -0.162763 +-0.0186701 0.512466 -0.355823 +0.273009 -0.498025 -0.162622 +-0.100074 0.509267 -0.377049 +-0.153945 0.513192 -0.401831 +-0.161874 0.497949 -0.378152 +0.507502 -0.0578524 -0.280809 +0.496787 -0.0265715 -0.249213 +0.510731 -0.0506154 -0.253202 +-0.433966 0.296429 -0.495013 +-0.499588 -0.447318 0.242577 +0.0414562 0.224272 -0.490761 +0.0781772 0.496406 0.117317 +-0.0532357 -0.282731 0.493627 +-0.462471 -0.468005 -0.482283 +0.238247 0.494706 0.155434 +0.250338 0.494174 0.0700667 +-0.123402 0.495648 0.354155 +-0.0577622 0.508446 0.34925 +0.511941 -0.401017 -0.369306 +0.233467 0.42911 0.492608 +0.495304 -0.0775247 0.391431 +-0.339612 0.447717 0.491565 +-0.0371095 0.509773 0.303277 +-0.0310144 0.514498 0.345964 +0.00601445 0.503246 0.364752 +-0.343784 -0.035806 0.514649 +-0.464365 0.482198 0.20142 +-0.377898 -0.512044 -0.233937 +-0.33932 0.243949 -0.503104 +0.00648562 0.496195 -0.460785 +-0.500247 -0.370676 -0.204224 +-0.496607 -0.388828 -0.0755491 +-0.503542 0.290892 -0.358448 +0.0536739 0.508837 0.0955874 +0.00976212 0.132244 0.491571 +0.0498975 0.497059 0.155481 +0.348075 0.509302 0.154288 +0.298679 0.502973 0.227203 +0.270255 0.498743 0.113272 +0.48905 0.291568 0.471666 +0.324874 0.49778 0.173746 +0.164898 -0.363464 -0.503066 +0.382157 -0.04639 0.500203 +0.056468 -0.0377234 0.493463 +0.36066 -0.0597862 0.501305 +0.502852 0.293961 -0.0273039 +0.00953829 -0.249815 0.498854 +0.497867 0.247583 -0.0999725 +0.492301 0.205324 -0.0106 +0.183672 0.321121 -0.496549 +0.3817 0.0366697 -0.504367 +0.146959 0.378781 -0.496989 +0.501873 -0.156456 -0.286688 +-0.402396 -0.30975 -0.50207 +-0.303062 -0.298081 -0.499459 +-0.200661 0.453336 0.500455 +-0.380348 -0.22505 -0.500084 +-0.351388 -0.276866 -0.50922 +0.158365 0.504097 0.408969 +0.0254122 0.502559 0.402698 +0.0924389 -0.502416 -0.259418 +0.106305 0.509239 0.404768 +0.329768 -0.511129 0.282425 +-0.141038 0.508257 0.279409 +-0.162495 0.508146 0.256344 +0.212275 -0.30269 -0.509324 +0.172227 -0.385814 -0.498753 +0.500168 -0.148118 -0.106343 +-0.491936 0.0218774 0.140688 +0.20839 -0.336282 -0.506631 +-0.347976 0.50593 0.399743 +0.0917157 0.496905 0.256608 +-0.286711 0.182096 -0.511368 +-0.364076 0.165197 -0.511227 +0.226996 -0.396482 -0.504335 +-0.317015 0.125541 -0.498638 +0.495222 0.0861306 0.229022 +-0.208964 -0.269337 -0.508894 +-0.236717 -0.172889 -0.501914 +0.403355 0.500299 0.0258203 +-0.291449 -0.197168 -0.511951 +0.470961 -0.441742 0.460297 +0.172566 -0.462119 -0.483128 +-0.42982 0.496433 0.109883 +-0.376121 0.502525 0.0635911 +0.451355 -0.315213 -0.496287 +-0.342112 0.500035 0.0624354 +-0.382038 0.507186 0.118045 +-0.228466 0.0417364 -0.493599 +-0.281163 0.0404838 -0.509705 +-0.24574 0.0841367 -0.493531 +-0.398299 -0.0861257 -0.5066 +0.11579 0.31023 -0.508026 +0.109682 0.256271 -0.506814 +0.134664 0.271001 -0.501548 +-0.0941418 0.371567 0.506717 +-0.187199 0.505396 -0.393017 +-0.245233 0.50676 -0.412747 +-0.381134 0.498384 0.295277 +0.400396 -0.168839 -0.505698 +0.323488 0.12629 -0.499005 +0.140087 0.502663 0.219253 +0.508927 -0.164258 0.232407 +0.494913 -0.218783 0.240563 +0.498623 -0.229568 0.16483 +0.478386 0.444807 -0.464057 +0.500631 -0.265175 0.210347 +0.50584 -0.127366 0.299111 +-0.163797 0.492825 -0.0599625 +0.509652 -0.212308 0.216758 +0.514555 -0.141949 -0.343945 +0.34252 -0.148107 0.496182 +0.297068 -0.0318658 0.512728 +0.329591 -0.0266144 0.503406 +-0.468521 -0.477941 -0.207344 +0.353339 -0.0101545 0.501693 +0.336466 -0.0966954 0.495076 +-0.485597 -0.441765 0.459809 +0.511134 -0.419041 0.321314 +0.469924 0.466085 -0.21832 +0.499033 -0.0186701 0.429594 +-0.48063 0.445404 -0.430155 +0.221989 -0.508144 -0.192422 +-0.287778 -0.22449 -0.500086 +0.198882 0.296175 -0.511498 +-0.101505 -0.423734 0.496893 +-0.225145 0.187279 0.508253 +0.0498629 -0.498281 -0.149096 +-0.487133 -0.432765 -0.0418141 +-0.0940867 -0.224705 -0.490453 +0.495748 0.283477 -0.224003 +-0.497057 -0.195524 0.216318 +-0.108986 0.165118 0.501928 +-0.306396 -0.499918 -0.328504 +-0.00360174 0.381196 0.505182 +-0.218499 0.156212 -0.490263 +-0.00275746 0.498902 -0.244051 +-0.507521 -0.234964 0.145906 +-0.495267 0.451879 -0.346432 +0.497513 0.433863 -0.212485 +-0.504817 -0.186529 -0.141232 +-0.509632 -0.362339 -0.270527 +-0.506036 -0.413019 -0.281883 +0.513101 0.281537 0.339932 +-0.491927 -0.416306 -0.250855 +0.0206377 -0.472833 -0.464122 +-0.397307 0.0399289 0.495649 +-0.102514 0.278334 -0.49441 +0.164084 -0.506387 0.193043 +-0.485684 0.440468 -0.268306 +0.187655 0.475832 0.4634 +0.307731 -0.490378 -0.453152 +0.0302884 -0.372656 0.498082 +-0.363621 -0.355171 -0.503772 +0.510188 0.223687 0.359661 +-0.438321 -0.488392 -0.338461 +0.185187 -0.500083 -0.429444 +0.503678 -0.397664 -0.202856 +-0.428263 0.499614 -0.200189 +0.100517 -0.506914 0.285131 +0.0849431 -0.36439 0.507632 +-0.0529538 0.500881 -0.154072 +-0.39144 -0.494411 0.18979 +-0.198947 0.0425899 -0.494693 +-0.504338 -0.0979401 0.267629 +-0.0133474 0.501834 -0.266163 +0.331071 0.0266823 -0.500419 +-0.202863 0.371316 -0.495743 +0.488471 -0.434906 0.438213 +0.365888 0.179268 0.514526 +0.0111217 0.164975 0.501397 +0.298979 -0.495497 0.0609964 +-0.500953 -0.213967 0.101018 +0.49469 0.141508 0.023263 +-0.260044 -0.457806 0.496668 +-0.505849 -0.0512462 -0.398887 +0.440882 -0.494864 0.38067 +-0.225539 -0.510051 0.426074 +-0.506583 0.0072157 -0.271095 +-0.495682 -0.02554 -0.233815 +-0.483782 -0.254262 0.44253 +-0.495282 0.0504924 -0.372052 +-0.502659 0.0340123 -0.10179 +0.0372581 -0.497699 -0.315951 +0.12254 0.180852 0.493781 +0.506278 -0.290706 0.338246 +0.0365262 0.245963 0.49565 +0.513187 -0.18179 0.355667 +0.101535 0.413806 -0.510187 +-0.335019 0.209592 -0.510156 +-0.178438 -0.506433 -0.373885 +0.501249 0.179384 0.213352 +0.344863 -0.132476 -0.499643 +0.14734 -0.501027 0.0232311 +0.237986 -0.511 -0.396493 +0.344747 0.122981 -0.512515 +0.3393 -0.496518 0.148611 +-0.495588 0.0898529 0.326544 +-0.0305178 0.441205 -0.503406 +0.212696 0.26559 -0.500801 +0.503862 -0.441664 0.227748 +-0.2727 -0.501263 -0.138303 +-0.50279 0.18248 0.264116 +-0.327211 -0.228159 -0.506147 +0.503491 -0.0968016 0.142993 +-0.333335 0.50378 -0.185214 +-0.103843 -0.492408 0.214597 +-0.495139 0.0803329 0.282068 +-0.475046 0.467258 -0.221602 +0.507367 0.233784 0.0363977 +-0.354313 0.503664 -0.144358 +0.363506 -0.455089 -0.485911 +-0.509626 -0.24866 0.227038 +-0.446445 -0.48194 0.403026 +0.435344 0.0696889 -0.495621 +-0.388717 0.495661 0.192499 +0.492774 -0.428974 -0.187122 +-0.231778 -0.273404 0.508022 +-0.362878 -0.38441 0.517666 +-0.0645739 -0.500863 -0.390441 +-0.0409399 -0.500174 -0.405791 +0.504741 0.374679 0.00127603 +-0.475341 -0.195774 0.482263 +0.103176 0.438265 0.497619 +-0.115517 0.30555 -0.494163 +0.0230881 0.361821 0.509014 +-0.0805336 0.362061 -0.504914 +-0.499053 0.292494 -0.38832 +0.152316 0.331122 0.509289 +0.498297 -0.42364 -0.410556 +0.499819 0.422169 -0.266945 +0.427079 -0.503197 -0.168507 +-0.348346 0.512373 0.21351 +0.346671 0.498077 -0.392384 +-0.296111 -0.403369 0.501253 +0.286199 0.349567 0.510667 +-0.367354 0.0415977 0.503437 +-0.361055 -0.502004 -0.146068 +-0.397806 -0.507443 -0.0127066 +-0.367915 -0.509902 -0.178009 +0.496995 0.286553 -0.061201 +-0.413411 -0.493922 0.257234 +-0.434095 -0.489806 0.32555 +-0.490685 0.0140712 0.0785156 +-0.459943 -0.469837 0.448576 +-0.210632 -0.507202 -0.357466 +-0.442877 0.487347 -0.193067 +0.0321241 0.435322 0.497686 +0.167118 -0.182808 -0.493765 +0.364171 -0.471699 0.470885 +0.0193631 -0.252363 -0.507902 +0.146394 -0.169999 0.501085 +-0.0390409 -0.354129 -0.505319 +0.399199 -0.280883 -0.510924 +0.468684 -0.471295 0.262271 +0.418476 -0.267794 -0.504251 +-0.210616 -0.502595 -0.32476 +0.436958 -0.247743 -0.502208 +0.208846 0.232909 -0.50387 +-0.151523 0.441172 0.486469 +0.495676 0.279778 -0.0918026 +-0.498408 0.369849 -0.180038 +-0.167235 -0.189379 -0.504842 +-0.445055 -0.483241 0.29983 +-0.241518 0.494894 -0.120821 +-0.328039 0.515711 -0.159716 +-0.285964 -0.103485 -0.50451 +0.279235 0.509095 0.28833 +-0.313739 -0.506944 -0.360441 +-0.31865 0.42925 -0.495245 +0.343546 0.0767568 -0.501463 +0.423983 -0.462554 -0.481141 +-0.465003 -0.459057 0.466284 +0.396767 -0.308375 -0.506287 +0.477221 -0.466283 0.444109 +0.463928 -0.458165 -0.468584 +-0.508082 0.185104 -0.0864894 +-0.347202 0.307819 0.513286 +0.424773 -0.449863 0.498792 +0.497305 -0.394282 0.261557 +0.135221 0.505056 0.19581 +-0.209156 0.30186 -0.510497 +-0.455643 -0.480922 0.462918 +0.495184 0.183085 -0.19647 +0.373236 -0.505422 -0.079917 +0.515528 0.401547 -0.386689 +0.506977 0.419224 0.10434 +0.0613206 -0.223044 -0.506859 +0.126707 0.505115 -0.426765 +0.0762691 -0.128072 -0.498728 +-0.310992 -0.386104 -0.515631 +-0.503514 0.446753 0.278094 +0.378044 -0.50695 0.122365 +0.147765 -0.507555 -0.389442 +-0.352086 -0.241827 -0.514478 +0.451058 -0.485562 0.457893 +0.212751 0.229314 0.504018 +-0.503508 0.303378 -0.0672984 +-0.369117 -0.503977 0.40154 +0.473085 -0.208957 0.488622 +-0.392059 -0.0139122 0.509416 +-0.482982 0.469182 -0.131969 +-0.45381 -0.208363 0.489069 +-0.444976 -0.0231334 0.483915 +0.492553 0.114719 -0.02684 +-0.40771 -0.205256 0.494659 +0.502369 -0.194864 0.160691 +0.491034 -0.187564 0.13408 +-0.00779999 -0.430207 0.505619 +0.497167 -0.442171 0.311094 +0.483948 -0.405332 0.456167 +0.508197 -0.13388 -0.372226 +0.499657 0.133699 0.400952 +-0.509328 0.0157067 -0.161922 +0.211529 0.515047 -0.335893 +-0.51086 0.292747 -0.419696 +0.2903 0.464572 -0.494615 +0.287429 0.399127 -0.510636 +-0.506592 0.404739 0.149028 +-0.400752 -0.252204 -0.508715 +-0.494068 -0.15215 -0.212992 +-0.186935 -0.153036 -0.500567 +-0.0421754 -0.502144 -0.173896 +0.514818 0.37037 -0.382466 +0.503318 0.365879 -0.327389 +0.357438 0.163174 -0.506128 +0.174869 -0.339649 -0.508541 +0.461272 -0.100458 0.495123 +-0.200113 0.238105 -0.491955 +0.298029 0.494471 0.0740874 +0.50809 -0.250173 -0.167415 +-0.507286 0.243902 0.00243096 +0.405513 0.511341 0.358286 +0.382388 0.506225 0.339037 +0.0793727 -0.51296 0.307419 +0.389709 0.514676 0.390012 +-0.224698 0.501281 -0.143242 +0.458108 -0.487282 0.418787 +-0.492628 -0.157219 0.254006 +0.187353 -0.267797 -0.500307 +0.37104 0.0501823 0.498414 +-0.471834 -0.471417 0.172348 +0.41906 0.490006 -0.132589 +0.506433 -0.377438 -0.413634 +-0.494306 -0.417666 -0.425285 +-0.252002 -0.0620567 0.511714 +0.0111294 -0.504355 -0.368969 +0.49589 0.419622 0.255079 +0.0359285 0.31039 0.509275 +-0.500957 -0.379758 -0.320638 +0.423145 0.512051 -0.372027 +0.508342 -0.0788573 0.0844771 +-0.465892 0.485995 -0.199576 +0.473576 -0.479409 -0.374789 +0.303771 0.0350201 -0.509415 +0.151705 -0.50747 -0.0478194 +0.495207 0.279609 0.150951 +0.407703 0.489204 0.447406 +0.510575 -0.338538 0.192907 +0.299106 0.416532 -0.496561 +-0.506777 0.402682 -0.35611 +-0.469147 0.482603 -0.352501 +0.514764 0.292075 -0.403507 +-0.444999 0.490728 -0.216265 +0.296232 0.187674 0.513306 +-0.390683 0.187134 -0.513827 +-0.145212 0.304066 -0.500425 +0.505339 0.329732 -0.101755 +-0.505458 -0.0422009 0.333608 +-0.113612 -0.414335 -0.499679 +0.371536 0.511861 0.415189 +-0.181944 0.0384196 0.503188 +-0.215278 0.0783977 0.50367 +-0.38568 -0.342851 0.519744 +-0.146753 -0.370127 -0.499877 +0.365705 -0.0323481 -0.51504 +-0.387866 0.507136 -0.431615 +0.227127 0.214463 -0.505325 +-0.0886474 -0.304194 -0.497937 +-0.511375 0.366552 -0.247113 +-0.512299 0.180271 0.377313 +0.498213 0.223493 -0.283102 +-0.481501 -0.377247 0.474109 +-0.272274 -0.249902 -0.50556 +0.487564 0.310429 -0.474609 +-0.417566 0.477649 0.47252 +0.498622 0.160412 -0.203607 +0.485757 0.140201 0.429544 +-0.511474 -0.303673 0.0770031 +-0.0937347 0.250493 -0.495245 +-0.0250963 -0.133705 -0.493361 +-0.49643 -0.428635 -0.408221 +-0.492286 -0.132515 0.459951 +-0.49975 0.23846 -0.346075 +0.504479 0.0671516 0.11282 +0.416133 0.354361 0.508527 +0.366589 -0.500979 0.365652 +0.280239 0.126215 0.494224 +-0.50125 -0.339846 -0.0906265 +-0.0837607 -0.505458 0.310058 +-0.473517 -0.471853 -0.0272395 +0.500236 -0.387258 -0.0196445 +0.335195 0.480095 0.462165 +0.47778 -0.169788 0.461059 +-0.115227 -0.296888 -0.497468 +0.477824 0.45413 0.461236 +-0.414352 -0.0110239 -0.49436 +0.478658 0.0806272 -0.458416 +0.466988 -0.475221 -0.311908 +-0.418187 0.0133188 -0.498307 +-0.515665 -0.247182 0.367674 +0.415214 -0.473512 0.464218 +0.505165 -0.281079 0.124348 +-0.435939 -0.440692 0.489893 +-0.360015 -0.512281 0.314238 +-0.425432 -0.500942 0.351642 +0.18996 0.0110591 0.490883 +-0.496783 0.390571 -0.19955 +-0.505034 0.39499 -0.255476 +0.480105 -0.477015 -0.197838 +0.498975 0.411081 -0.412055 +0.273212 0.0439031 0.505311 +-0.16502 0.100319 -0.495673 +0.493819 0.261275 0.0491242 +0.514266 -0.377157 -0.291786 +0.496674 0.381661 0.0729321 +-0.507905 0.204686 0.0330154 +-0.23674 -0.0878351 -0.508966 +0.0214083 -0.494741 0.237633 +0.441876 -0.403162 0.488088 +-0.500637 0.169411 -0.422205 +-0.507582 -0.397214 -0.102826 +-0.501832 0.291938 -0.0204214 +-0.506914 0.0886772 -0.270407 +-0.350869 0.417663 -0.509438 +-0.504628 0.116263 -0.263841 +-0.494695 0.166816 -0.060863 +-0.181163 -0.509327 -0.0277289 +0.479408 -0.147141 0.480182 +-0.504729 0.315917 0.0610726 +0.249819 -0.49857 0.0397109 +-0.504276 -0.433805 -0.304427 +0.451562 0.494517 -0.343354 +0.502408 0.0630251 -0.443068 +0.411037 -0.501154 -0.0881569 +-0.50002 -0.334891 -0.420057 +-0.502594 0.104037 -0.393175 +0.231387 -0.178143 -0.499026 +0.0683292 0.497366 0.0674435 +-0.465913 0.173466 -0.494395 +-0.504045 0.410335 0.29455 +-0.402672 0.505422 -0.403997 +0.500933 0.42946 -0.391255 +0.509781 0.328942 -0.211049 +0.472101 0.484761 -0.134413 +0.266636 0.504998 -0.308757 +0.06204 0.481263 0.471436 +-0.490613 0.423657 -0.456816 +0.28012 -0.171877 -0.497558 +-0.29164 0.479257 -0.484277 +0.491692 -0.4634 0.218578 +0.512085 -0.401461 -0.338365 +0.512258 -0.340783 -0.368482 +0.0300879 -0.498593 -0.268662 +-0.39423 -0.504329 0.0214806 +-0.388116 -0.503689 -0.0406833 +-0.290064 -0.430576 -0.508843 +-0.355311 -0.510883 0.191174 +-0.378826 -0.504173 0.134091 +-0.372976 0.497846 -0.453912 +0.10404 0.49974 0.322178 +0.508479 -0.265465 -0.120965 +0.0195858 -0.404863 -0.504759 +-0.386588 -0.507348 -0.431272 +0.271929 0.507989 -0.085948 +0.159993 0.489621 -0.124446 +0.466173 0.095209 -0.471946 +-0.260366 -0.336395 -0.501503 +0.473795 -0.469624 -0.430335 +0.380667 0.505356 -0.0770955 +0.282426 -0.206496 0.495277 +0.513134 -0.37185 0.000685296 +0.49996 -0.104919 -0.379648 +0.389257 -0.51169 -0.379204 +-0.490358 0.253857 -0.464004 +-0.48883 -0.137061 -0.42867 +0.176391 0.494718 0.393735 +-0.180881 -0.454933 0.485289 +0.501537 -0.435916 -0.12079 +0.49476 0.421763 -0.433359 +-0.50168 -0.163926 0.369173 +0.502751 0.0960074 -0.102148 +-0.462518 -0.205202 -0.472776 +-0.00798212 0.325479 -0.513649 +0.499085 0.435688 -0.454762 +0.508991 -0.37459 -0.260899 +0.418455 -0.349516 -0.50508 +-0.457157 0.262195 0.498771 +-0.471265 0.151845 -0.477389 +-0.514696 0.366465 0.409888 +-0.00186652 0.496069 0.446862 +0.453686 0.459545 -0.480028 +-0.327844 0.455091 -0.49614 +0.501208 -0.0919546 -0.403237 +-0.461459 -0.483837 -0.122548 +0.266748 -0.502411 -0.0467151 +0.323164 0.50789 0.334437 +-0.391514 -0.507174 -0.130717 +-0.489871 0.156957 -0.466362 +0.368171 0.318216 0.517015 +0.498573 -0.0703153 -0.308179 +0.434988 0.257777 0.506284 +-0.230323 -0.505497 -0.181476 +-0.243199 -0.502003 -0.234931 +0.176278 -0.500721 0.057259 +-0.374178 0.147557 0.501466 +0.501934 0.0464618 -0.251483 +-0.368373 0.491041 0.463322 +-0.115743 0.502907 -0.0827505 +0.404502 0.494896 0.418589 +-0.330741 -0.1456 -0.513909 +0.452762 -0.288318 0.482162 +-0.380936 -0.113326 -0.513071 +-0.491787 0.218424 -0.180356 +0.355233 -0.517461 0.397465 +0.515515 -0.203087 0.343295 +-0.505298 -0.223791 -0.0277568 +0.446745 0.491436 0.0744828 +-0.489814 -0.184337 0.467345 +-0.485341 -0.0284347 -0.44367 +-0.497276 -0.424478 -0.384421 +-0.465956 0.247198 -0.490956 +-0.508228 0.00371574 -0.412436 +-0.434639 0.452877 -0.474401 +0.464368 -0.471828 0.151966 +0.32352 -0.480585 -0.467079 +0.163715 0.383962 0.506221 +0.447146 -0.452435 0.480275 +0.465858 0.147033 -0.47185 +-0.349655 -0.502801 0.0719813 +-0.340999 -0.401551 0.504008 +-0.130932 0.499037 0.409587 +-0.437693 -0.486648 0.426097 +-0.496143 -0.131909 -0.383794 +-0.413956 -0.51011 -0.307036 +0.50534 -0.120072 0.218491 +-0.236496 -0.436203 -0.492822 +-0.488965 0.211203 -0.451433 +-0.18117 -0.493828 0.441258 +-0.199961 -0.493297 -0.255851 +0.428901 0.00112216 -0.499417 +-0.319413 -0.435785 -0.496903 +0.500351 0.353197 -0.285547 +0.0734708 0.466249 -0.484247 +0.466936 0.479693 0.256785 +0.208764 -0.493715 0.256206 +0.173038 -0.345503 0.504645 +-0.0681916 -0.498183 -0.312387 +-0.132523 0.229196 0.50041 +0.475863 -0.466146 -0.228031 +-0.450166 0.39958 0.486112 +0.386195 -0.442114 -0.502107 +-0.308542 0.49734 0.297313 +-0.256999 0.493935 0.135353 +-0.513335 0.415587 -0.335032 +-0.483502 0.446161 -0.297683 +-0.374276 -0.481446 0.468385 +-0.363254 0.485118 -0.466968 +-0.398891 0.499393 0.423935 +0.487161 -0.459009 0.303582 +-0.365452 -0.501771 -0.448853 +-0.482124 -0.474368 0.372616 +0.511151 -0.0392445 -0.394216 +-0.422436 0.49296 -0.258754 +-0.26171 -0.435765 0.5053 +0.103814 -0.501156 0.00681238 +0.420475 0.34861 -0.511894 +0.444127 0.394543 -0.488279 +0.510829 0.30784 0.0716353 +-0.450784 -0.300277 -0.48993 +-0.388365 -0.439504 -0.494201 +0.491721 0.0984524 -0.44459 +-0.497955 0.198731 0.445849 +-0.149409 -0.483683 0.459572 +-0.229711 -0.512739 -0.257458 +-0.462914 0.281842 0.476988 +-0.508169 -0.353459 -0.329348 +0.479418 -0.410131 -0.468355 +-0.502279 0.35609 -0.116995 +-0.514018 0.370586 0.014553 +-0.244555 0.288141 -0.511779 +0.0749224 0.365342 -0.50857 +-0.511463 -0.149686 -0.36798 +0.00431463 -0.506769 0.0408487 +-0.347434 0.466619 -0.491751 +-0.512701 0.347301 0.260089 +-0.510297 -0.399648 0.0807242 +0.432009 0.0676442 0.491882 +0.410479 0.195663 0.497687 +0.501664 0.113992 -0.377647 +-0.439466 -0.162801 0.500123 +0.493443 0.0589056 -0.407526 +0.43368 -0.333839 -0.494615 +0.467692 -0.176131 0.482586 +0.493157 -0.140987 0.173461 +-0.0058322 0.225706 -0.509526 +-0.494004 0.231996 -0.10155 +0.0427216 0.40018 -0.495028 +-0.497597 0.127382 -0.384746 +-0.453602 -0.480338 0.329866 +-0.47115 -0.464738 0.456041 +0.159231 -0.23381 0.498758 +0.499459 0.204517 0.023014 +-0.11687 0.490985 -0.172199 +0.0158808 -0.505371 -0.0604319 +0.507422 -0.273803 -0.367874 +0.48966 -0.0861268 0.442202 +-0.469624 0.469494 0.0787668 +0.280913 -0.511087 0.138614 +0.501504 0.425542 0.196907 +0.409117 -0.083179 -0.493632 +-0.475446 0.229005 0.482513 +0.364802 -0.108436 -0.500573 +0.3109 -0.488346 0.475056 +-0.500932 -0.18443 0.140996 +-0.424486 0.440432 -0.482295 +0.501756 0.130626 0.166368 +-0.461307 -0.480814 0.42866 +-0.463736 -0.482343 0.354514 +0.142226 -0.202848 -0.507006 +0.276718 0.379465 0.514012 +-0.476711 -0.460135 -0.191702 +-0.506817 -0.439884 0.112559 +-0.389805 0.123111 -0.512937 +-0.490815 0.327307 0.46556 +-0.43468 -0.473311 0.459911 +-0.380494 0.0761943 -0.512107 +-0.160825 0.460858 -0.498413 +0.436983 -0.491603 0.271533 +0.305122 0.493488 -0.0364003 +0.36717 -0.454167 0.504173 +0.275849 0.50533 0.00671648 +0.499898 0.0732856 0.253708 +0.503266 0.0687019 0.304515 +0.283392 -0.468161 -0.48759 +-0.372218 -0.431793 0.494524 +-0.030892 0.392728 -0.511859 +-0.373675 0.499269 -0.319796 +-0.42055 0.500477 -0.351354 +0.359495 -0.109902 0.511396 +0.503332 -0.232346 -0.18837 +-0.459036 0.487305 -0.150849 +0.462804 -0.388325 0.488891 +-0.411242 -0.457244 0.496036 +-0.113608 0.447509 -0.493496 +0.445671 -0.19625 0.484638 +-0.144595 0.417805 -0.493182 +0.0708087 -0.496567 -0.373052 +-0.361194 0.507759 -0.0637033 +-0.25529 -0.0279781 0.500768 +0.475376 0.190794 0.483408 +-0.426764 -0.488009 0.445376 +0.247506 -0.503613 0.0636111 +-0.14986 -0.466327 0.492484 +0.476846 0.0934702 0.462477 +0.474349 -0.462482 -0.448822 +-0.415836 -0.496004 -0.336225 +-0.482897 -0.451075 -0.112867 +0.448224 -0.11091 -0.486208 +0.371254 -0.487209 0.459688 +0.0125424 -0.340658 -0.497944 +0.499995 -0.274441 -0.0350759 +0.490159 -0.0484525 0.00259824 +0.487505 0.443206 0.448531 +0.249866 0.507342 -0.0378986 +0.229801 0.505588 0.00082569 +0.279606 -0.511547 0.283151 +0.50245 0.0892542 0.428709 +-0.504907 -0.123304 -0.20363 +-0.489616 -0.0588109 0.434943 +0.07903 -0.108136 0.5008 +0.375993 0.502959 0.15865 +-0.271233 0.505811 -0.0327945 +-0.184372 0.493305 0.231475 +0.326635 -0.492133 0.448128 +-0.318664 -0.499117 0.389436 +0.334014 0.479841 -0.461352 +0.127467 0.0538733 0.497379 +0.459741 -0.413979 0.477997 +-0.0443313 0.360168 -0.512466 +-0.506808 -0.240348 0.424966 +-0.288113 -0.250341 0.497646 +0.499665 -0.277668 -0.415715 +0.501399 0.280457 0.173239 +0.23307 -0.491097 0.181295 +0.141562 -0.385223 0.506158 +0.511613 0.389492 0.173739 +0.406581 0.384464 0.494772 +0.428032 -0.429434 -0.499202 +0.499296 0.37074 0.132587 +0.13605 -0.497579 -0.166006 +0.209627 0.479738 -0.47977 +-0.50561 0.258145 0.237807 +0.436606 -0.443534 -0.485658 +-0.467009 0.477145 -0.405517 +-0.49984 -0.392991 -0.423767 +0.451373 -0.48456 -0.0166895 +0.493792 -0.271274 0.436579 +-0.153783 -0.497473 0.355417 +0.512171 -0.206729 0.262213 +-0.462675 0.445167 -0.472182 +0.503343 0.427845 -0.0942685 +-0.505373 -0.290047 0.377786 +-0.499709 0.439026 0.443139 +-0.289961 -0.511754 -0.24673 +0.19499 -0.0661223 0.503837 +-0.371808 -0.0269936 -0.496295 +-0.373556 0.0297859 -0.497443 +-0.330206 -0.500418 -0.276 +0.499515 0.160109 0.348946 +-0.164036 0.45742 0.478193 +-0.328819 -0.51478 -0.216274 +0.449322 0.48786 0.242817 +0.126206 -0.478063 -0.460579 +0.0402985 -0.482455 0.464444 +-0.0994894 -0.495299 -0.426347 +0.16879 -0.375907 0.512023 +0.502331 -0.334094 0.263009 +0.437366 0.421354 -0.490602 +0.511124 -0.359641 0.344781 +0.453467 0.312935 -0.492566 +0.329122 -0.516482 0.370059 +-0.387079 0.494366 0.44698 +0.466625 0.218861 -0.470662 +0.457798 -0.150441 0.482496 +-0.418443 0.465776 -0.488895 +0.4088 0.501209 0.217255 +-0.406934 0.503066 0.0660711 +0.312687 -0.498098 -0.25794 +0.180635 0.201416 -0.499909 +0.349132 -0.161571 -0.503538 +-0.389158 0.503246 0.00962747 +-0.433367 -0.413375 0.489171 +0.466585 -0.317022 0.493768 +-0.501434 0.166812 -0.311286 +0.257811 -0.49356 0.234683 +0.0875454 0.486899 0.453705 +-0.318561 0.494958 0.446049 +0.277586 -0.00834951 0.494695 +-0.262219 0.504611 0.200166 +-0.229219 0.506095 0.417918 +0.452778 0.111101 -0.481479 +0.133336 0.491645 0.447276 +0.200901 0.490014 0.0414842 +-0.49442 -0.421317 0.426648 +-0.428163 0.509212 -0.228508 +-0.315946 0.49974 -0.42263 +0.279236 0.497158 0.417307 +-0.489699 -0.352512 0.444816 +0.0863312 0.505117 0.0908735 +0.256178 0.348739 -0.51468 +0.512711 -0.32294 0.386543 +0.508863 -0.378918 0.397013 +-0.155505 0.501947 0.349645 +0.500289 -0.440647 0.340946 +-0.030816 0.504589 0.437533 +-0.125445 -0.0938168 -0.4937 +0.477981 0.0405356 0.458858 +-0.37392 0.505374 -0.254017 +0.501121 -0.205713 -0.317905 +0.502403 -0.172353 -0.0626427 +-0.512925 0.411667 0.323663 +0.177542 0.471268 0.480587 +-0.353715 0.390891 -0.513438 +0.152064 -0.103549 0.50277 +-0.292705 0.499021 0.313985 +-0.389694 -0.497174 0.457972 +-0.44006 0.218582 -0.492951 +0.368204 0.508898 0.284307 +-0.139399 0.509166 -0.00245276 +-0.0138883 0.470537 0.488408 +0.349547 0.499129 -0.15301 +-0.493069 0.109748 0.248653 +-0.501697 0.166873 0.293732 +0.336785 0.499179 -0.0345595 +0.484179 0.00385718 -0.4612 +0.329002 0.501858 0.0156999 +-0.296257 0.510397 0.381294 +0.18735 -0.511668 0.377727 +0.17626 -0.492701 0.45136 +-0.47663 0.302875 0.470377 +-0.0580429 0.453066 0.49496 +-0.474833 0.461372 -0.0489507 +0.381981 0.461687 -0.471991 +0.323054 0.349479 -0.519228 +-0.351545 -0.46515 -0.497006 +0.285392 -0.129917 0.510507 +0.327353 0.495968 0.425262 +0.496624 -0.336898 -0.145353 +-0.413634 -0.470671 0.47208 +0.479881 0.469998 0.381979 +0.342994 0.514178 0.361914 +0.349964 0.498119 0.109197 +0.365744 0.499105 0.0518944 +-0.509872 -0.297972 -0.365019 +0.506649 0.0396703 0.191597 +0.114756 0.479044 0.458191 +0.217641 -0.200277 -0.498436 +0.0142327 0.492324 0.248069 +0.493622 -0.454732 -0.234107 +-0.161276 0.497154 0.176207 +0.489666 -0.22203 0.469679 +0.223193 -0.0680984 0.490375 +0.235069 -0.147848 0.500427 +0.496409 0.115744 0.22405 +0.496027 0.167489 0.243855 +0.116248 0.48987 0.0898033 +0.475148 -0.47693 0.235969 +0.0988071 0.506097 0.0643583 +-0.442015 0.498611 0.276565 +0.302631 0.498775 -0.134079 +0.303966 0.497568 -0.0864494 +0.49917 -0.0301441 -0.158132 +-0.257123 0.221807 -0.503285 +-0.159571 0.27639 0.496265 +0.50425 0.390199 0.0251044 +-0.416469 -0.495286 -0.431395 +-0.465036 -0.470614 -0.428215 +-0.342827 -0.508658 -0.0127583 +-0.226712 0.487015 0.463554 +0.0280426 0.498409 0.170626 +-0.167964 -0.498158 0.330211 +-0.498192 -0.263957 0.00422267 +-0.0156926 0.507778 0.367297 +0.0258555 0.502014 0.375634 +0.510598 0.214653 0.275247 +0.340761 -0.455739 0.492017 +-0.282851 -0.04251 -0.505744 +0.0375036 0.498917 -0.2979 +0.450071 -0.491309 -0.0964163 +0.306685 0.486517 0.456738 +-0.0528786 0.508773 0.391074 +-0.461155 0.480576 0.417786 +-0.131593 0.497062 0.437423 +-0.439226 0.239052 0.489966 +-0.144043 0.502936 0.135794 +0.206915 0.503702 -0.0750526 +0.466754 0.449052 0.467707 +-0.216388 0.503625 0.335863 +-0.434604 0.48348 0.463305 +-0.496102 0.300648 -0.237855 +0.43436 0.498488 0.413702 +0.0163666 0.42296 0.50577 +-0.485483 -0.00896095 -0.461285 +0.492809 -0.0483412 -0.144514 +-0.472616 0.487112 0.121586 +-0.504883 0.0845841 0.436988 +-0.466668 -0.0467544 -0.482707 +-0.0701595 0.496768 -0.360626 +-0.430068 -0.500934 -0.185372 +0.494338 -0.0400872 -0.0495281 +0.503476 -0.250831 -0.245346 +-0.490316 0.464885 0.0601366 +-0.431435 0.261946 -0.50216 +0.295586 0.495679 0.159613 +-0.0753908 0.498833 0.326771 +0.322243 0.501194 0.117141 +0.458943 0.224481 -0.488979 +-0.00807915 -0.484607 -0.471018 +0.0874157 0.498996 0.427907 +-0.110514 0.49345 0.275402 +0.260732 -0.425399 -0.49707 +-0.341523 0.467066 0.480556 +-0.289829 -0.476886 0.472886 +-0.283664 0.208871 -0.508583 +-0.409829 0.503039 0.113332 +-0.254246 0.0410035 -0.494696 +-0.395508 -0.141366 -0.501427 +-0.430613 0.501075 0.311666 +-0.376542 0.507785 0.31852 +-0.492326 0.187456 0.468823 +0.506122 -0.204482 0.188678 +0.338017 -0.070821 0.498493 +-0.485384 0.468144 -0.364803 +0.167087 -0.496641 0.222927 +0.109984 -0.496827 0.195759 +0.503352 -0.000378356 -0.415524 +0.243644 -0.497185 -0.178953 +0.0976387 -0.132544 -0.489801 +-0.494186 0.451637 0.206879 +-0.492246 -0.163707 -0.465859 +-0.269306 -0.158889 0.497714 +0.0446565 -0.498224 0.32307 +-0.111173 -0.44579 0.500708 +0.417766 0.505247 -0.237382 +0.301101 -0.446225 -0.489368 +-0.270458 -0.498188 -0.31293 +-0.372844 0.364799 -0.499586 +-0.423745 0.506613 0.158165 +-0.0460218 0.507661 0.00361463 +0.50813 -0.291661 -0.105333 +0.0464028 0.507593 -0.15413 +-0.00311363 -0.391667 -0.497419 +0.0385136 -0.0303836 -0.491092 +0.208754 -0.500486 -0.406502 +0.289962 0.0185575 0.511165 +-0.505396 0.118788 0.378633 +-0.203558 -0.505105 0.299064 +-0.151965 -0.500591 0.306102 +-0.2517 0.253854 -0.500308 +-0.282286 -0.499996 0.342295 +0.460756 -0.0800112 -0.477573 +-0.126471 0.467974 -0.472183 +0.503223 0.30241 0.276618 +0.287358 -0.43113 -0.51004 +-0.501108 -0.268557 -0.0693151 +0.461114 0.489305 0.379301 +0.348292 -0.403727 -0.50717 +-0.0673818 -0.0294295 -0.504982 +-0.435579 -0.463827 0.481975 +0.495193 0.210156 -0.042535 +-0.252586 0.241335 0.507954 +-0.273623 -0.511189 0.0733366 +0.482956 -0.462637 -0.326201 +-0.505563 0.397734 0.125742 +-0.318409 -0.130638 0.508646 +-0.121945 -0.503067 -0.19192 +0.0931222 -0.282833 0.505165 +0.0435874 -0.0883884 -0.505732 +-0.23351 -0.507507 0.365359 +-0.502309 -0.266284 -0.0958948 +-0.0961313 -0.0127264 -0.500526 +-0.483845 -0.458094 0.429181 +-0.21462 -0.503542 0.152309 +0.243356 -0.495568 -0.445206 +0.0716057 -0.0660665 0.506455 +-0.0735383 0.160561 -0.501416 +-0.10095 0.170551 -0.492745 +-0.121432 -0.187683 -0.497208 +0.384179 -0.515462 -0.243549 +-0.0922762 -0.19825 -0.499258 +-0.505165 -0.103314 0.361009 +-0.440518 -0.13966 -0.48823 +0.507364 -0.352417 -0.121307 +0.486708 0.471232 0.0745881 +-0.482943 -0.302798 0.456854 +0.469914 0.465693 -0.371836 +-0.331179 -0.306275 -0.508503 +0.320231 0.0190402 0.510344 +-0.118713 -0.112974 0.504874 +0.406771 0.169869 0.497032 +-0.493221 0.256702 -0.206909 +-0.412968 -0.404353 0.503227 +-0.129531 0.0402712 -0.492337 +-0.0739979 0.273701 -0.501632 +-0.23092 -0.479624 -0.458175 +-0.222768 -0.506788 -0.152205 +0.491851 -0.327085 -0.439123 +0.50662 -0.241985 -0.215429 +0.476966 -0.472349 -0.141198 +0.475897 0.468758 0.459178 +-0.125271 -0.157366 -0.493953 +0.466195 -0.384627 -0.475812 +0.273407 -0.500319 0.307752 +-0.517793 0.334435 -0.320961 +0.469928 -0.484281 -0.113561 +-0.368486 0.483711 0.483806 +0.195329 -0.500182 -0.017652 +0.416414 -0.510908 -0.192701 +-0.0538128 -0.339086 0.502194 +-0.340501 -0.421692 -0.503757 +-0.324736 0.49485 -0.443475 +0.35809 0.208888 -0.513769 +0.143856 -0.480044 0.474289 +-0.398749 -0.324627 0.498431 +-0.129726 0.150228 0.502914 +-0.462683 0.492485 0.250235 +-0.271481 0.44302 0.486941 +-0.246975 0.431038 0.493421 +-0.0270675 0.394852 0.510492 +-0.0994795 -0.110173 -0.50615 +-0.500411 0.20773 -0.270084 +0.468346 -0.41593 -0.487478 +0.327126 -0.501998 0.0671992 +0.321472 -0.504931 0.0162387 +-0.470378 -0.4712 -0.143889 +-0.499093 0.426513 0.0457903 +-0.496772 0.143748 -0.00751674 +-0.479437 0.463973 -0.419202 +-0.389604 0.150327 -0.499642 +-0.0818206 0.473228 -0.491038 +-0.337989 0.36713 -0.501752 +0.294051 -0.49366 0.448756 +-0.346441 -0.482971 -0.455241 +-0.40471 0.34753 -0.501801 +0.238113 -0.49902 -0.420249 +0.00912699 -0.173731 -0.508617 +-0.246594 0.159236 -0.496726 +-0.290394 -0.513639 0.25632 +0.357355 -0.517529 -0.331132 +0.508875 -0.0554792 -0.341285 +0.113572 -0.500043 -0.281974 +0.0378708 -0.468551 0.476678 +0.26085 -0.504746 -0.249773 +-0.491555 0.00993286 -0.0803339 +0.116763 0.497197 -0.233363 +-0.45721 0.338889 0.48226 +-0.137459 -0.496283 -0.35066 +-0.397334 -0.501345 -0.186512 +0.503663 0.317957 -0.05426 +0.222593 -0.00598502 -0.506729 +0.434244 -0.494312 -0.314586 +-0.284564 -0.165501 -0.509611 +0.507601 -0.231515 -0.297836 +0.502879 -0.0103334 -0.230241 +0.506072 -0.291598 -0.322589 +-0.511748 0.278592 0.165372 +-0.227484 -0.402396 0.496878 +0.0503354 -0.50811 -0.292424 +0.313064 -0.466131 -0.480697 +-0.495964 0.12876 0.184807 +0.0313375 -0.184277 -0.504554 +0.0787984 -0.150546 -0.500516 +-0.187577 -0.505446 0.13311 +-0.159954 -0.507196 0.116077 +-0.507925 -0.204709 -0.198224 +-0.494524 -0.0590528 0.218836 +-0.505843 0.414951 -0.0599898 +-0.0657645 -0.357102 -0.498485 +-0.491576 0.191992 -0.182176 +-0.407031 -0.49853 0.446225 +-0.51482 0.251003 0.350367 +0.394594 0.501924 -0.42083 +-0.232428 -0.424077 0.491706 +0.507419 -0.353643 0.375302 +-0.500299 -0.423647 -0.218656 +-0.502911 -0.389448 -0.259998 +-0.409912 -0.505385 0.0980659 +0.355972 -0.507677 0.195581 +-0.246031 -0.385886 0.512505 +-0.282421 -0.122249 0.495832 +-0.468176 -0.223948 0.476459 +0.454463 -0.139706 -0.475615 +-0.464576 -0.494972 0.378412 +0.357275 -0.496878 0.229836 +-0.112494 0.31938 0.506468 +-0.491556 0.439374 0.0674945 +0.0149256 -0.162358 0.508752 +-0.301279 -0.511818 0.291309 +-0.139654 -0.495982 0.329685 +0.0284802 0.496287 -0.0987178 +-0.183048 -0.496971 0.356313 +-0.507894 0.246818 0.163268 +-0.508808 0.237049 0.134609 +0.00480958 -0.510601 -0.287083 +0.501636 0.437881 -0.359809 +-0.428806 0.0751311 -0.503331 +-0.158724 -0.49062 0.0834249 +-0.296232 -0.506689 -0.406283 +0.380676 -0.264095 -0.516287 +0.487265 -0.442416 -0.27802 +0.299828 0.0983032 0.499269 +0.33351 0.100212 0.509952 +0.31964 0.0716809 0.50715 +-0.14762 0.221271 -0.497336 +-0.139712 0.250904 -0.495051 +0.0780569 -0.49426 -0.0849627 +0.509771 -0.308546 0.193253 +0.244887 0.124851 0.50818 +0.379983 0.273343 -0.51403 +-0.502209 0.420777 -0.262337 +-0.0696993 -0.509949 -0.221298 +0.0339589 -0.49465 -0.110445 +0.490698 -0.193364 0.454793 +-0.164826 0.508278 -0.129115 +-0.486173 0.448254 -0.21753 +0.212326 -0.493013 -0.139235 +-0.502674 0.299521 0.404829 +0.465305 0.388501 -0.478279 +0.513872 -0.323689 0.216629 +0.462751 0.00256896 0.481167 +0.505348 0.036333 0.389145 +0.0391554 -0.387194 -0.513456 +-0.360392 -0.385294 -0.50288 +-0.310157 -0.356725 -0.508064 +0.472157 0.485878 0.0796619 +0.378175 -0.512077 0.419016 +-0.401141 0.0923739 0.498275 +-0.389704 0.119819 0.512948 +0.0157193 -0.477708 0.471899 +0.432983 -0.469307 -0.461726 +-0.124936 0.00265224 -0.49126 +-0.504919 0.0712765 -0.182028 +0.147864 -0.327066 0.512544 +-0.433733 -0.505285 -0.316708 +0.496548 -0.377978 -0.171977 +0.105312 -0.493348 0.259206 +0.515496 -0.214168 0.319655 +-0.494041 -0.462352 0.261614 +0.475525 -0.486812 0.400432 +0.04748 -0.509629 0.289089 +0.46831 0.478576 -0.0226913 +0.332998 0.10355 -0.51364 +0.458583 0.239292 0.477026 +-0.481614 -0.113655 -0.476534 +0.510651 -0.134836 0.414881 +0.385437 0.305957 -0.504676 +-0.396723 -0.495526 0.156042 +0.425773 -0.047321 0.493703 +0.483177 -0.0422246 -0.465979 +0.460112 -0.470452 -0.16898 +-0.504885 -0.166024 0.399468 +-0.445812 0.480027 -0.41544 +0.403244 -0.215729 -0.513127 +0.374533 -0.503703 0.443116 +-0.504256 -0.193561 0.404369 +0.431836 0.489039 0.460074 +0.195346 0.348701 -0.508302 +0.41045 0.428014 -0.500593 +-0.507858 -0.244738 0.262118 +-0.149476 -0.0161285 -0.49188 +0.439441 -0.0814351 -0.501078 +0.405109 0.508467 -0.0771707 +0.418166 0.508402 -0.0514563 +0.0383594 0.12662 -0.505325 +0.509079 0.371378 -0.299196 +0.232586 -0.504072 0.448892 +-0.507086 0.0515281 0.0823813 +0.502184 0.265271 -0.16067 +-0.511985 -0.346858 0.00539576 +-0.511625 0.323559 0.41963 +-0.133954 0.202179 0.495818 +0.226566 0.349439 -0.501127 +-0.412723 -0.0934708 0.507315 +-0.0867294 -0.49675 -0.153738 +-0.00133491 0.43802 -0.489236 +-0.465261 0.482267 -0.0712748 +-0.0994519 0.261024 0.505743 +0.499556 -0.290122 0.171537 +0.510491 -0.264158 0.148257 +0.485282 -0.454112 0.381948 +-0.4978 0.256395 0.116521 +-0.503771 0.296463 0.140806 +0.418166 -0.49348 0.433422 +-0.50313 0.37442 -0.276855 +0.451156 -0.486004 -0.239047 +-0.512262 -0.276796 -0.209301 +0.426318 -0.479588 0.450148 +-0.218993 -0.378104 -0.512737 +0.00841831 0.0977768 0.503385 +-0.273487 0.115121 -0.507319 +0.00660631 0.0638448 0.490346 +-0.07025 -0.492969 0.449481 +-0.304195 0.508469 -0.398327 +-0.00512728 -0.507861 0.0901858 +-0.495837 -0.426562 -0.188899 +-0.473536 -0.248082 -0.466436 +0.220265 -0.461944 -0.494156 +-0.496029 -0.225071 -0.424729 +0.50195 -0.157941 -0.0408449 +-0.0191466 -0.500583 0.442446 +0.18638 -0.449382 0.481259 +0.403526 -0.512259 -0.0154673 +0.0109646 0.196535 0.51012 +-0.511529 -0.0343679 -0.320521 +-0.147504 -0.208412 -0.496002 +0.44555 0.483929 0.4267 +-0.414444 0.0662453 0.50347 +0.489543 0.134097 0.0928638 +0.0889821 -0.496887 -0.43105 +0.502845 0.298738 -0.176824 +-0.200901 0.422923 -0.496413 +-0.508365 -0.275872 -0.042305 +0.110207 0.508184 -0.173493 +-0.50753 -0.316399 -0.00618334 +0.197479 -0.476895 0.458295 +0.136712 -0.457537 0.479784 +-0.481781 -0.466577 -0.0709846 +-0.191191 0.49235 0.0324655 +-0.243434 -0.493358 0.0631129 +-0.344379 -0.50546 -0.368814 +0.501582 0.295074 0.449036 +0.303864 0.438689 0.490765 +0.136863 0.508112 -0.252052 +0.0671448 0.164472 0.499099 +0.495738 -0.294872 0.216891 +-0.415735 0.493956 0.342682 +0.117715 0.136921 0.500886 +-0.0990809 -0.169065 -0.508099 +-0.0769062 -0.154212 -0.497859 +-0.10035 -0.14048 -0.49337 +-0.50363 0.0400211 0.0509514 +0.489908 -0.0261775 -0.452212 +-0.0637019 -0.309063 -0.496533 +0.111407 0.227449 -0.503805 +0.384801 0.161577 0.502136 +-0.506269 -0.298315 -0.28495 +0.110843 -0.506619 0.167396 +0.500027 0.321513 -0.455351 +-0.167916 0.149449 -0.498487 +0.383411 0.489615 -0.450939 +0.252331 0.498006 0.0437778 +-0.250831 0.374848 0.511398 +0.0342557 -0.107221 0.492195 +-0.440482 -0.489022 -0.418926 +-0.0774738 0.134568 0.497518 +-0.489518 -0.435909 -0.274723 +-0.239101 -0.499568 -0.431559 +-0.514062 0.025511 -0.39253 +-0.149019 0.47347 0.472672 +0.181599 -0.502156 -0.0467224 +-0.0381666 -0.469232 -0.471838 +-0.22849 0.103713 0.493965 +-0.502377 0.11323 -0.436114 +-0.493493 0.0884235 -0.413372 +-0.267435 -0.505618 -0.420401 +-0.178924 0.207879 -0.506563 +0.490233 0.445323 -0.0754957 +-0.367747 0.470217 -0.475404 +0.427295 -0.166489 -0.502907 +0.507536 -0.400966 -0.242379 +0.504683 -0.371217 -0.228564 +-0.217428 0.297453 0.503229 +-0.191157 -0.0543094 0.494501 +-0.158025 -0.0663997 0.501714 +0.24213 0.178765 0.493918 +-0.4436 -0.0607428 -0.493526 +-0.470378 0.350364 0.466733 +0.495632 -0.013136 0.332395 +0.40577 -0.502046 0.412608 +-0.50434 -0.250349 -0.2371 +0.0578904 -0.365265 0.503125 +-0.264887 -0.359408 -0.513876 +-0.284795 -0.344993 -0.504244 +0.227659 0.152155 0.500456 +-0.0594442 -0.492184 -0.156235 +-0.0139698 -0.504237 0.0638397 +0.0625794 -0.508233 -0.31752 +-0.129436 -0.506656 0.307504 +-0.111834 -0.508506 0.323477 +-0.356729 0.303886 -0.518795 +-0.457648 0.298507 -0.486508 +0.509195 -0.0792718 -0.0683686 +0.104962 0.20495 0.493202 +0.471454 -0.421835 0.464574 +0.232003 0.494444 0.226477 +0.0924657 0.148165 0.505983 +0.0386431 -0.139049 0.507109 +0.455411 -0.485551 0.194046 +0.485267 0.440064 -0.432087 +0.506627 0.304942 -0.112951 +0.496021 0.301392 -0.145296 +0.503797 0.272885 -0.123691 +-0.0278331 -0.491752 0.0830628 +0.480177 -0.460936 -0.259102 +0.0871938 0.231967 0.494582 +0.0377261 0.213937 0.495502 +-0.511476 -0.208259 0.271106 +0.499797 -0.40022 -0.276269 +0.386347 -0.504255 -0.345964 +0.412558 -0.503291 -0.328767 +-0.452023 0.481716 0.468427 +0.50816 -0.227862 0.288799 +-0.499411 -0.00256934 -0.326574 +0.187569 -0.49757 -0.348296 +-0.133673 -0.492388 0.132125 +0.141863 -0.0213173 0.497172 +0.453286 -0.226727 0.496672 +-0.465962 0.310108 0.491481 +-0.493004 0.266957 0.139315 +-0.122477 -0.436549 -0.497678 +-0.164401 0.497861 -0.450903 +0.0606492 -0.198426 0.496292 +0.0474846 -0.169129 0.499993 +0.473697 -0.487477 -0.248563 +-0.496942 -0.0204542 -0.0910334 +0.501421 -0.108566 -0.068403 +0.0238589 -0.506303 0.0985391 +0.441906 0.488368 0.150402 +-0.509463 0.041509 -0.0702484 +0.156003 -0.507382 -0.42789 +-0.507509 0.0541653 0.199943 +-0.492626 -0.116262 0.417819 +-0.505205 -0.0646681 0.391691 +0.0989121 -0.508662 0.12736 +0.0868011 0.385791 -0.503139 +0.487446 -0.0920974 0.466034 +0.455736 0.138484 -0.48285 +-0.160583 -0.496565 0.147489 +-0.370772 -0.490534 -0.471028 +-0.160191 -0.499175 0.17664 +-0.309023 0.226143 -0.511368 +-0.359696 0.195502 -0.511587 +0.423374 0.493931 -0.290267 +-0.0925817 0.0857081 -0.489881 +0.265489 -0.508687 -0.12792 +-0.507245 0.342677 0.32822 +0.456773 -0.483507 -0.142585 +0.472633 0.387924 0.482059 +-0.0994681 -0.493366 0.0513585 +0.479687 -0.0950573 -0.464179 +0.182472 0.232504 0.495037 +0.166291 0.206415 0.490193 +-0.150117 -0.510338 -0.370642 +-0.0112015 -0.504175 -0.168845 +0.49535 -0.400225 -0.397353 +-0.387113 0.177505 0.496481 +-0.478905 0.350075 -0.468121 +-0.470956 -0.0413451 0.485238 +0.492114 -0.443935 -0.340635 +0.435453 -0.474923 0.464375 +0.241861 0.119451 -0.505997 +0.179476 -0.282244 0.497118 +0.502598 0.327198 0.41511 +-0.1318 -0.494535 0.10024 +-0.105718 -0.493009 0.117428 +-0.102932 -0.506735 0.0852511 +-0.509162 -0.00932841 -0.0270201 +-0.498273 0.0165109 -0.0485099 +0.210441 -0.501403 0.367386 +-0.516602 0.320492 -0.37099 +-0.508127 -0.0961799 0.0563879 +-0.193895 -0.378637 0.496171 +0.507245 0.391679 -0.1659 +0.347826 0.226858 0.4985 +-0.494275 -0.286994 -0.084399 +0.266365 -0.507283 -0.383326 +-0.479632 -0.0370548 -0.46414 +-0.0347223 -0.498513 -0.142266 +-0.438839 0.0199555 -0.488587 +0.0323827 -0.502538 -0.0346123 +0.0142468 -0.507602 -0.0109959 +-0.497639 -0.128978 -0.015246 +-0.158729 0.186605 0.502078 +0.440374 0.352227 -0.501707 +-0.189867 0.184841 0.492118 +0.433277 -0.499942 0.0393781 +0.338962 0.14497 -0.509233 +-0.0338633 -0.503778 0.32198 +-0.0491812 -0.504961 0.350716 +0.221243 -0.468911 0.467893 +0.408658 0.508573 -0.266517 +0.419259 0.495295 0.143055 +0.208984 -0.495387 0.0122438 +-0.498441 0.351865 -0.0344871 +0.339612 -0.50537 0.093317 +0.402925 -0.202762 0.501508 +-0.480813 -0.439075 0.43682 +0.493464 -0.442388 0.199394 +-0.29036 -0.511158 -0.192755 +0.457329 0.483048 0.0515667 +0.326774 -0.188843 0.502213 +0.47944 0.477555 0.135435 +0.357216 -0.501363 0.0693742 +-0.501335 0.363464 0.358263 +-0.510057 -0.256543 0.0306754 +0.284261 -0.356441 0.505822 +-0.498943 -0.431372 -0.0696698 +-0.490877 -0.109154 0.441762 +0.00821664 0.465031 0.490984 +-0.508705 0.381858 -0.0463709 +0.127386 0.0781336 0.508392 +0.182216 0.0672102 0.503703 +-0.280244 -0.478557 -0.458645 +0.0310964 0.470961 0.478147 +0.241276 0.226375 0.498102 +0.055454 -0.137616 -0.49531 +0.214301 -0.436114 -0.492037 +-0.0305116 -0.4918 -0.252057 +-0.306348 -0.474181 -0.48135 +0.509868 0.115445 0.35469 +0.172582 -0.493365 -0.271111 +0.162239 -0.503255 -0.29897 +-0.269242 0.512602 -0.00022896 +0.133169 -0.500235 -0.305175 +-0.0379039 -0.0449318 0.503096 +0.106738 -0.339668 -0.505161 +-0.245043 -0.506564 -0.130915 +-0.293266 -0.507441 -0.0957901 +-0.491382 0.185639 -0.242514 +-0.507091 -0.220045 0.403373 +-0.0764033 -0.490136 -0.0386405 +-0.0927746 0.113378 -0.497673 +-0.0963822 0.141458 -0.498665 +-0.14298 0.33034 0.50111 +-0.194448 0.317481 0.503742 +-0.444709 0.491146 -0.307403 +0.503995 0.104695 0.0699366 +0.344284 0.196161 0.496824 +0.229949 -0.504419 -0.0149797 +-0.51153 0.331269 0.364209 +0.10806 0.483916 -0.476752 +-0.512031 0.300808 0.376686 +-0.426961 0.0913578 0.496185 +0.239345 -0.510082 0.0170048 +0.267505 -0.496701 0.0239551 +-0.50868 0.263416 0.305675 +-0.498515 0.222152 0.259811 +0.387762 0.468585 0.477677 +-0.0478353 -0.174012 0.501629 +0.511271 -0.410756 -0.131677 +0.493524 -0.0670087 0.144491 +-0.130383 -0.202285 0.503257 +0.0745782 0.0783066 -0.499231 +-0.16293 -0.193314 0.494333 +-0.479514 0.466223 -0.462404 +0.176762 -0.494403 0.252283 +0.221763 -0.508667 0.283738 +0.447819 -0.0627505 0.499461 +-0.497126 0.451185 0.123262 +-0.501567 0.225867 0.441761 +0.405407 -0.0597093 0.501937 +-0.302367 0.511974 -0.0494672 +0.407835 0.285176 -0.498096 +-0.493587 -0.463121 -0.13529 +-0.0388252 0.493661 -0.425414 +-0.503472 -0.421712 -0.142138 +0.485496 -0.452107 0.02697 +-0.513798 0.00621524 0.31266 +-0.506785 -0.00425552 0.282598 +-0.51286 0.0273614 0.287921 +-0.0243284 -0.500375 -0.19882 +-0.0412784 -0.49987 -0.224421 +0.289953 -0.505233 -0.104018 +0.509922 0.323339 0.156535 +-0.502563 0.198177 -0.301558 +-0.0683012 0.0703843 -0.506858 +0.199759 -0.496832 -0.0753315 +-0.508566 0.191157 -0.332484 +0.271892 0.181518 0.498989 +0.25998 0.153625 0.510592 +0.191576 -0.503043 0.0361501 +-0.504595 0.397002 0.00388823 +0.351437 0.502093 0.433018 +-0.0823108 -0.492553 0.196292 +0.508359 0.251267 0.409952 +0.509403 0.254839 0.364761 +0.492318 0.370907 0.444382 +-0.438885 0.495203 0.173041 +-0.214525 -0.30604 0.503016 +-0.199406 -0.494914 0.247687 +0.234878 -0.49945 0.406737 +0.199677 -0.5093 -0.2722 +0.442955 0.484325 0.305966 +0.502776 -0.320129 -0.168056 +0.509454 -0.312563 -0.145216 +0.375339 -0.225249 0.500974 +0.406506 -0.234116 0.49385 +-0.11642 -0.217282 -0.490846 +0.494944 -0.0506823 -0.0701234 +0.511504 -0.261801 -0.309321 +-0.483115 0.366115 -0.449224 +0.505491 0.00110585 -0.083884 +0.235408 0.494744 -0.165527 +-0.00890906 0.353049 0.508923 +0.0121087 0.329715 0.506626 +0.502669 0.028079 -0.0711673 +-0.0562069 -0.499747 0.181775 +0.515054 -0.361471 0.247682 +-0.127989 0.261934 0.497815 +-0.510451 0.305335 -0.129012 +-0.507509 -0.00297528 0.0073393 +-0.135758 0.296831 0.512604 +0.495272 -0.428715 0.25717 +-0.178891 0.447552 0.494284 +-0.388162 -0.393339 0.499754 +-0.269924 0.124643 0.494747 +-0.430739 -0.489513 -0.218776 +-0.450711 -0.488133 -0.197948 +0.490027 -0.430335 0.456248 +0.402164 0.503055 0.163087 +-0.405893 0.401999 0.502804 +0.439759 -0.502866 -0.142757 +0.482584 -0.461287 -0.35752 +0.413184 0.124657 0.503669 +-0.496132 0.023341 -0.0156671 +-0.491985 0.0310692 0.0175993 +-0.506334 0.0108567 -0.437021 +-0.172932 0.174187 -0.496479 +0.428004 -0.486516 -0.431366 +0.0346788 -0.303402 0.49791 +0.477091 0.45579 -0.430596 +-0.0774342 0.00235756 0.493154 +-0.0945874 -0.512819 -0.400884 +0.0519547 -0.496403 0.223236 +-0.443968 0.502073 -0.153962 +0.492499 0.449479 -0.410876 +0.0396538 -0.514313 0.35502 +-0.459231 -0.480164 -0.00832268 +-0.0160677 -0.504867 0.346734 +0.177226 -0.494136 -0.101298 +0.185433 -0.499434 0.354797 +0.209139 -0.503037 0.338179 +0.497738 -0.0242981 -0.408905 +-0.265187 -0.503039 -0.0770189 +-0.183269 -0.312399 0.511434 +0.45332 -0.485909 0.0370496 +-0.20806 0.444458 -0.500187 +0.0941982 -0.389199 0.51371 +0.246996 -0.486788 -0.468272 +-0.497025 0.424353 0.208916 +0.497963 0.128151 -0.142301 +-0.257463 0.209146 0.499537 +-0.264007 0.173133 0.497111 +-0.483762 -0.469241 0.0332359 +-0.299089 0.171484 0.493713 +-0.50394 0.174643 -0.277667 +0.344161 -0.49333 0.470361 +0.508515 -0.143396 -0.0721632 +-0.499156 -0.375501 0.456989 +-0.00347206 -0.0568146 0.49061 +0.0349757 -0.0694107 0.492935 +-0.150748 0.364445 -0.495644 +0.493774 0.171377 -0.10664 +0.492346 0.193404 -0.114816 +-0.453191 -0.484961 -0.227087 +0.490801 0.0446169 0.060085 +-0.197281 0.433893 0.502676 +-0.487699 -0.438793 -0.425136 +0.496882 0.145692 -0.0965865 +0.492372 0.123241 -0.113459 +0.505199 -0.158776 -0.362799 +-0.500398 -0.0418406 -0.171227 +0.444284 -0.374758 0.496567 +-0.439184 0.501113 -0.372056 +-0.494913 -0.0650266 0.411311 +0.0132021 -0.497021 -0.198602 +0.0488838 -0.491038 -0.181337 +-0.152603 0.0630994 0.505886 +-0.117847 0.12268 -0.495017 +-0.14811 0.130539 -0.505749 +-0.50102 -0.323157 0.269645 +-0.500201 0.431922 -0.422682 +0.0173067 0.329101 -0.498454 +0.461319 0.483973 -0.11377 +-0.472302 0.0437244 -0.476638 +-0.469078 -0.472563 -0.274581 +-0.482346 -0.449852 0.113954 +0.0471598 -0.498545 -0.216154 +-0.00129075 -0.495311 -0.258697 +-0.510177 0.032009 -0.421239 +-0.0703323 -0.31217 0.503076 +-0.184847 -0.494221 -0.433141 +0.332006 -0.371283 0.518742 +0.305317 -0.371114 0.512278 +-0.504361 0.0448745 0.347536 +-0.468489 0.474537 0.049913 +0.316304 0.340401 0.514605 +-0.182667 -0.365722 -0.497579 +0.263485 -0.453893 0.491392 +-0.458795 0.460735 -0.459767 +0.466888 0.298449 -0.480292 +-0.489931 -0.0847554 0.135684 +-0.503381 -0.0111674 -0.214104 +-0.490006 0.0824264 -0.466329 +0.137708 -0.504603 0.210864 +-0.29409 0.0118374 -0.508811 +0.474685 0.464517 0.186844 +-0.488477 0.272162 0.469365 +0.312437 0.511641 -0.347191 +0.430649 -0.497885 -0.0128112 +-0.423208 -0.504342 0.292984 +-0.507963 -0.261402 0.163084 +-0.490228 0.426683 -0.116892 +-0.438578 0.50162 0.242777 +0.458898 -0.364337 0.48559 +-0.491352 0.0846695 0.459648 +0.481063 -0.0323725 0.450453 +-0.495729 0.0560937 -0.00544293 +-0.41806 -0.150007 0.492583 +0.379649 0.491217 0.437206 +-0.318202 0.47307 0.474344 +-0.501204 0.112857 -0.0177465 +-0.296842 0.497581 -0.442769 +-0.209439 -0.135192 -0.494927 +0.226838 -0.497006 0.232089 +0.496026 -0.074647 0.332354 +0.0782504 0.449006 0.492262 +0.0291129 0.0485143 0.509632 +0.490803 0.443967 0.338322 +0.0441813 0.197994 -0.491985 +0.101989 -0.0851123 -0.491407 +-0.492093 0.300196 0.453713 +-0.48818 0.162996 -0.442048 +-0.490803 0.231089 -0.468961 +-0.131105 0.333751 -0.50162 +-0.157001 -0.507025 0.0505732 +-0.128251 -0.500035 0.0340612 +0.371805 0.451984 -0.49038 +0.292731 -0.209958 -0.507012 +0.14645 -0.446834 -0.482508 +-0.171219 -0.158701 0.509534 +0.486927 -0.450766 -0.106023 +0.507099 0.44389 0.363241 +0.192609 -0.193903 -0.493187 +0.456461 -0.438585 -0.47388 +0.459331 -0.0529797 0.480216 +-0.513472 -0.0752765 0.335693 +0.47343 0.462802 -0.448378 +-0.0110324 -0.257648 -0.501452 +0.475863 -0.430129 -0.45563 +-0.102597 0.484326 0.466624 +-0.160938 -0.397896 -0.507875 +-0.194121 -0.402586 -0.504358 +-0.152884 0.464474 -0.474243 +0.206396 -0.4898 -0.108879 +-0.412174 0.129791 -0.510229 +0.462122 -0.357199 -0.479774 +-0.503839 0.277781 -0.110223 +-0.11508 -0.510602 -0.294337 +0.47448 0.0313656 -0.46719 +-0.445683 0.496713 0.150367 +0.122557 -0.189516 0.508737 +-0.515745 0.287334 0.314699 +0.0769251 -0.17285 0.505912 +-0.480043 -0.471369 0.00275415 +0.226241 -0.494417 -0.0641645 +0.211972 -0.504005 -0.0438276 +-0.353976 -0.190225 0.500517 +-0.329139 -0.163386 0.509716 +0.49278 0.440572 0.0277743 +-0.502241 -0.110743 0.325405 +-0.507596 -0.119111 0.291605 +0.122176 0.471973 0.480013 +-0.105169 -0.48845 -0.446027 +0.482499 0.478167 0.0532297 +-0.488355 -0.471327 -0.346517 +-0.468555 0.402 0.479094 +0.417754 -0.509483 0.386758 +-0.496997 -0.414004 0.325588 +0.399081 0.487766 -0.435951 +0.243935 -0.508994 0.208796 +-0.298049 -0.500282 -0.437568 +0.169045 -0.184844 0.504285 +-0.503758 -0.307535 -0.0366763 +-0.298416 0.508441 -0.11126 +0.182643 -0.427956 0.503168 +0.496776 0.0727507 -0.176186 +0.207949 0.16729 -0.506366 +-0.479466 -0.461461 0.0633404 +0.00322549 -0.367089 -0.499936 +-0.487951 -0.443936 0.0964702 +-0.0306745 -0.332549 -0.495146 +0.49128 -0.423392 -0.429432 +0.135788 0.206774 0.490356 +-0.441483 0.442027 0.495166 +0.243967 -0.492615 0.467388 +0.314752 0.470103 0.472036 +-0.50015 -0.0257089 -0.119845 +0.495547 0.0669785 0.407918 +-0.118843 0.492147 -0.469576 +0.327416 0.517073 -0.291859 +-0.2748 0.262608 0.505907 +-0.302934 0.258234 0.5096 +-0.471251 0.0761752 -0.481272 +-0.292212 0.278896 0.51373 +0.308435 -0.354594 -0.510596 +-0.426214 -0.0886704 -0.498808 +-0.323876 -0.502943 0.205444 +-0.29384 -0.502628 0.218608 +-0.43612 0.460834 0.489125 +-0.0593427 0.439913 -0.493851 +-0.389996 -0.296129 0.502974 +-0.360542 -0.293093 0.506489 +-0.0149632 0.181155 0.492691 +0.416859 0.148837 -0.505762 +-0.21637 0.456771 0.481711 +-0.0172926 0.150549 0.507758 +-0.067243 0.161071 0.491726 +0.474873 -0.221883 -0.484308 +-0.499491 0.375339 -0.0151069 +0.496966 -0.140086 0.230824 +-0.491945 0.180561 0.0302305 +-0.478271 -0.272068 0.462991 +-0.500478 0.150781 0.0227319 +-0.408665 0.0114465 0.494754 +0.399344 -0.259022 -0.498209 +-0.449953 0.0522979 -0.489456 +0.201133 0.46425 0.477379 +0.412941 -0.241129 -0.50593 +-0.1104 0.508166 0.383344 +0.412099 -0.502181 -0.361723 +0.49182 -0.111474 -0.449934 +0.0054591 -0.447135 0.486143 +0.478805 -0.448087 0.42458 +0.118461 -0.0443019 0.493665 +0.494108 -0.413938 -0.0833304 +0.472221 0.476048 -0.187506 +0.50237 -0.436932 -0.0936661 +0.26989 -0.0991985 -0.501121 +0.181851 0.275299 -0.493039 +0.46463 -0.440646 0.47765 +0.180775 0.45652 0.49387 +0.490345 -0.440305 -0.422966 +-0.435146 -0.396087 -0.507325 +-0.509216 0.106403 -0.173014 +-0.178239 0.487559 0.441663 +0.297997 0.126995 -0.512429 +0.270852 0.123842 -0.509828 +0.289539 0.10233 -0.496461 +0.0666167 0.510583 -0.280159 +0.340975 -0.0491505 0.497562 +-0.160405 0.396793 -0.504964 +0.490433 0.006292 -0.0266519 +0.44966 0.489006 0.213437 +-0.438264 0.488283 0.049017 +-0.490447 -0.425105 0.0280085 +0.317348 -0.0534184 0.503866 +0.396393 0.0929882 -0.504406 +-0.212604 -0.50082 0.0488882 +0.488232 -0.414086 0.438012 +0.501965 -0.294722 0.399513 +-0.185851 -0.507206 0.0666361 +-0.513187 0.363957 -0.326533 +0.33727 -0.122792 0.502389 +0.425945 -0.421811 0.505229 +-0.0462206 -0.209629 0.508153 +-0.509207 0.343755 -0.348851 +0.431696 0.501055 -0.344441 +-0.508812 -0.374248 0.395853 +-0.51424 0.219384 -0.323177 +0.0351007 -0.507036 0.386069 +0.389346 0.497715 -0.24494 +-0.267942 0.346864 -0.513165 +-0.300961 0.368889 -0.515774 +-0.484218 0.300577 -0.483874 +0.451095 -0.34283 0.500822 +0.515075 -0.112747 -0.352148 +-0.307963 0.097483 0.512716 +0.105468 -0.493586 -0.450772 +0.101138 0.134007 -0.492481 +0.455753 0.368532 -0.499867 +-0.307258 -0.326861 -0.51531 +-0.508259 -0.0552982 0.304813 +-0.511203 -0.0875885 0.299608 +-0.497216 -0.40922 -0.168727 +0.452729 -0.497275 -0.266136 +0.241816 -0.439609 -0.486256 +-0.502635 -0.348396 -0.44642 +-0.0518564 -0.445042 -0.490034 +-0.0698578 0.130364 -0.500786 +0.270662 -0.450115 -0.500496 +0.0121696 0.373294 -0.505789 +0.101184 0.348778 0.504183 +-0.06328 0.390982 -0.504788 +0.312168 0.289261 -0.517223 +-0.121469 -0.233012 0.498187 +-0.326503 0.121512 0.50338 +0.504514 -0.0840015 -0.361057 +-0.312312 0.146628 0.512228 +-0.297207 0.123245 0.49492 +-0.295429 -0.506152 -0.380577 +-0.269323 -0.506888 -0.39056 +-0.321243 -0.502942 -0.388252 +0.0700977 0.498007 0.374545 +-0.325695 0.396938 -0.504148 +-0.349284 0.440809 -0.490639 +-0.454919 0.0933691 0.50241 +0.314675 -0.462156 0.485821 +-0.0789658 0.473608 0.469083 +-0.186154 -0.502363 0.16476 +0.510386 -0.324171 -0.305732 +-0.490048 -0.0456034 -0.0721302 +-0.499473 -0.0411789 -0.0397132 +-0.0271654 -0.495101 0.106797 +-0.485325 0.471045 -0.0204713 +0.507277 -0.415513 0.354086 +0.229454 -0.491377 -0.0887568 +-0.0497603 0.181268 -0.50812 +-0.00233884 0.199097 -0.499208 +-0.0572858 0.212608 -0.498177 +0.339119 0.304352 -0.509174 +0.366224 0.10164 0.501296 +-0.107976 -0.26063 0.510798 +-0.0883153 -0.286133 0.511673 +0.375056 0.0693086 -0.512295 +-0.209961 0.514355 0.364825 +0.253591 0.501347 -0.274551 +0.449886 0.488489 -0.0232315 +-0.487078 -0.452405 -0.297627 +0.362052 -0.24383 -0.501365 +-0.413921 -0.059385 -0.49897 +0.373102 -0.211729 -0.509977 +0.341095 -0.22154 -0.510333 +-0.117678 0.0507167 0.502374 +0.505631 0.435114 -0.156226 +-0.0451646 -0.493104 -0.0287932 +-0.0169731 0.210802 0.507754 +-0.303568 -0.148038 -0.510951 +0.421581 0.492594 -0.445339 +-0.452224 0.071257 0.482822 +-0.488811 0.0601558 0.453563 +-0.492128 0.138177 -0.0391721 +-0.485732 -0.153497 0.439528 +-0.49044 -0.145999 0.417871 +-0.501467 0.242632 -0.26063 +0.424192 -0.494649 -0.458093 +-0.509936 0.261814 -0.290166 +0.502734 -0.10012 -0.302121 +-0.5088 0.216081 -0.243951 +0.486907 0.047111 0.444032 +0.509771 -0.240419 0.227476 +0.498395 -0.235798 0.198292 +-0.500134 0.185423 -0.208715 +-0.50617 0.212547 -0.0814497 +-0.186556 0.501111 0.343518 +-0.276418 0.321882 0.505155 +0.0114591 0.444783 0.499344 +0.373616 -0.506008 0.0429552 +0.405437 -0.506851 0.042587 +0.484704 0.348547 0.447763 +-0.510985 -0.40183 0.269544 +0.023844 0.00125808 -0.493404 +0.0142419 0.0326248 -0.505329 +0.202298 -0.48133 -0.467156 +-0.508312 -0.260704 0.106956 +0.479331 0.476393 -0.0468049 +0.509264 -0.39241 0.299865 +0.266534 -0.266655 -0.508197 +0.500321 0.0473958 -0.158936 +0.494535 0.0188439 -0.169805 +0.180983 -0.50953 0.328695 +0.476182 -0.445547 0.446715 +0.172111 -0.501359 0.303771 +-0.26271 0.384052 -0.510952 +-0.225061 0.397865 -0.495268 +-0.507126 0.256196 -0.0973395 +-0.23946 0.324862 -0.510328 +-0.187274 0.324932 -0.510858 +-0.477569 -0.0781867 0.463481 +-0.181474 0.351641 -0.506842 +0.507442 0.143922 -0.435894 +-0.377968 0.400379 -0.496029 +-0.511642 0.286879 -0.209389 +-0.483653 -0.462219 0.404403 +0.116788 -0.507384 -0.123002 +0.0985956 -0.492931 -0.104525 +-0.149876 -0.507088 -0.195306 +-0.179399 -0.50201 -0.198358 +-0.166458 -0.504211 -0.16686 +-0.130674 -0.502097 0.209048 +-0.156698 -0.502584 0.203545 +-0.143929 -0.501652 -0.245216 +-0.132012 -0.505753 -0.218778 +0.261313 0.0962269 -0.499933 +-0.164619 -0.490448 -0.132701 +-0.432165 -0.0761487 0.499236 +-0.435642 0.160472 0.489844 +-0.239643 -0.509238 -0.405376 +-0.187898 -0.486803 -0.452009 +0.492187 0.454793 0.00148661 +-0.511362 -0.245492 -0.0498324 +-0.490821 -0.212375 -0.0589036 +0.307645 -0.00511369 0.50728 +0.0261602 0.497937 -0.236419 +-0.084107 0.504958 -0.162869 +-0.162844 -0.384788 0.509217 +-0.466398 -0.400062 0.472574 +0.503829 0.396712 0.0955677 +-0.183107 0.500997 -0.189769 +0.504492 0.372289 0.245763 +0.315105 -0.214368 0.495501 +-0.489099 -0.0407381 0.454442 +0.109043 -0.499277 -0.179697 +-0.107945 0.508157 -0.139902 +0.0804004 -0.50926 -0.161058 +0.394422 -0.462697 -0.481721 +0.111743 -0.491806 -0.149816 +0.0464698 -0.412151 -0.508545 +0.494121 -0.275111 -0.22152 +0.513055 -0.283686 -0.254476 +0.249443 -0.501503 0.126747 +0.256297 -0.505406 0.158716 +-0.209431 -0.498982 -0.20397 +0.365125 0.346753 0.505848 +0.310602 0.495605 0.0352461 +-0.492466 -0.224863 0.445846 +-0.372261 -0.473605 -0.489024 +0.428174 0.177632 0.492246 +-0.385854 -0.183786 0.499046 +0.394862 0.477533 -0.463139 +-0.415711 -0.174593 0.506906 +-0.494961 0.0984116 0.228164 +-0.494476 0.172842 0.00238029 +-0.499744 0.114206 0.205041 +0.207909 0.490093 -0.457672 +0.0885639 -0.040415 0.490389 +-0.0749538 0.494366 -0.132584 +-0.506006 -0.155636 -0.419923 +-0.216816 0.0724128 -0.500308 +-0.317663 -0.0549078 -0.510279 +-0.196085 0.100871 -0.492125 +-0.505567 -0.142237 0.313995 +0.445286 0.423031 0.484711 +0.356212 0.259568 0.510425 +0.465365 0.164109 0.48107 +-0.287931 -0.0738139 -0.499021 +0.347149 0.307471 0.500679 +0.428667 0.40612 0.499585 +0.377606 -0.338243 0.502149 +0.423027 -0.356105 0.494223 +0.501146 0.212008 -0.190868 +0.505893 0.255575 -0.217 +0.458148 0.487285 -0.439025 +0.05249 -0.509239 -0.0973883 +-0.514247 0.330414 -0.0804362 +-0.510795 0.3043 -0.0963321 +0.395461 -0.504635 -0.0703301 +-0.362004 -0.0115441 0.513412 +0.00376305 -0.353038 0.495911 +-0.356653 -0.0623701 0.509947 +-0.401589 0.496088 -0.033658 +0.506843 -0.0256624 0.117918 +0.508551 0.0720068 0.0812636 +-0.237963 0.49891 -0.17212 +0.50413 0.39307 -0.318332 +-0.510252 0.370608 0.280227 +-0.505185 0.397886 0.273753 +0.394899 -0.505238 -0.428234 +-0.00904911 0.00963603 -0.496029 +-0.204817 0.51153 -0.254161 +-0.0371797 -0.0115937 -0.498598 +0.135232 0.241851 -0.499131 +-0.0728726 -0.499507 0.0714565 +-0.0502116 -0.504421 0.0914571 +-0.0426506 -0.491386 0.0633276 +0.374845 0.499326 0.314217 +0.491636 -0.0411748 0.240243 +-0.477622 0.42976 0.454751 +-0.505966 -0.127173 -0.409541 +-0.498693 -0.0778479 -0.389698 +0.49262 0.197897 -0.429657 +0.486528 0.155937 -0.449243 +0.335073 -0.516426 -0.389687 +0.360097 -0.518659 -0.366485 +0.483253 -0.377438 0.459755 +0.334679 0.00304796 -0.512904 +0.322513 -0.0181639 -0.510908 +0.422814 0.316927 0.504994 +-0.153485 -0.109442 -0.504959 +-0.126702 -0.126038 -0.506228 +-0.503281 0.325633 0.147268 +-0.513499 0.378643 0.141112 +-0.314226 -0.0908365 -0.508403 +-0.502646 0.327222 0.176345 +0.49479 -0.105761 0.0978086 +0.495604 0.392964 0.149635 +-0.292586 0.478455 0.485848 +-0.51296 -0.334939 -0.372177 +0.446075 -0.0882108 0.499158 +0.44505 -0.485635 -0.168446 +-0.501875 -0.100439 -0.221993 +0.477565 0.340074 -0.46509 +-0.504576 0.0628203 -0.258171 +0.329996 0.199843 -0.497355 +-0.510971 -0.409045 -0.403978 +-0.378891 -0.510152 -0.405956 +-0.442857 -0.371199 -0.490771 +0.515232 -0.235791 -0.329227 +0.1832 -0.0664992 -0.506672 +0.50778 -0.425942 -0.323725 +-0.0867368 -0.498237 -0.370302 +0.475094 0.462065 -0.0715158 +0.331883 0.171005 -0.496006 +-0.064237 -0.194167 -0.490477 +0.464835 -0.19363 -0.492531 +-0.0467777 -0.213616 -0.495163 +0.299221 0.181433 -0.512409 +-0.512346 -0.20351 -0.365267 +-0.030463 0.476199 -0.487441 +-0.154206 -0.506104 -0.267427 +0.392416 0.3339 0.51014 +0.295619 -0.505159 0.385232 +-0.442067 -0.489966 -0.443249 +-0.44461 -0.477435 -0.460082 +-0.0714975 0.503205 0.142031 +0.295901 -0.517218 0.355152 +-0.496257 0.428796 -0.168488 +-0.16998 0.425897 0.501778 +-0.0447487 0.14909 -0.50099 +0.410135 0.464088 -0.47216 +-0.0960846 -0.434796 -0.503507 +0.493299 0.0315076 -0.0430278 +0.496713 0.0326303 -0.0142344 +0.473268 0.218773 0.472575 +0.408465 -0.497321 -0.143344 +0.399639 -0.499205 -0.216865 +0.460856 -0.465493 0.455054 +-0.496942 0.0480371 -0.156143 +0.481296 0.454477 -0.351497 +0.424287 0.486661 -0.203709 +0.272367 0.485288 0.443371 +0.270251 0.503692 0.370856 +0.352804 -0.487624 0.446571 +0.389554 0.402522 -0.497037 +0.504412 -0.229571 0.347169 +0.498163 -0.254876 0.319999 +-0.506612 0.243889 0.377727 +-0.494629 0.0950805 0.149305 +0.274545 0.447938 0.500784 +0.322384 -0.502826 -0.113266 +-0.492395 -0.468894 0.233555 +0.46199 0.164381 -0.485008 +-0.336544 -0.398408 -0.513491 +0.507686 -0.332086 -0.0390025 +-0.512739 -0.176659 -0.37907 +-0.0869458 0.210769 0.499268 +-0.0785244 0.24437 0.501173 +-0.0501242 0.221963 0.496727 +-0.0966141 -0.313112 0.495231 +-0.15016 -0.322695 0.495807 +-0.508522 0.374217 -0.353917 +-0.428553 -0.505521 0.40429 +-0.0490322 -0.496935 -0.272852 +-0.486749 0.452413 0.455752 +-0.455498 0.464908 0.468248 +-0.0134513 -0.180419 -0.499493 +-0.2491 -0.491513 0.424931 +-0.498529 0.116415 -0.139299 +-0.433631 0.504016 -0.108163 +0.0622029 0.494973 -0.247759 +0.505169 0.407409 0.382126 +-0.20649 -0.4914 0.21642 +0.441575 0.492738 -0.234658 +-0.430598 0.496862 -0.398879 +0.33519 -0.50031 -0.174668 +-0.182865 -0.506596 0.194773 +-0.211156 -0.501405 0.184651 +0.23657 -0.511333 0.383377 +0.266853 -0.500546 0.36935 +0.503218 0.383869 -0.408917 +-0.47092 0.432955 -0.463604 +-0.0112929 -0.021703 0.492098 +0.237858 -0.51484 0.352196 +-0.50796 0.159889 0.052851 +-0.507549 0.423651 0.27425 +-0.452304 0.458884 0.484563 +0.507062 -0.290593 -0.348378 +-0.115581 -0.495134 -0.243814 +-0.0997668 -0.490576 -0.215045 +-0.46919 0.150855 0.481402 +0.432143 0.493137 -0.0775979 +0.368448 -0.50856 -0.274503 +0.500588 -0.00617177 -0.315196 +-0.500157 0.183105 0.148778 +-0.502378 -0.201547 -0.392898 +0.487097 -0.455924 -0.437458 +-0.447427 -0.00103934 -0.481233 +-0.498051 0.215306 0.156566 +-0.491944 0.174672 0.205952 +-0.50736 0.142933 0.206178 +-0.467448 0.458951 -0.46994 +-0.501275 0.192646 0.179474 +-0.513903 -0.264844 0.289263 +-0.497969 -0.294209 0.280039 +-0.496542 -0.274462 0.264562 +-0.486164 -0.447825 0.289258 +-0.459879 -0.493127 -0.43262 +-0.502798 0.0360651 -0.187662 +-0.508648 0.0194327 -0.21641 +0.230979 0.25295 0.493789 +0.490897 0.0589756 -0.0292117 +0.0213645 -0.491135 -0.161424 +0.289763 -0.496422 -0.185522 +0.305589 -0.51234 -0.166234 +-0.509746 0.00343584 -0.189521 +-0.507262 -0.0142624 -0.166555 +0.222347 -0.503684 0.0433906 +0.475319 -0.470781 0.0713649 +0.220167 -0.492549 0.0755449 +0.43667 -0.499882 0.104075 +0.426093 -0.505572 0.132227 +0.367597 -0.503031 0.145956 +0.265172 0.17516 -0.496429 +0.236093 0.169939 -0.493478 +0.253117 0.147059 -0.509766 +-0.400997 0.504696 0.316274 +0.430993 0.180029 -0.503627 +0.406581 0.245547 -0.512555 +0.21123 0.17833 0.508852 +-0.355389 0.514632 0.30502 +0.19785 -0.473054 -0.484365 +-0.409838 0.501756 0.287246 +-0.0175253 0.456285 -0.487655 +-0.215296 0.129267 0.504731 +-0.184229 0.131696 0.50133 +-0.198221 0.103124 0.499474 +-0.46742 -0.491061 -0.252544 +-0.492251 -0.367961 -0.459977 +-0.492965 0.0968941 -0.207605 +-0.507739 0.0911123 -0.241539 +-0.456317 -0.395139 -0.494362 +-0.182104 0.0716887 -0.493295 +-0.414154 0.496595 0.461497 +0.504583 0.0744625 -0.146546 +0.491816 0.0997426 -0.130973 +-0.0646471 -0.507559 -0.133285 +0.390422 -0.256389 0.508608 +0.404942 -0.282093 0.511029 +-0.209084 0.497386 -0.416822 +-0.014734 0.484665 -0.472655 +0.0917649 -0.499213 -0.131148 +-0.392903 -0.0826388 0.49708 +-0.400709 -0.041276 0.49629 +-0.440183 -0.498811 -0.159385 +-0.438286 -0.489178 -0.133909 +-0.49164 -0.174202 0.195842 +0.483407 -0.327807 -0.46022 +0.308208 0.255275 -0.497533 +0.335486 0.232411 -0.497525 +0.256086 -0.370673 0.501182 +0.478953 0.481875 0.352725 +-0.475371 -0.483809 -0.23112 +-0.317702 -0.39579 0.513426 +-0.218658 0.501589 -0.394884 +-0.422468 -0.500397 -0.0761173 +0.0241002 -0.497318 0.0175828 +0.0542509 -0.506451 0.0235032 +-0.450415 -0.0572623 0.490895 +-0.472152 0.108842 0.490596 +-0.509807 -0.166082 0.223944 +0.503274 0.209331 -0.372419 +-0.489732 0.449226 -0.170636 +-0.454752 0.168087 0.484252 +-0.459776 0.189657 0.484167 +0.135102 0.298871 -0.497611 +-0.495113 -0.143874 -0.18425 +-0.477827 0.158651 0.46363 +-0.509758 -0.238063 -0.204192 +0.0242734 -0.427218 0.490246 +-0.124392 0.0869657 0.499241 +-0.12863 0.121087 0.502071 +-0.0972826 0.109876 0.500798 +0.445007 0.496759 -0.315502 +-0.221832 0.358755 0.512082 +-0.173888 0.339416 0.500573 +-0.50781 0.106048 -0.049943 +-0.507921 0.0809778 -0.027845 +-0.501311 0.0736676 -0.0601634 +0.416203 0.510777 0.000379014 +0.505816 0.435552 -0.183426 +0.22619 0.447348 -0.499152 +-0.213794 -0.500945 -0.449026 +0.0594959 -0.464114 0.492075 +0.111149 0.286303 -0.503621 +0.148983 -0.423424 0.493375 +-0.428275 0.481565 -0.455161 +-0.508044 -0.180166 0.168046 +0.138733 -0.405524 0.493401 +-0.300716 -0.26908 -0.496988 +0.0355891 0.50846 -0.267067 +-0.350692 0.509336 -0.433381 +0.439436 -0.382241 -0.498105 +-0.501509 0.0165471 -0.357184 +-0.421083 -0.492303 0.20025 +-0.509652 -0.331171 0.18375 +-0.451188 -0.490377 0.205954 +-0.43226 -0.495912 0.232866 +-0.314475 0.492889 -0.468091 +0.2944 0.43785 -0.495856 +0.369938 -0.50532 0.0975088 +-0.499863 -0.419968 -0.112651 +-0.491408 0.136375 0.075446 +-0.489351 0.436926 0.401073 +0.135846 0.156931 0.490482 +-0.463146 -0.479425 -0.469802 +0.417195 -0.49889 0.162209 +0.195643 0.152375 0.509231 +0.190837 -0.167638 -0.505831 +0.090148 -0.474327 0.459026 +0.178574 0.125548 0.508399 +0.31739 0.401977 -0.51152 +-0.507914 0.413672 0.178661 +0.0984753 -0.413718 0.508793 +0.41702 0.506265 -0.319755 +-0.435648 -0.283181 0.496059 +-0.108703 0.489215 -0.426122 +-0.409511 -0.16702 -0.493328 +0.091755 0.307949 -0.499715 +-0.494932 -0.203279 -0.285227 +-0.438939 -0.312205 0.490915 +-0.494243 -0.15954 -0.244294 +0.423954 -0.492627 -0.268319 +0.399704 -0.507665 -0.27217 +0.479733 0.460961 0.445987 +0.411585 -0.497893 -0.243416 +0.051793 -0.415328 0.497707 +0.0744832 -0.402419 0.494381 +0.361449 0.321055 -0.512981 +-0.477579 0.0601849 -0.464049 +0.387166 0.342142 -0.507663 +0.353192 0.349117 -0.503621 +-0.356241 0.172858 0.508955 +-0.501578 0.349886 -0.432697 +-0.504584 0.353885 -0.377868 +-0.496831 0.334907 -0.456383 +0.483023 0.0641811 0.463963 +-0.156797 -0.504412 -0.0439322 +0.50994 -0.38261 0.0316057 +0.4972 -0.0193774 -0.0113116 +0.505172 0.00829688 0.00229433 +0.125043 -0.503007 0.127861 +0.493198 0.01161 -0.204081 +0.491861 0.451134 0.198296 +0.112013 -0.49981 0.104017 +-0.147923 -0.176077 -0.505189 +-0.156028 -0.144916 -0.508514 +-0.191717 -0.182878 -0.500899 +-0.450179 0.489436 -0.443884 +0.504537 0.337861 -0.379635 +0.509843 0.388711 -0.353514 +-0.490706 -0.163967 -0.161963 +-0.498499 -0.184022 -0.110446 +-0.503354 -0.212722 -0.125594 +0.507848 -0.273651 0.243615 +0.343984 -0.371593 -0.517254 +0.513474 -0.264623 0.280804 +0.11999 -0.506927 0.431758 +0.374238 0.184579 -0.514576 +0.363766 0.136236 -0.505966 +0.390336 0.125419 -0.497976 +-0.498352 0.104866 0.0667146 +-0.504525 0.0732828 0.0585682 +-0.0650502 -0.0678758 0.507236 +0.0278607 -0.490653 -0.132242 +0.497647 -0.157408 0.370732 +-0.405819 0.505321 0.214173 +-0.491519 0.0143604 -0.454202 +-0.420358 0.506506 0.187982 +0.271399 0.241142 -0.501975 +0.249998 0.219152 -0.510742 +0.504813 -0.00677104 -0.290286 +0.272766 0.205549 -0.494741 +-0.0248324 0.491663 -0.0184156 +-0.276121 -0.498994 0.28356 +-0.2271 -0.507528 0.310999 +-0.485495 0.473713 0.205641 +-0.151514 0.363544 0.497013 +0.467019 -0.47389 -0.343519 +-0.23972 -0.499003 -0.452175 +-0.0657404 0.456741 -0.488247 +0.510793 0.107029 0.333336 +-0.269091 -0.510868 -0.220704 +0.210051 0.46362 -0.492656 +0.502398 0.175724 -0.2951 +-0.0401762 -0.425529 -0.499672 +-0.00748346 0.505813 0.0433708 +0.489678 -0.442346 -0.251801 +0.196637 0.445399 -0.493199 +-0.444173 0.499462 0.0927033 +-0.327891 -0.512136 0.145387 +0.337767 0.512382 0.274167 +-0.495119 -0.406007 -0.0249715 +-0.0120597 -0.494601 -0.444579 +-0.501589 -0.0932507 0.028368 +-0.494702 -0.0958889 -0.0020036 +0.318127 0.507766 0.0590242 +0.0342304 -0.494772 0.0464142 +0.33171 0.513404 0.240461 +0.0145712 -0.500381 0.0691397 +-0.210709 -0.508869 0.359885 +0.503653 -0.0238905 -0.430721 +-0.197049 -0.0205334 0.492159 +-0.496071 0.357329 0.453337 +-0.511346 -0.310782 -0.194513 +-0.500536 -0.285906 -0.247422 +0.0247433 -0.428098 -0.494001 +-0.449275 0.444312 -0.487485 +-0.243772 0.462171 -0.48381 +-0.499673 0.399625 0.432456 +0.217226 0.506531 0.361096 +0.211516 0.425902 -0.505527 +0.242767 0.422773 -0.496212 +-0.501959 0.134768 -0.322845 +-0.50626 0.140938 -0.287939 +-0.509647 -0.370247 0.0571793 +-0.441886 0.0682018 0.505573 +-0.500795 -0.403063 0.00902614 +-0.320923 0.501741 -0.354215 +0.158125 -0.314915 -0.502483 +0.00844726 0.494372 -0.0119194 +0.51582 -0.336732 0.237359 +-0.472552 0.0159419 -0.464869 +-0.173151 0.497734 -0.158892 +-0.172111 0.421658 -0.502708 +-0.445816 -0.494497 -0.100687 +-0.344175 -0.508734 0.018904 +-0.499612 0.200063 0.293542 +-0.483683 0.103983 -0.479299 +-0.455243 0.489023 0.03781 +0.498831 0.393618 0.451679 +-0.455803 0.490167 0.0679169 +0.105208 0.024795 -0.494398 +-0.508449 0.218909 -0.00506474 +0.471882 -0.470788 0.038786 +-0.267303 -0.493923 0.196291 +-0.241207 -0.494306 0.17379 +-0.494631 -0.450771 0.21075 +-0.234481 0.361415 -0.511815 +-0.169683 -0.428577 -0.498887 +-0.484297 0.44207 -0.143207 +-0.495609 -0.148096 0.0103008 +-0.145441 0.0267218 0.496571 +-0.464079 0.480631 -0.128314 +-0.508637 -0.401861 0.384931 +0.464863 0.471099 0.108568 +0.499345 0.0241541 0.330606 +-0.141112 0.501213 -0.149204 +0.499974 -0.176131 -0.0132206 +0.49664 -0.210601 -0.0174723 +0.430998 -0.48744 -0.405765 +0.37288 0.512839 0.362504 +0.00352408 -0.444691 -0.486749 +0.494466 -0.243627 -0.0257694 +-0.492818 -0.0106593 0.196704 +0.498036 0.450748 -0.169611 +-0.420362 -0.507283 0.0121417 +-0.412232 -0.506947 -0.0425591 +0.450839 0.0578097 0.480551 +-0.149938 0.505579 -0.181198 +-0.497601 -0.218376 0.238419 +-0.510583 -0.148219 0.282727 +-0.151534 -0.264098 -0.499243 +-0.42265 -0.140427 -0.499152 +0.355222 -0.503242 -0.446671 +-0.254831 -0.38555 -0.508893 +-0.260325 -0.418511 -0.502665 +0.205977 -0.24743 -0.510486 +-0.448768 0.348742 -0.490749 +-0.454966 -0.484977 0.242952 +-0.280389 0.101989 0.502395 +0.145282 -0.288215 -0.50221 +0.193925 -0.289227 -0.50671 +-0.0952359 -0.506627 -0.183741 +0.171971 -0.28889 -0.511435 +-0.176995 0.205635 0.496853 +0.507593 -0.0215235 0.172749 +0.397209 0.0516797 0.496006 +-0.438576 -0.116751 -0.503887 +-0.235516 0.499087 0.202871 +-0.474304 0.472296 -0.246271 +0.364202 0.0286915 0.514718 +0.41304 0.493298 -0.103263 +0.506035 -0.261452 -0.19248 +-0.409169 -0.114496 -0.493547 +-0.49979 0.322728 -0.0249612 +0.313284 0.509168 0.298125 +0.487304 -0.473092 0.282928 +-0.024721 -0.496718 -0.363188 +0.0243361 -0.507851 -0.338444 +-0.510841 0.352683 -0.15827 +-0.501506 0.332592 -0.108503 +-0.508492 0.381302 0.38518 +-0.265588 0.0647623 -0.494877 +0.217121 0.507422 -0.1067 +0.0441745 -0.495973 0.0750639 +0.0551639 -0.506525 0.103756 +-0.252199 0.110549 -0.499862 +0.495277 -0.0440575 -0.0269066 +0.493154 -0.0634082 -0.0459556 +0.148328 -0.476022 -0.479597 +0.505277 -0.0735085 -0.0183824 +0.302646 0.219011 -0.507632 +0.437539 -0.498827 -0.288723 +-0.246857 0.490105 -0.459888 +0.433737 -0.309972 -0.503071 +0.430631 -0.214481 0.505108 +-0.315691 0.0327522 0.505222 +0.470528 0.485013 -0.0685511 +0.218499 -0.069135 -0.507107 +0.496997 0.461395 -0.0486407 +0.254098 -0.0699097 -0.494107 +0.237987 -0.0388387 -0.507645 +-0.299564 -0.494885 -0.0653281 +0.483827 0.169829 -0.474284 +0.48868 0.201792 -0.472835 +0.0591005 0.325983 0.501681 +-0.242024 0.0608049 -0.497582 +-0.500913 0.416052 0.448503 +-0.17873 -0.123861 0.497402 +-0.15165 -0.101016 0.508766 +0.275912 -0.412041 -0.50892 +0.281435 -0.386456 -0.51172 +0.26428 -0.274764 0.504649 +-0.358996 -0.516511 -0.285617 +0.319635 -0.424676 -0.503261 +-0.319062 0.0662526 0.510341 +-0.338305 -0.514982 -0.338611 +0.467298 0.470671 -0.0924249 +-0.357708 0.49679 0.0936519 +-0.371062 0.410095 0.511314 +-0.39402 0.449138 0.501833 +-0.107596 -0.244053 -0.507415 +0.153523 -0.499674 0.132769 +0.111448 -0.496998 0.145383 +-0.327388 0.315678 -0.508829 +0.466039 0.123845 -0.471768 +0.136187 -0.494517 0.180498 +0.491525 0.259944 0.104876 +0.49075 0.465266 -0.096799 +0.492033 -0.0188095 0.0196348 +0.509051 -0.0501776 0.0688243 +-0.122712 -0.512901 0.353243 +-0.366961 -0.315703 -0.517088 +-0.409445 -0.438278 -0.487414 +-0.482885 0.0715921 0.473603 +-0.335702 -0.01138 0.512775 +0.429955 0.489142 0.435835 +-0.3452 0.0160384 0.496723 +0.180849 0.179272 0.505583 +0.15943 0.257241 -0.506012 +0.441212 0.444665 0.475398 +0.19785 -0.103022 -0.500117 +-0.49926 -0.0250563 0.16945 +-0.500733 -0.041212 0.194275 +0.230607 0.498465 -0.0536341 +-0.495103 -0.29338 0.183048 +-0.500343 -0.280039 0.218226 +-0.497585 -0.314216 0.213866 +-0.392042 0.497165 0.0907757 +0.152074 -0.4977 -0.211484 +-0.0722444 -0.489176 0.426451 +0.122537 -0.491587 -0.251878 +0.0822788 -0.179241 -0.494437 +-0.480185 0.0977326 0.472012 +-0.093377 -0.482699 0.462029 +-0.016915 0.0724962 -0.504253 +-0.503359 -0.0790043 -0.241977 +0.00794115 0.060773 -0.503808 +0.29953 0.0589046 -0.508223 +0.124321 -0.497359 -0.0984753 +0.141091 -0.505378 -0.0262454 +-0.132329 0.491909 0.462135 +-0.374009 0.501082 0.146129 +0.152893 -0.491064 0.459985 +-0.504292 0.0577634 -0.124417 +-0.489969 0.0908758 -0.11539 +-0.501382 0.0661069 -0.0924283 +0.211977 0.115519 -0.491869 +0.194276 0.141505 -0.491382 +-0.479235 -0.321306 -0.472212 +-0.348843 -0.134511 0.512561 +-0.344021 -0.088909 0.498597 +0.0893786 0.316009 0.512944 +0.124126 0.324335 0.50126 +0.506926 0.300441 0.16499 +0.498595 0.283363 0.123348 +-0.263953 -0.21576 -0.501037 +-0.0335297 -0.490285 -0.0858234 +0.479772 0.344583 0.469969 +0.454291 -0.491731 -0.298326 +0.0912827 0.21055 -0.498147 +0.305411 -0.507083 -0.290664 +0.273923 -0.507881 -0.300006 +-0.505235 -0.0215798 0.410943 +-0.237267 -0.201147 -0.491735 +0.32243 0.429674 -0.509486 +0.31985 0.449908 -0.488663 +-0.476641 -0.476554 0.253316 +-0.418647 -0.303084 0.507353 +-0.207079 -0.416246 0.494202 +-0.225747 0.448466 -0.484318 +-0.203107 0.458714 -0.488239 +-0.0718081 -0.0958144 -0.505903 +-0.047398 -0.114106 -0.496837 +-0.00992521 -0.463437 0.476074 +0.49737 -0.055163 0.437121 +0.0699879 -0.340048 0.503099 +-0.506552 0.429584 -0.353503 +-0.154212 0.441145 -0.500244 +-0.501702 -0.0473736 0.247996 +-0.496297 -0.0669342 0.27393 +-0.498923 -0.430829 -0.165756 +-0.504359 -0.078062 0.243024 +-0.46558 0.273483 -0.47756 +0.503291 -0.438771 0.0911955 +0.501873 0.32927 -0.0258379 +0.503695 0.291096 -0.25168 +-0.130717 0.494849 0.0306961 +-0.12247 0.496657 0.0649042 +-0.0116614 0.454906 0.499072 +-0.232593 -0.236905 -0.508524 +-0.443453 0.320775 0.500454 +0.502671 0.320687 -0.404485 +0.182488 0.463391 -0.480958 +-0.260168 -0.227641 0.502643 +-0.26276 -0.193818 0.500292 +-0.317599 -0.501198 -0.115893 +-0.510883 0.229483 -0.293746 +0.463589 -0.114575 -0.469072 +-0.344175 -0.495508 -0.12389 +-0.285753 0.231019 0.512891 +0.110924 -0.220134 0.4916 +-0.427134 0.498689 -0.0269961 +0.320824 0.180045 0.509994 +0.253827 0.499966 -0.114526 +-0.394832 -0.439832 0.500948 +-0.494385 -0.299615 -0.442082 +0.50308 0.437173 0.0822488 +-0.491405 0.135579 -0.449932 +0.516199 0.337962 -0.236804 +-0.0303158 -0.368853 0.501047 +0.502383 0.116315 -0.056815 +0.499516 0.142356 -0.0697699 +-0.514878 -0.408701 0.356279 +-0.399413 0.225863 -0.510914 +0.501215 -0.299864 0.143876 +-0.435491 0.00758292 0.492407 +-0.0396821 0.0232363 -0.493284 +0.474329 0.36403 0.480894 +-0.041708 0.0555794 -0.503689 +0.485281 0.439008 0.111599 +-0.502172 -0.225845 -0.261456 +-0.12844 -0.499025 0.000928538 +-0.307727 0.159965 -0.501476 +0.505665 0.04984 -0.131674 +-0.152492 -0.226174 0.509308 +0.507612 -0.00742113 0.278564 +0.0026579 -0.0928935 0.492845 +0.49307 0.455396 0.14328 +-0.504974 -0.0656456 0.0132076 +-0.501508 -0.387128 0.334119 +-0.503664 -0.03663 -0.00558407 +-0.502138 -0.443579 0.319391 +-0.492895 0.455897 0.019194 +-0.168798 0.243839 -0.500159 +-0.483815 -0.393495 -0.461046 +-0.17507 0.301275 -0.501504 +-0.220477 0.263837 -0.508516 +0.13702 -0.490949 -0.115772 +0.40392 0.510648 -0.397623 +-0.50458 0.00604552 0.169518 +-0.419736 0.498238 -0.0558056 +0.326738 -0.150279 -0.503553 +0.502166 -0.317936 -0.267786 +0.506374 -0.349255 -0.28008 +0.50119 -0.345449 -0.247622 +-0.489608 -0.296386 -0.464128 +-0.50967 -0.184149 0.38394 +-0.503719 -0.227555 0.382232 +0.455544 -0.483758 0.145569 +-0.497999 -0.431446 0.350826 +-0.336172 0.178479 -0.50411 +-0.484744 0.465238 -0.190128 +0.175742 -0.48569 -0.472138 +-0.241809 -0.134938 0.507757 +-0.50875 -0.328653 0.351514 +0.218206 -0.416982 0.507067 +0.112861 -0.445043 -0.491776 +0.0617193 -0.111014 -0.502421 +0.087516 -0.108827 -0.500885 +0.395828 0.499121 -0.215736 +0.434628 0.266512 -0.505313 +-0.46743 -0.475643 -0.361793 +0.310774 -0.110871 0.495964 +0.497336 -0.13851 0.437738 +0.509379 0.339213 -0.0777019 +-0.129874 0.204183 -0.49763 +-0.25906 0.188589 -0.509941 +0.240301 -0.34718 -0.506263 +0.498746 -0.152483 -0.136 +0.50397 -0.178629 -0.147761 +0.493367 -0.177527 -0.118717 +-0.164665 -0.480543 0.480871 +0.212334 -0.500066 -0.329381 +-0.368831 -0.42806 -0.502147 +-0.377766 0.501371 0.216485 +0.208033 -0.503071 -0.299459 +-0.49679 -0.00453532 0.364702 +-0.497447 -0.0539852 0.355486 +-0.51232 -0.0132761 0.336892 +-0.0487262 -0.379481 -0.500923 +-0.104655 -0.389761 -0.504086 +-0.0864825 -0.409498 -0.497698 +-0.0432403 0.117158 -0.509347 +-0.0682398 0.10056 -0.497448 +-0.042578 0.0863653 -0.49129 +0.183967 -0.200928 0.498814 +-0.183072 -0.500091 -0.341845 +0.221824 -0.168154 0.502291 +0.189766 -0.364482 -0.498145 +-0.513323 0.343255 0.408142 +-0.370117 -0.513937 0.00364755 +0.502583 0.447886 -0.0252272 +0.495573 0.420983 0.365843 +-0.053967 -0.491038 -0.199481 +-0.0775744 -0.498911 -0.199493 +-0.0692332 -0.504334 -0.177751 +0.481972 0.462867 -0.166033 +0.489516 0.240303 -0.44957 +0.444319 -0.0467747 -0.485381 +-0.210657 0.0361046 0.509145 +-0.24341 0.0812529 0.493048 +-0.205182 0.0558119 0.498166 +0.35864 -0.47012 0.493991 +-0.497738 0.232192 0.105877 +0.484052 0.474972 0.161552 +-0.406314 -0.39767 -0.499093 +0.162147 -0.430952 -0.503744 +-0.0812046 0.507291 0.435885 +0.00755072 -0.284324 0.498494 +-0.021454 -0.299124 0.506471 +0.500124 -0.343032 0.113279 +0.510581 -0.359047 0.0578677 +0.114708 0.290805 0.511432 +0.119138 0.233593 0.495411 +-0.154136 0.0130625 -0.492608 +-0.166216 0.0424981 -0.509121 +-0.130072 0.504896 0.250945 +-0.0250468 0.488133 -0.450628 +0.461125 0.0327772 -0.485831 +0.0908719 -0.510884 0.389776 +-0.414019 -0.27967 -0.496388 +-0.437512 -0.441692 -0.491947 +-0.221187 0.420135 0.506757 +-0.370526 -0.447992 -0.489489 +0.138991 -0.507788 0.360897 +0.252851 0.0658532 -0.495738 +-0.171066 0.507986 0.136648 +0.231263 0.0902413 -0.491787 +0.47097 0.356124 -0.484458 +0.264316 -0.495794 -0.222485 +0.404274 -0.0862497 0.493506 +0.427402 -0.0740413 0.503839 +-0.4943 0.389909 0.45025 +-0.121693 -0.372947 -0.51276 +-0.0793196 -0.331711 -0.495519 +0.195768 0.401619 -0.502125 +0.211034 0.375343 -0.497158 +-0.506741 -0.0674157 0.0457773 +0.350137 -0.0150928 -0.503518 +0.375471 -0.0115766 -0.502622 +-0.501483 0.236611 -0.22817 +-0.508949 -0.401893 -0.341517 +0.481603 -0.453034 0.0835513 +0.241659 0.498565 0.12417 +-0.498511 0.247502 0.45613 +-0.474275 -0.0669936 -0.465321 +-0.19674 0.499506 0.262179 +-0.306855 0.380575 0.508838 +-0.279295 0.391966 0.508781 +0.339345 0.357996 0.520177 +0.337852 0.380834 0.507564 +0.361011 0.37435 0.515402 +0.443449 -0.0175084 -0.493607 +0.25692 0.485025 -0.448369 +0.498063 -0.0526624 -0.45968 +0.489782 0.436419 -0.0493117 +0.219685 0.190624 -0.497076 +0.244574 0.195603 -0.510218 +0.188326 0.223067 -0.493875 +-0.122317 0.512139 0.301655 +-0.452627 -0.348253 -0.486715 +-0.0724367 -0.287695 -0.496878 +-0.4228 -0.333336 -0.507001 +-0.45734 0.21426 0.493309 +-0.0815388 -0.244404 -0.492864 +-0.0920124 0.507329 0.299762 +-0.107305 -0.326653 -0.497037 +0.495888 -0.194738 -0.256303 +0.504383 -0.226193 -0.266634 +-0.471144 0.477647 0.227015 +0.503088 -0.220515 -0.236776 +-0.49592 0.338749 -0.184281 +0.28161 0.0154463 -0.496562 +-0.0676692 0.00491616 -0.503608 +0.503699 -0.323735 -0.0695649 +0.494369 0.30445 0.141219 +0.508697 0.0705185 0.175653 +-0.484694 0.380584 0.472118 +0.258539 -0.00962771 -0.50472 +0.292004 -0.0150465 -0.505534 +-0.415248 -0.430682 0.502524 +-0.436092 0.420287 -0.482458 +-0.504032 0.210835 0.376928 +-0.435139 -0.491062 -0.0428383 +-0.498001 0.249413 0.406817 +-0.498602 0.0689815 0.229025 +-0.500674 0.0531986 0.262047 +0.239917 -0.500862 -0.0440909 +0.260077 -0.498671 -0.002713 +0.5064 0.415375 -0.366193 +0.503624 -0.372457 0.096509 +0.501064 -0.409646 0.094319 +0.471347 0.486011 0.199813 +0.495063 0.238988 -0.261753 +0.285418 0.422741 0.495791 +0.0143301 -0.514406 0.336268 +0.234014 -0.422552 -0.507551 +0.248771 -0.376162 -0.502922 +0.202104 -0.497673 0.308816 +-0.43464 -0.163113 -0.491902 +-0.147758 0.510079 0.303597 +0.0773202 0.506464 0.398994 +0.435716 -0.495493 -0.241912 +-0.409207 -0.273079 0.493991 +0.013359 -0.500854 -0.402747 +-0.49626 -0.449823 0.0453819 +0.0734067 -0.493879 -0.405029 +0.501141 -0.0350298 -0.306984 +0.503828 -0.0783221 -0.259981 +0.503193 0.13459 -0.169933 +-0.512225 -0.166151 -0.280382 +-0.096505 0.497298 -0.108688 +-0.160135 0.503605 0.11319 +0.496842 0.0963629 -0.193529 +0.33031 0.498782 0.447771 +-0.512257 0.104275 -0.337229 +-0.504847 -0.0494545 -0.103237 +-0.492296 -0.0792246 -0.121827 +0.165102 -0.49726 -0.0220393 +0.494311 0.221783 0.407751 +0.50379 0.114772 0.424283 +0.31101 0.373315 0.516242 +-0.176538 -0.0600311 -0.501276 +-0.252875 -0.490193 -0.460625 +0.503154 0.20209 0.435592 +-0.476802 -0.298086 0.480315 +-0.451797 0.11819 -0.493002 +0.0968317 0.499704 -0.4426 +-0.476959 0.274972 -0.463826 +0.0632366 -0.48 0.476198 +-0.433724 -0.486608 0.174502 +-0.440297 -0.502687 -0.254558 +-0.489858 0.301504 -0.457281 +-0.0753106 0.496897 -0.429608 +-0.120919 -0.475409 -0.483312 +-0.486081 -0.472545 -0.316599 +0.180177 0.488797 -0.446067 +-0.185323 -0.455064 -0.498017 +0.0827356 -0.437402 -0.487371 +0.137027 0.0247922 -0.50692 +0.502802 0.298818 -0.429999 +-0.307775 -0.501652 0.32378 +0.448545 0.485957 -0.256996 +-0.34826 -0.505683 0.372855 +-0.22046 0.500877 0.123347 +-0.106882 0.198952 -0.509523 +0.170833 0.037321 0.494623 +-0.0650388 0.243437 -0.497021 +-0.492261 -0.0497334 -0.128326 +0.238303 -0.50943 -0.342627 +0.119939 0.495767 0.426366 +-0.507899 -0.0329933 -0.146057 +-0.49775 0.0596232 -0.429624 +-0.485603 0.0357972 -0.439172 +0.500452 0.163092 -0.0573693 +0.497386 0.143395 -0.0109506 +-0.510168 -0.369922 0.180769 +-0.49872 -0.332817 0.239836 +-0.0269153 -0.491754 0.136234 +0.391476 -0.309322 0.512611 +-0.507807 0.407825 -0.121306 +-0.503074 -0.327364 -0.342666 +-0.502162 0.00580887 0.0415908 +-0.49531 -0.0321932 0.0330688 +-0.0390047 -0.187557 -0.50181 +0.399445 -0.503565 -0.112381 +0.0949808 0.496328 0.376592 +0.498532 -0.0786219 -0.450221 +0.0871434 0.285186 0.501549 +-0.476237 -0.326092 0.469233 +-0.50364 0.112686 0.0973748 +-0.498329 0.352739 0.226682 +-0.505539 0.249085 -0.31843 +0.509465 0.0361306 0.126654 +0.14802 0.498084 -0.18639 +0.0365806 0.475385 -0.457767 +-0.474037 0.329986 -0.491873 +0.387779 0.365015 0.51102 +0.326582 -0.505544 0.314807 +0.359395 -0.500245 0.26463 +-0.204716 -0.496094 -0.0410264 +-0.182078 -0.503954 -0.056289 +0.496168 0.0123484 -0.334429 +-0.509353 -0.107871 -0.307115 +-0.22354 -0.504709 -0.0521122 +0.50568 0.0245172 -0.392096 +-0.491399 -0.308732 0.436734 +0.279067 -0.500675 0.427729 +0.506113 -0.137685 -0.266938 +0.224816 0.365263 0.50223 +-0.405276 -0.350707 0.501795 +-0.50065 0.163155 -0.188549 +-0.456164 -0.292489 0.48866 +0.117957 -0.509865 0.403387 +-0.227583 0.248852 0.508899 +-0.490252 0.140772 -0.164442 +-0.233862 0.503693 -0.350843 +0.136167 0.507931 -0.149857 +-0.507306 -0.0960387 -0.158278 +-0.50369 -0.116433 -0.12822 +-0.494087 -0.118214 -0.179029 +0.347882 -0.512747 0.338561 +-0.513723 -0.380696 0.3652 +0.0816193 -0.450233 0.496137 +-0.5075 -0.326313 -0.0626609 +0.499136 0.173606 -0.387824 +-0.29014 0.513873 -0.341311 +-0.506479 -0.376921 -0.0104274 +-0.503126 0.413855 -0.438863 +-0.463732 -0.263206 -0.473949 +-0.500311 -0.442507 -0.124886 +-0.496 0.404457 -0.408481 +-0.244364 -0.462029 -0.489943 +0.487723 0.468545 0.301443 +-0.509615 -0.114522 0.0403516 +-0.499159 -0.158475 0.0653174 +0.402955 -0.413128 0.500889 +-0.0234356 -0.495065 0.414839 +-0.0549619 -0.510765 0.410082 +-0.0468994 -0.490953 0.432033 +-0.501364 -0.271369 0.0833625 +-0.496569 -0.291572 0.0191429 +-0.503885 0.0817972 -0.148366 +0.513339 -0.387744 -0.0453893 +-0.518687 -0.358962 0.343202 +-0.178909 0.466192 -0.485222 +-0.510953 0.154089 0.26855 +-0.0141963 0.0423862 -0.495851 +-0.14206 -0.290085 -0.502694 +-0.421155 -0.463428 -0.491517 +-0.127554 -0.348242 -0.495216 +-0.106071 0.287086 0.507728 +-0.256722 0.417268 -0.50133 +-0.04722 0.139138 0.505841 +-0.251369 0.443825 -0.494411 +-0.282055 0.433834 -0.490003 +-0.424894 -0.0323428 -0.4894 +-0.0867241 -0.497071 -0.292394 +0.123918 0.50403 0.15314 +0.210467 0.312241 0.514252 +-0.493974 0.157009 0.174784 +-0.06443 -0.50314 -0.288998 +0.171426 0.492809 -0.156078 +-0.322214 -0.280769 -0.517179 +0.498248 -0.246912 0.0929043 +0.494392 -0.232399 0.110914 +-0.505868 -0.260398 0.320354 +-0.271597 0.291296 0.5112 +-0.505301 -0.297007 -0.325231 +-0.497418 0.0256544 -0.132433 +-0.508211 0.0031118 -0.110876 +-0.505221 -0.00474316 -0.139604 +0.494619 0.353703 -0.451857 +-0.144005 0.485633 -0.467598 +0.453337 -0.397834 -0.495448 +-0.385526 -0.281553 -0.507089 +-0.0105273 -0.494991 -0.228055 +0.335776 0.284879 0.510939 +0.0936038 -0.152343 0.50562 +-0.107205 0.462299 0.49145 +0.502285 -0.276235 0.0995092 +0.510153 -0.282063 0.0487246 +0.503721 -0.309336 0.111673 +0.228316 0.0979189 0.509525 +-0.456919 -0.433635 -0.491121 +-0.0414782 -0.513925 -0.332146 +0.0783098 0.459007 0.474838 +-0.243148 0.456302 0.495264 +-0.0161017 -0.497023 -0.308771 +-0.370151 -0.515265 0.345396 +0.502029 0.118007 -0.4301 +-0.500052 -0.419001 -0.359205 +0.496685 -0.0193446 -0.0391267 +0.506705 0.00412534 -0.0549103 +0.497009 -0.0227781 -0.065793 +0.248006 0.270241 -0.507622 +0.259373 0.301127 -0.496445 +0.228524 0.296458 -0.510947 +0.503161 -0.304671 -0.0145102 +0.383099 -0.0725413 0.501633 +0.424893 -0.184214 0.492504 +0.227888 0.497433 0.0283571 +0.228521 0.492797 0.0793288 +0.509042 -0.292907 0.0194626 +0.224232 0.0142388 0.490907 +0.208963 -0.0191153 0.506415 +0.153325 -0.405221 -0.498071 +-0.265426 0.503121 -0.360867 +0.0954636 -0.394559 -0.501551 +0.452194 -0.479526 -0.194719 +0.474808 -0.487425 -0.0361153 +-0.0702523 -0.507523 -0.111172 +-0.458181 0.144147 0.500178 +-0.274486 -0.465999 0.481393 +0.495571 0.0246857 0.458494 +-0.297377 0.0708268 -0.504851 +-0.482332 -0.449302 -0.44497 +-0.294763 0.105055 -0.511562 +-0.501502 -0.382182 0.217587 +-0.503536 -0.291458 0.111315 +-0.339656 0.0945983 0.51023 +-0.512186 -0.290745 0.146917 +-0.130269 -0.431372 0.505575 +-0.497195 0.388897 -0.227659 +-0.397308 -0.424211 -0.508281 +-0.497471 0.412881 -0.235965 +-0.505797 0.418081 -0.192902 +-0.257964 0.513869 -0.329714 +0.263445 0.0940861 0.492708 +0.239504 0.0470319 0.494668 +0.215164 0.0709701 0.493015 +0.454699 0.369323 0.484781 +0.500595 -0.125238 -0.0418888 +0.495319 -0.141556 -0.0132146 +0.489959 -0.106971 -0.0140774 +0.507372 -0.401448 -0.307382 +0.193856 -0.139154 -0.491225 +0.209504 -0.179526 -0.495194 +-0.506973 0.228154 0.0749273 +0.342358 -0.505403 0.0427386 +-0.498243 0.223738 0.0192014 +-0.473027 -0.481286 0.144119 +0.135396 0.0812289 -0.497884 +0.0416106 -0.496822 -0.416565 +0.0420347 -0.487911 -0.439198 +-0.411548 0.491586 0.440411 +0.074266 -0.507797 0.000282142 +0.119953 -0.500801 -0.0448449 +-0.443201 0.488363 -0.275487 +0.0949296 -0.493437 -0.0225397 +0.286131 0.493261 -0.420774 +-0.511781 0.120464 -0.411985 +-0.495289 0.196483 -0.415778 +0.467343 -0.492331 0.0617913 +-0.0379493 -0.491521 0.00484974 +-0.0268444 -0.508212 0.0364309 +-0.126072 -0.396428 0.496583 +-0.00614986 -0.506747 0.011626 +0.250789 -0.467357 -0.485794 +-0.499486 0.312593 0.0044148 +-0.425969 -0.251566 -0.489566 +-0.415056 -0.222456 -0.507438 +0.119882 -0.15914 0.499535 +0.144592 -0.136195 0.500634 +0.498371 -0.349492 0.023735 +0.0081996 0.262091 0.50294 +-0.479822 -0.45638 -0.271631 +-0.0201263 0.244007 0.496034 +-0.50802 0.405287 -0.0251932 +-0.513773 0.356179 -0.0643581 +-0.508253 0.384315 -0.0786166 +0.427666 -0.330547 0.496474 +-0.306564 0.260387 -0.511323 +-0.271905 0.31045 -0.500769 +0.502878 -0.0828146 -0.284385 +0.0560059 -0.363808 -0.513176 +-0.489973 -0.449324 -0.0695281 +-0.106538 0.236849 0.498739 +0.066263 -0.390115 -0.503011 +-0.0163374 0.134071 -0.503586 +-0.35271 -0.510264 0.284102 +0.508288 -0.348222 -0.401953 +-0.0684077 0.0384934 -0.5034 +-0.486733 -0.462702 -0.426459 +-0.0958499 0.0553068 -0.499848 +0.464509 -0.482799 0.441179 +-0.0971095 0.0214946 -0.502359 +-0.157688 -0.50315 0.430141 +-0.493246 -0.4471 -0.206543 +-0.496474 -0.0684222 -0.0203305 +-0.416029 0.432972 0.505309 +-0.41835 0.4539 0.492031 +-0.463303 -0.473503 0.0522834 +-0.502864 0.283177 0.114496 +-0.498713 0.326837 0.0854563 +-0.399457 0.503129 -0.334573 +-0.209151 -0.20953 -0.491035 +0.239821 -0.502084 -0.308405 +0.498817 0.029877 -0.425224 +0.418452 -0.509235 -0.06276 +-0.503485 -0.349661 -0.39781 +-0.439799 0.169506 -0.492603 +0.243114 -0.432682 0.488044 +-0.422167 0.199338 -0.491994 +0.440356 -0.496239 -0.0331221 +-0.502496 0.430683 0.300412 +0.0247899 0.508102 -0.202329 +-0.456964 0.120169 0.501587 +0.440615 0.504366 0.122468 +0.459179 0.415383 -0.483951 +0.0107709 0.502301 -0.12152 +-0.507847 -0.264941 -0.306472 +-0.513926 -0.233602 -0.292364 +-0.336022 -0.338776 -0.505988 +-0.45597 -0.277537 -0.485799 +0.493271 -0.444975 -0.30917 +0.494719 0.414345 -0.338802 +-0.455565 -0.253407 -0.4983 +-0.498474 -0.260059 -0.271824 +-0.284907 -0.450802 0.496144 +-0.385786 0.501613 -0.377538 +0.490696 0.4319 -0.125315 +0.497058 -0.0542925 0.264209 +0.498033 -0.00382483 -0.148948 +-0.488698 -0.454694 -0.0173051 +0.501905 -0.0512199 0.287589 +0.50443 0.0590478 -0.0625068 +0.506354 -0.0239942 0.297751 +0.124757 -0.400982 -0.507982 +-0.371606 0.0937099 0.500721 +-0.460032 0.483838 0.391851 +0.0747375 -0.414042 -0.49122 +0.384734 -0.499193 -0.443905 +0.133911 -0.426051 -0.498152 +0.0388537 0.148374 0.490881 +0.495893 0.22902 0.30478 +0.0578692 0.482853 0.439405 +-0.519732 -0.35147 -0.353706 +0.229174 0.511484 -0.418952 +-0.342926 0.146559 0.495784 +0.46261 -0.0252598 0.481731 +-0.502164 0.0486787 -0.0379812 +-0.508096 -0.397092 -0.37351 +-0.152165 -0.500409 -0.393922 +0.284736 -0.473812 0.48877 +-0.21143 -0.508548 -0.420981 +0.324774 -0.505019 -0.438846 +0.492064 -0.107319 -0.271429 +0.466492 0.489231 -0.358181 +0.347781 0.51073 -0.424859 +0.508188 0.320481 -0.189441 +-0.481157 -0.0584577 -0.445191 +0.131241 -0.0877274 -0.49073 +0.441908 0.504321 0.0490239 +0.503553 0.378254 -0.131602 +0.509192 0.344671 -0.18941 +0.107005 0.333068 -0.501693 +0.419394 0.398777 -0.493056 +-0.49667 -0.426772 0.226806 +0.15596 0.471136 -0.470008 +-0.463461 -0.322661 -0.486768 +0.127009 0.354941 -0.510387 +0.37935 0.392363 0.50053 +0.0537727 0.3529 0.51543 +-0.431756 -0.253418 0.494292 +-0.469711 -0.143541 -0.469631 +-0.493116 -0.417153 0.151417 +0.00752529 -0.128138 0.497481 +-0.0193012 -0.151678 0.49501 +-0.514233 -0.400454 0.162862 +-0.470926 -0.292888 -0.479599 +-0.493782 0.449622 -0.408445 +-0.503584 -0.422852 0.172232 +-0.499634 0.314712 -0.341767 +0.127751 0.454014 0.497467 +-0.5098 -0.328088 -0.310155 +-0.516402 -0.357796 -0.299756 +-0.4318 0.332266 -0.505734 +-0.502785 -0.248891 0.061578 +0.46825 0.415165 0.48228 +0.387595 -0.510182 0.391012 +0.467181 0.470249 -0.432475 +-0.114094 0.213797 0.503421 +0.144052 0.503967 0.174428 +-0.186581 -0.293917 -0.496458 +-0.49745 -0.057856 -0.341279 +-0.297135 -0.50213 0.185073 +0.160485 0.345713 -0.505212 +0.215081 -0.157873 -0.495124 +0.269497 -0.151483 -0.506206 +0.150332 -0.487665 -0.462301 +-0.459559 -0.488807 -0.0369718 +0.488297 0.457331 0.171997 +0.51712 -0.376992 -0.321547 +0.280845 0.277571 -0.510184 +0.118438 -0.0596274 -0.506753 +0.503751 -0.316816 -0.341397 +0.513335 -0.37409 -0.35276 +-0.471733 -0.471277 0.337474 +0.499463 0.0404243 0.421096 +0.500041 0.0172072 0.438061 +0.111278 -0.191289 -0.503424 +0.361988 -0.501064 0.30358 +0.0464932 -0.497272 -0.244446 +0.101496 -0.504588 -0.229107 +-0.275535 0.159858 -0.493486 +0.062365 -0.508975 -0.265269 +-0.358564 0.508461 0.276678 +-0.483058 0.0444315 0.473719 +-0.272734 -0.392501 0.505206 +-0.252582 -0.409091 0.49983 +0.503829 0.136625 0.367869 +0.506921 0.206016 0.384139 +0.509839 0.234345 -0.0248081 +-0.497037 -0.0356512 0.278568 +0.510842 0.19156 0.355734 +-0.354288 0.0679891 0.496688 +-0.469457 0.0836966 0.485368 +-0.332376 0.0625656 -0.501256 +-0.345846 0.114871 -0.502144 +-0.41407 -0.498929 0.0403177 +0.0404274 0.0770737 0.490065 +-0.435787 0.110921 0.490429 +-0.512599 0.391866 0.0270841 +-0.39279 -0.51318 0.0509925 +-0.369708 -0.510685 0.0342699 +0.20292 -0.0366745 -0.505489 +0.48731 0.383711 -0.448487 +0.499681 0.221018 -0.0750164 +-0.480174 0.108646 -0.451743 +-0.426882 -0.192237 -0.499178 +0.495406 0.154366 0.270661 +-0.156471 0.244767 0.504779 +0.237177 -0.28673 -0.508425 +0.236704 -0.317709 -0.50515 +0.441023 0.346265 0.494015 +-0.0161179 0.504975 -0.121649 +-0.472338 0.0154456 0.469136 +0.436741 0.486454 0.000797994 +0.50513 -0.409348 -0.0282287 +0.162998 0.139361 -0.503193 +0.38999 -0.476585 0.47007 +-0.0249228 0.490201 -0.145776 +-0.505252 -0.366427 0.312018 +0.475528 -0.119576 0.46615 +0.496777 0.261573 -0.0406662 +0.233712 -0.45371 0.480771 +-0.49689 -0.424077 0.289917 +0.445817 -0.500577 0.0121596 +0.499817 0.336259 -0.429712 +0.440008 -0.499513 0.301959 +0.468819 0.0479562 0.471469 +-0.483798 0.461608 0.279048 +0.224038 0.143473 -0.503824 +0.103114 -0.432652 0.489805 +0.489444 -0.247388 -0.448945 +0.496136 -0.274649 -0.439775 +-0.477892 0.477014 -0.103915 +-0.327193 -0.457332 -0.489885 +0.508041 -0.247668 -0.42808 +0.177692 0.511634 0.290918 +0.0705849 -0.497663 0.342783 +0.116746 -0.497085 0.353347 +0.345718 -0.504618 0.42804 +-0.510674 -0.129842 -0.31829 +0.0731813 -0.0851555 -0.500263 +0.0876425 -0.0584525 -0.4899 +0.0564052 -0.0591896 -0.501591 +-0.448747 0.496631 0.339239 +-0.0161735 -0.494044 0.290762 +-0.383209 -0.500305 0.375045 +0.0168602 -0.505284 0.305139 +0.489771 -0.354986 -0.44993 +-0.292484 -0.426153 0.495975 +-0.274768 -0.415681 0.512028 +0.500381 -0.172715 0.0457893 +-0.0781138 0.276097 0.501443 +-0.0827346 0.307709 0.513787 +0.00388079 -0.506527 0.427974 +-0.306043 -0.0191065 -0.500104 +-0.301721 0.502921 -0.0158487 +0.328562 -0.503656 -0.144733 +0.352059 -0.505911 -0.124174 +0.0609171 -0.120553 0.50733 +-0.491076 0.326142 0.438489 +-0.502493 -0.186906 0.113348 +-0.494817 -0.133964 0.0904866 +-0.368469 -0.506929 -0.0552621 +-0.392715 -0.503858 -0.0660345 +-0.510473 -0.220947 -0.406847 +0.444604 -0.11308 0.494485 +-0.0786867 -0.449144 -0.490184 +-0.510691 -0.201415 -0.418101 +0.484681 -0.465039 -0.0256644 +-0.286478 -0.399543 -0.495888 +0.149854 -0.0623663 -0.503734 +0.0414735 -0.485701 0.447602 +0.188978 0.401881 0.493806 +-0.0979986 0.470879 0.476081 +-0.161033 0.102462 0.508005 +0.130511 0.423368 0.489479 +0.0705049 -0.274375 -0.501782 +0.0940995 -0.303371 -0.503439 +0.460623 -0.483994 0.376453 +-0.34674 -0.508838 0.162355 +-0.370911 -0.50265 0.162109 +0.512066 -0.343406 0.427267 +0.460632 0.285611 0.477221 +-0.496928 0.0988379 -0.0825476 +0.16834 -0.123851 -0.503307 +-0.265852 -0.087927 -0.500699 +-0.458579 -0.179054 0.49222 +-0.252908 -0.133833 -0.494321 +0.4519 -0.00900592 0.500755 +-0.464847 -0.487334 0.275337 +-0.233305 -0.120041 -0.496537 +-0.445289 -0.220554 -0.493812 +0.5059 -0.133794 -0.435581 +-0.212877 -0.111562 0.508384 +-0.248876 -0.0982077 0.494616 +-0.218688 -0.0761575 0.505943 +-0.502599 -0.186775 -0.311709 +-0.506625 -0.213532 -0.309339 +0.411036 -0.508976 0.33501 +-0.321828 0.518299 -0.380803 +-0.369349 0.506567 -0.403589 +0.233007 0.335351 0.50412 +0.489312 -0.353147 0.442913 +0.504113 -0.322664 0.437814 +0.129462 0.47003 -0.484993 +-0.490113 0.195783 0.0593552 +-0.503694 -0.0250949 -0.191294 +-0.492269 -0.0484916 -0.193452 +-0.500079 -0.038186 -0.213548 +0.115716 0.383388 -0.495248 +0.483868 -0.473684 -0.0603957 +0.0121051 -0.470126 -0.486347 +0.512353 -0.292002 -0.13332 +-0.254069 -0.515352 0.325905 +0.357927 -0.0352137 0.500046 +0.347226 0.0144252 0.508129 +-0.135495 0.459797 0.48487 +-0.443386 0.290083 0.485319 +-0.357341 -0.509002 -0.424838 +-0.314153 -0.411823 -0.501808 +-0.0561162 0.473668 -0.485083 +0.491419 0.178242 0.119982 +0.508054 0.174861 0.164389 +-0.237069 -0.33068 -0.510809 +-0.161967 -0.309362 -0.493853 +-0.218686 -0.307621 -0.496343 +-0.419028 -0.367023 -0.504734 +-0.019729 0.346549 -0.502935 +-0.0539204 0.299482 -0.506296 +0.499092 0.363456 0.0283352 +0.503257 0.35946 -0.023578 +0.495634 -0.100306 -0.2403 +-0.467166 -0.235301 -0.481661 +0.49926 -0.14582 -0.241843 +0.513161 0.0927385 0.353852 +-0.0281672 -0.493848 0.167568 +0.487873 0.455605 0.0889971 +0.129483 0.495165 -0.449694 +-0.112138 -0.496122 -0.107844 +0.159367 0.415629 0.509429 +-0.0891763 -0.50253 -0.123299 +0.295938 0.496091 0.129767 +-0.487222 -0.192349 -0.468991 +0.447394 -0.461005 -0.477302 +0.318332 0.253353 0.498485 +-0.379534 -0.402845 -0.498944 +-0.496402 -0.322291 -0.436718 +-0.491687 -0.196491 0.446343 +0.459789 0.477504 0.155809 +0.49524 0.205271 -0.404338 +0.503946 0.17018 -0.435408 +0.510915 0.157181 -0.415566 +0.32833 0.500263 0.206638 +-0.497676 0.436828 -0.0865066 +-0.493382 0.444895 -0.0564886 +0.20012 0.484826 0.44452 +0.0702455 0.200194 0.506686 +0.257401 0.426384 0.494485 +-4.68059e-06 -0.502604 0.11953 +0.00113886 -0.499436 0.152091 +0.0343369 -0.496506 0.133415 +0.321629 0.494681 0.144414 +-0.307959 0.408409 0.50925 +-0.338821 0.423683 0.50953 +-0.158919 -0.498506 -0.0732762 +-0.409215 0.419109 -0.500369 +-0.135407 -0.491084 -0.0907525 +-0.161673 -0.507381 -0.102541 +0.494144 -0.428052 -0.0126361 +0.504413 0.215882 -0.338152 +0.512093 0.221098 -0.306951 +0.288264 -0.23379 0.511812 +-0.482074 0.467776 0.00720359 +0.239442 -0.251431 0.506756 +0.0137075 0.148692 -0.499814 +0.0180355 0.181879 -0.503417 +-0.0563599 0.473527 0.485582 +-0.202371 -0.331116 0.51151 +0.49206 0.150613 -0.123935 +0.453191 0.0141744 0.499728 +-0.219914 -0.380769 0.51425 +-0.0101042 -0.492934 0.466833 +-0.0416187 -0.495459 0.459052 +-0.441911 -0.457363 -0.475208 +0.470967 -0.166516 -0.480662 +-0.00782902 0.500545 0.124901 +0.501338 -0.150301 -0.315225 +-0.470133 -0.174101 -0.476466 +-0.237926 -0.359387 0.511867 +0.287592 -0.0607797 0.492589 +0.234613 -0.0415877 0.49089 +-0.491085 -0.0108998 0.142866 +-0.490089 0.00167063 0.113389 +-0.184587 -0.405314 0.508257 +0.0240438 0.50871 0.141897 +-0.155073 -0.441616 0.494319 +-0.182198 -0.429617 0.495898 +0.494678 0.0746237 -0.303336 +0.489984 0.214504 -0.449019 +-0.507222 -0.137304 0.348695 +-0.505351 -0.192083 0.360753 +0.318723 0.502308 -0.259223 +0.0437875 0.0273914 -0.500128 +-0.168469 -0.462089 -0.474757 +-0.0522577 0.295098 0.512704 +-0.483298 -0.445378 -0.326781 +-0.0226457 0.319394 0.509966 +-0.0214424 0.279363 0.507958 +-0.504669 -0.437866 0.15326 +-0.204772 0.508305 -0.166234 +0.432942 0.501481 0.0951988 +0.0245995 0.503614 0.111915 +-0.361955 -0.109542 0.512633 +0.504392 0.102349 -0.290408 +-0.397067 -0.153896 0.509653 +-0.388491 -0.10444 0.505388 +-0.164488 -0.0319002 0.491945 +-0.171662 0.00250787 0.493142 +-0.179386 -0.211138 -0.49149 +0.480099 -0.07117 0.48025 +-0.393724 -0.484826 -0.448588 +-0.164724 -0.237853 -0.492395 +0.5084 -0.124888 -0.224552 +-0.0673089 0.498964 -0.387336 +-0.186848 -0.218798 0.507979 +-0.208304 -0.246238 0.510286 +-0.0351486 0.235185 -0.504735 +0.00661101 0.307541 -0.498181 +-0.0190707 0.294909 -0.511838 +0.393612 0.496297 0.0491001 +-0.0968119 -0.511367 -0.31819 +0.0814168 -0.498396 -0.201248 +-0.0760982 -0.502276 -0.341073 +-0.107674 -0.502447 -0.347241 +0.20033 0.257757 0.502246 +-0.501482 -0.298206 0.246877 +-0.0955583 0.496609 0.167173 +-0.0610282 0.494706 0.175737 +0.0288302 0.476782 0.452009 +0.498854 -0.132106 0.386494 +0.49894 -0.0754383 0.362503 +-0.49184 0.457474 0.0891255 +-0.501278 0.271254 -0.455436 +-0.21479 -0.450235 -0.479575 +0.313576 -0.393901 0.503851 +0.284072 -0.385916 0.511048 +0.290963 -0.412735 0.505693 +0.253294 -0.199085 0.500249 +0.245337 -0.172742 0.508091 +0.20568 -0.507146 0.398001 +0.416555 -0.322481 -0.50231 +0.49048 -0.0830593 -0.173368 +0.0322565 0.45459 0.494065 +0.494106 -0.0104484 -0.177351 +0.494424 -0.10241 -0.148677 +-0.478874 -0.469717 -0.116025 +-0.158475 0.492799 0.426185 +-0.51169 0.349009 0.429665 +-0.400252 0.209058 0.509127 +-0.229388 0.183338 -0.491387 +0.470443 -0.0431531 0.466401 +-0.430009 0.267194 0.501341 +-0.502102 0.272479 0.037929 +-0.483096 -0.459185 -0.0923909 +-0.0530997 -0.138123 0.50914 +-0.513415 0.299437 0.0343059 +-0.507486 0.283588 0.0608733 +0.497267 -0.0962549 0.232848 +-0.00155398 0.494299 0.161011 +0.00749948 0.0324844 0.505343 +0.501881 0.431546 0.385802 +-0.0424774 -0.0824134 -0.497785 +-0.0379904 -0.0478284 -0.500359 +0.497305 -0.123728 -0.126466 +0.497809 -0.0926001 -0.0888557 +0.442316 0.500717 -0.109872 +0.479853 -0.448439 -0.207497 +-0.509218 -0.0992947 -0.0346011 +-0.495508 -0.0720023 -0.0532709 +-0.512163 0.240081 -0.42351 +-0.505695 -0.409828 0.214417 +-0.385141 -0.506516 0.106581 +-0.0527278 -0.490407 0.120539 +-0.0801759 -0.495729 0.134587 +-0.0545013 -0.505606 0.151045 +-0.501327 0.264179 -0.405223 +0.507715 -0.0723822 -0.42457 +0.504263 -0.0498803 -0.440697 +-0.184898 -0.494894 -0.0844201 +0.501665 -0.102434 -0.428154 +-0.429546 0.507987 0.132159 +0.481102 0.422739 -0.464407 +-0.499085 0.2672 -0.234389 +0.0942931 0.472845 0.471051 +-0.223424 -0.475638 -0.480197 +0.494151 0.429223 -0.000567402 +0.397839 -0.366137 -0.506125 +0.31105 0.0078336 -0.503254 +-0.509594 0.29364 -0.290723 +-0.165728 0.307969 0.506356 +0.43202 0.492974 0.282448 +-0.498805 -0.379954 -0.122546 +0.424061 -0.100064 0.490897 +0.0643114 -0.493388 0.4583 +0.0581151 -0.499783 0.433154 +-0.0976459 -0.078487 -0.498797 +-0.0962564 -0.0459841 -0.501452 +-0.0616146 0.189159 0.503654 +-0.498695 0.19309 -0.0421721 +0.200051 0.509868 0.242311 +0.471137 -0.239641 0.483478 +-0.490975 0.194977 -0.0150665 +-0.498938 0.168165 -0.0270683 +0.509909 0.341229 0.00481851 +0.500613 0.288124 0.00557042 +0.498333 0.286565 0.0343669 +-0.195557 -0.463738 -0.472087 +-0.015745 -0.459486 -0.479058 +-0.229789 0.49023 -0.436696 +0.365962 -0.504362 -0.397578 +0.344845 -0.513054 -0.419855 +-0.496 0.0690125 -0.29035 +0.295275 -0.482465 -0.472063 +-0.498192 0.0746119 -0.322355 +-0.504812 0.104074 -0.299229 +-0.342053 0.502497 0.1862 +-0.507931 0.273689 0.361974 +-0.516425 0.225971 0.351126 +-0.13271 -0.50584 -0.0614043 +0.0174146 -0.382724 -0.496683 +-0.387244 -0.506375 -0.15882 +-0.393315 -0.495698 -0.215012 +-0.414357 -0.495463 -0.152981 +-0.33794 0.508827 -0.0337336 +0.506895 0.41947 -0.0315593 +-0.274115 -0.0113527 -0.509451 +0.259313 -0.329532 -0.499745 +-0.443911 -0.326486 -0.495527 +0.504814 -0.388503 -0.148077 +-0.505412 -0.403224 -0.125293 +0.496174 -0.405609 -0.165283 +0.1654 0.483143 0.447625 +0.41386 -0.506406 -0.392561 +-0.460487 0.221466 -0.495565 +-0.510237 -0.412159 -0.0565214 +0.488115 -0.297848 0.4443 +-0.494671 -0.00865616 0.460571 +0.480885 -0.462954 -0.466515 +-0.43873 -0.277854 -0.492577 +0.495566 0.355206 0.425184 +0.0250023 0.0753391 -0.496002 +0.212123 -0.440148 0.487473 +0.313035 0.420523 0.500865 +0.510081 0.136975 -0.254289 +0.49965 0.129965 -0.282848 +0.410963 0.249562 0.512129 +0.364426 0.290226 0.505129 +0.392594 0.301359 0.513269 +0.200778 0.512403 0.301048 +-0.185294 -0.0889066 0.492699 +-0.305624 0.44154 0.505751 +-0.213554 -0.462171 0.484624 +0.258481 -0.338657 0.500668 +0.231866 -0.319821 0.499283 +0.235227 -0.287104 0.497886 +0.438321 0.0352712 -0.50406 +-0.480076 -0.416388 -0.454971 +-0.352037 0.501489 0.125153 +0.409814 0.221987 0.500351 +0.0938709 -0.50111 0.0597201 +0.217206 0.394585 0.512627 +-0.481343 -0.0540415 0.469633 +-0.223764 0.506162 0.152735 +0.0848342 -0.50001 0.0298919 +-0.421839 -0.41971 -0.49595 +-0.484748 0.471741 -0.336101 +-0.279081 0.487141 -0.460359 +0.354279 -0.27316 -0.504365 +0.25488 0.357352 0.512631 +-0.238223 -0.507024 -0.210132 +-0.505341 -0.369775 -0.0960816 +-0.260704 -0.492838 -0.18864 +0.469676 0.490034 -0.32982 +-0.188645 -0.505787 -0.113419 +-0.216582 -0.50964 -0.122705 +0.282092 0.265592 0.501452 +0.173841 -0.50404 0.108381 +0.200143 -0.496086 0.0589085 +0.482056 0.26318 0.450646 +0.159196 -0.501787 0.0796601 +-0.0620518 0.50153 -0.410216 +0.492271 -0.417262 -0.105958 +-0.00959952 0.495257 -0.406787 +0.166111 -0.494118 -0.4482 +0.25375 -0.468095 0.473958 +-0.497392 0.24461 -0.0725684 +0.0918492 -0.196672 0.501876 +-0.497721 0.277139 -0.0821838 +0.427873 0.234649 0.502901 +-0.193186 -0.481319 0.479817 +-0.454821 0.495189 0.222202 +-0.0833518 0.0381289 0.499519 +-0.424374 0.0427979 -0.499702 +0.314117 -0.507862 -0.412976 +0.24562 0.442452 0.48405 +0.212471 0.448217 0.498025 +-0.501983 -0.404462 0.239034 +0.322968 -0.310478 0.509072 +-0.326182 0.00690428 -0.497448 +-0.455119 0.479362 0.173295 +0.336285 -0.259056 0.50297 +-0.382296 -0.169834 -0.506477 +0.0359456 0.0230558 0.493136 +0.476317 -0.356313 -0.46849 +0.0901405 -0.459878 -0.481383 +-0.348538 -0.176998 -0.497842 +-0.506908 -0.362308 -0.238279 +-0.492947 0.131813 -0.0719708 +-0.498401 0.12475 -0.105404 +-0.495474 -0.453016 0.152249 +0.49178 -0.462497 0.328894 +-0.507549 0.156625 -0.0940081 +0.0949616 0.119218 0.503144 +0.514081 0.0453473 0.356241 +0.506566 0.0696801 0.34938 +0.247848 0.506927 0.425903 +-0.466193 -0.451407 -0.469561 +0.495814 -0.153049 0.281665 +-0.493207 0.131094 -0.197451 +-0.512057 -0.381528 -0.173223 +-0.449219 0.483618 -0.173964 +0.384307 -0.495266 -0.16269 +0.357602 -0.502711 -0.153809 +-0.502637 -0.198895 -0.0335044 +-0.502597 -0.156861 -0.0120176 +-0.362921 -0.466339 0.480753 +-0.499454 -0.201055 -0.00910244 +0.055866 0.454064 0.477237 +0.154621 0.505114 -0.440027 +0.123351 -0.489301 0.45621 +0.104134 0.409989 0.494247 +0.451898 0.0821952 -0.483061 +0.437389 0.127836 -0.490187 +-0.489814 0.441527 0.422268 +0.285291 -0.324848 -0.506781 +0.262864 -0.302837 -0.50958 +-0.149727 -0.0459401 -0.498599 +-0.151384 -0.0771444 -0.509127 +-0.123997 -0.0619299 -0.506554 +0.233468 -0.255802 -0.510803 +0.0438142 -0.502849 -0.00575703 +-0.328699 -0.50762 -0.144844 +0.140587 0.451591 -0.498646 +-0.465402 0.059398 0.480457 +0.226285 -0.22683 -0.50276 +0.502716 0.054662 0.328941 +-0.490771 -0.397689 0.438173 +-0.512372 -0.339071 -0.212617 +-0.494664 -0.00559417 -0.446251 +-0.501723 -0.0246711 -0.405934 +-0.0471864 0.508634 0.324371 +-0.360159 -0.508436 0.113271 +-0.497916 -0.0468373 -0.425272 +-0.487849 -0.110567 -0.429574 +0.479574 -0.460896 -0.294024 +-0.479385 -0.0928162 -0.450818 +-0.452358 0.459847 -0.472677 +0.282064 0.497866 -0.448551 +0.0765551 0.396713 0.495962 +-0.482614 -0.352388 0.46256 +0.133064 0.395993 0.499328 +0.232507 0.490096 -0.442282 +-0.433947 -0.105088 0.496902 +-0.157902 -0.452209 -0.491645 +0.176242 -0.31392 0.505606 +0.51421 0.319317 0.180253 +0.500096 0.324022 0.227298 +-0.24247 0.496691 0.323459 +0.383009 -0.0985309 0.514035 +-0.10911 0.493329 -0.26311 +0.269938 -0.484103 -0.477869 +-0.315677 -0.50666 0.0974182 +0.0113102 -0.504175 -0.111276 +0.0736388 -0.504822 -0.11281 +0.491267 0.0535117 -0.465507 +0.0511912 -0.495764 -0.122935 +0.458463 0.437618 0.473175 +0.501977 0.28342 -0.345459 +0.499105 0.248155 -0.325053 +-0.315754 0.192684 0.508332 +-0.313907 -0.172318 -0.50685 +-0.428338 0.506326 -0.135299 +-0.363788 0.20512 0.502165 +-0.318616 0.235519 0.497271 +0.110931 0.495624 -0.463115 +-0.456737 0.146134 -0.492034 +0.0888696 0.480756 -0.459418 +0.19927 0.0859515 -0.496127 +-0.344353 -0.501541 -0.0987706 +-0.461563 -0.477688 0.021612 +0.436631 0.498512 -0.399874 +-0.345428 -0.508165 -0.0708447 +-0.324577 -0.506014 -0.0593447 +-0.145201 -0.135567 0.493345 +-0.280572 -0.317216 -0.501287 +-0.13815 -0.16965 0.49231 +-0.456003 -0.479752 0.172913 +0.501792 -0.202616 -0.286939 +0.4959 -0.179373 -0.279151 +-0.466932 -0.472265 0.195321 +0.355785 -0.508805 -0.301301 +0.239497 -0.498889 -0.370127 +0.214853 -0.512001 -0.358867 +0.439024 0.122762 0.486844 +-0.0881406 0.512923 0.357182 +0.258836 -0.512485 -0.356954 +-0.504098 -0.313858 0.414537 +-0.492357 -0.070044 -0.410175 +-0.510104 0.223763 0.18662 +0.503307 -0.0707862 -0.230661 +-0.50874 0.10388 0.35179 +-0.392383 0.505806 -0.0615789 +0.443221 0.156579 -0.493753 +-0.410224 0.492348 -0.0860378 +-0.51201 -0.299883 0.357076 +-0.0964818 0.500759 0.409185 +0.508147 0.383693 -0.101058 +0.509168 0.411447 -0.143555 +0.265897 0.506205 0.174622 +-0.491687 -0.469905 0.187753 +0.497847 -0.365478 0.134614 +-0.0178105 0.0121519 0.496729 +-0.0443643 -0.0100209 0.502396 +-0.0615889 0.507856 0.300006 +-0.0499725 0.0249756 0.500616 +0.51277 -0.310661 0.241331 +0.403835 0.14716 0.510207 +0.130202 0.503934 0.120692 +0.272863 0.496411 0.0857352 +-0.41377 0.33241 0.492713 +0.184111 0.513224 0.319684 +-0.451233 -0.0268235 -0.494009 +-0.204802 -0.477277 -0.460904 +0.190988 0.50976 0.349145 +-0.497876 -0.205531 -0.457553 +0.267309 0.511741 0.142607 +-0.486697 -0.131463 -0.452147 +-0.449706 -0.491373 -0.310473 +-0.237962 0.207015 -0.491549 +-0.21268 0.208016 -0.498489 +0.0081655 0.297091 0.495059 +0.480696 0.475494 -0.116674 +-0.229549 0.231555 -0.511555 +0.50004 -0.0957745 0.206652 +0.327633 -0.511983 0.248395 +0.131701 -0.242467 0.503609 +0.511113 0.139878 0.292648 +-0.500406 0.262297 0.0880798 +0.498834 -0.0830065 0.166838 +-0.483606 0.465755 -0.393319 +-0.486151 0.453424 0.156474 +0.398237 0.509721 -0.370391 +0.468945 -0.489117 -0.220574 +0.386339 0.495215 0.073351 +0.406131 0.503173 -0.347547 +-0.331203 0.506609 0.288861 +0.426097 0.149455 0.50588 +-0.324947 0.502428 0.318427 +0.338624 0.329123 -0.504311 +-0.228374 -0.407925 -0.493455 +0.44655 -0.221847 -0.485931 +0.0440957 -0.498081 -0.358299 +0.100788 0.461489 0.490535 +0.0915936 0.496655 0.189528 +-0.149612 -0.482951 -0.475263 +0.503943 -0.0668778 -0.0939557 +-0.497061 0.216155 -0.431759 +0.493943 0.430694 -0.416763 +-0.0712604 -0.0328011 0.492186 +0.113833 0.450359 -0.489273 +-0.44493 -0.495658 0.0089157 +-0.424771 -0.49226 -0.0159303 +0.464938 -0.344357 0.477026 +-0.447024 -0.494226 -0.0190956 +0.16986 0.509617 0.368683 +0.150904 0.51063 0.387897 +0.115768 0.494768 -0.0860927 +-0.053293 -0.506089 0.297405 +0.466232 -0.0458298 -0.473347 +-0.504293 0.423811 -0.00226809 +-0.482626 0.449081 -0.0320001 +0.445813 0.497217 -0.367836 +-0.488927 0.447259 -0.00531057 +-0.0865598 -0.49337 -0.244466 +0.149362 0.502566 -0.0928041 +-0.0586287 -0.506043 -0.247029 +-0.0744777 -0.503937 -0.268902 +0.336592 -0.508836 -0.279972 +-0.434918 -0.222242 0.505634 +-0.205327 -0.504476 0.434626 +-0.206318 -0.502377 -0.0134125 +0.499023 0.336339 0.0370394 +-0.209013 -0.508866 0.016759 +0.222194 -0.4991 0.149117 +0.186459 -0.500588 0.140132 +0.133471 -0.0899635 0.504789 +-0.156453 -0.498133 -0.329595 +-0.211605 -0.512153 -0.288124 +-0.177946 -0.493711 -0.278377 +-0.0102892 -0.497577 0.252105 +0.143762 -0.498742 0.30422 +-0.343422 0.482253 -0.47618 +0.114151 -0.503382 0.30733 +0.133266 -0.501528 0.332714 +0.40742 0.0589828 -0.498439 +0.402438 -0.0112951 -0.497043 +0.406613 0.021679 -0.495096 +-0.297394 0.506399 0.0165041 +0.0390177 0.505802 -0.126198 +-0.177998 0.475258 0.474462 +0.412987 -0.499317 0.226085 +0.160067 0.490445 0.199137 +0.317262 -0.495049 -0.0765094 +0.125945 0.504671 -0.117516 +0.450257 0.483291 0.101556 +0.279549 -0.506539 -0.0731869 +0.296886 -0.503927 -0.046117 +0.2362 0.240416 -0.507469 +-0.109238 0.495251 0.42729 +-0.231825 0.47702 -0.473701 +0.502084 -0.159871 -0.416373 +0.325976 -0.51175 0.130255 +0.0747362 0.502961 0.144642 +0.507911 0.346483 -0.263427 +-0.321527 0.46661 -0.478282 +0.49963 0.384952 -0.222325 +0.503097 0.370864 -0.271931 +-0.429368 0.364795 -0.49899 +0.202232 -0.333043 0.497847 +0.329379 -0.501417 -0.0417915 +-0.179298 -0.0914172 -0.503974 +-0.205078 -0.0733047 -0.497858 +-0.207835 -0.105132 -0.490645 +0.501029 0.324799 0.261188 +0.512074 0.357161 0.275744 +-0.0869799 -0.396622 0.500047 +-0.103808 -0.365623 0.50219 +-0.0687941 -0.368593 0.511696 +0.45816 0.498126 0.409227 +0.502997 0.314838 0.36388 +0.50463 0.348893 0.350746 +-0.489897 0.447408 0.0410086 +0.0967432 0.494086 0.162135 +-0.228204 0.223079 0.497662 +0.10104 0.492293 0.134713 +-0.179719 0.229202 0.498301 +-0.327004 0.495667 -0.0986911 +-0.300893 0.507808 -0.0809735 +0.341737 -0.49821 -0.0121909 +0.38806 -0.499209 0.0146814 +0.359254 -0.499346 -0.0359233 +-0.358126 -0.351104 0.514879 +-0.34271 -0.319774 0.502125 +-0.230207 -0.501943 0.445436 +-0.210622 -0.499803 -0.389339 +0.0579829 0.102845 -0.497463 +0.0876524 0.105767 -0.49134 +-0.0969598 -0.482242 -0.464264 +-0.506106 0.0964875 0.0358305 +-0.494298 0.0883927 0.00424333 +-0.243581 -0.473121 0.485076 +0.0863922 -0.467714 0.481687 +-0.126996 -0.50708 -0.322815 +-0.506992 0.120035 0.0137138 +0.331022 0.509631 -0.134032 +-0.448314 -0.487247 0.040449 +-0.126662 -0.481657 -0.456432 +-0.501172 0.38258 -0.304929 +-0.463793 0.363979 -0.478991 +0.497334 -0.0298159 -0.273798 +-0.497941 0.426879 -0.290911 +0.460509 -0.0788505 0.487039 +0.352539 0.0737962 0.507308 +-0.451582 -0.489819 -0.0671788 +-0.183483 0.0153463 -0.50567 +-0.264919 0.487631 0.470322 +0.471318 -0.465155 0.377998 +0.482085 0.47649 0.00216214 +0.469477 0.270781 -0.480832 +0.13099 0.496117 -0.284783 +-0.308331 0.49833 -0.2454 +-0.217119 0.503043 0.179603 +0.117652 -0.310241 0.511514 +0.101423 -0.250764 0.494918 +0.150028 -0.295156 0.503414 +-0.00257828 -0.492131 -0.0853904 +-0.0437208 -0.503667 0.263823 +-0.0181835 -0.502183 -0.0537975 +0.264167 0.223213 0.50521 +0.501428 0.296998 0.188001 +0.00593641 -0.506933 -0.0357915 +0.124665 0.503691 -0.398717 +0.449385 0.235332 0.502457 +0.156053 0.439948 0.492558 +0.153105 0.461523 0.478281 +0.503921 0.227074 0.113332 +0.505786 0.215556 0.0838453 +0.368799 0.240316 -0.508359 +0.506159 0.195669 0.103897 +0.171674 -0.212903 -0.49006 +0.132358 -0.261304 -0.508543 +0.497937 -0.239076 0.257609 +0.161054 -0.263812 -0.501635 +-0.33537 -0.496384 -0.440711 +0.145477 -0.379647 -0.511087 +0.501408 -0.0809898 -0.384144 +0.500945 0.373129 -0.0454965 +0.510033 0.404399 -0.00100272 +0.496731 -0.0648747 -0.399036 +0.510359 -0.0591788 -0.375154 +-0.402817 0.514492 -0.240761 +-0.339332 -0.0242532 -0.498663 +-0.344366 0.0326268 -0.502854 +-0.208497 -0.443709 0.501819 +0.337318 0.501892 0.0414943 +0.476521 -0.0977533 0.485087 +0.510074 -0.0400449 -0.227089 +0.515213 0.260978 0.306205 +-0.499161 0.434462 -0.32241 +0.123802 0.506149 0.382108 +0.464566 -0.479519 0.127754 +0.496443 -0.184653 0.106225 +-0.496003 0.35709 -0.0935337 +0.49506 -0.156177 0.094433 +0.50588 -0.180614 0.0765429 +0.136746 -0.497122 -0.13782 +0.331475 -0.0016586 0.514131 +0.183888 -0.501292 -0.130338 +0.498578 -0.457054 0.111983 +0.496353 0.112059 0.449307 +-0.236571 -0.449605 0.494569 +-0.227779 -0.332286 0.513327 +0.4943 0.424206 0.344093 +-0.435756 -0.489871 0.378093 +0.194364 -0.501453 -0.378239 +-0.507633 0.0583896 -0.219962 +-0.497408 -0.113548 0.117519 +0.0276602 0.353387 -0.506375 +0.375662 0.511736 -0.380893 +-0.135285 0.505657 -0.378459 +0.499164 0.231115 0.255834 +0.462492 0.489007 0.00167004 +0.50362 0.000905376 0.143989 +0.509518 0.275074 0.277215 +0.504719 0.257153 0.25184 +-0.456851 0.47715 0.0983958 +0.00925052 0.116102 -0.501154 +0.00644436 0.0874251 -0.500202 +0.0306255 0.0974766 -0.489809 +0.423778 -0.493915 0.358104 +-0.443237 0.486909 -0.342534 +0.0120588 0.500998 0.316462 +-0.443658 0.489727 -0.0475558 +-0.267474 -0.495782 0.0422313 +-0.237668 -0.503275 0.0300989 +-0.261929 -0.496146 0.0106536 +0.431605 0.373561 -0.502306 +-0.192183 0.507423 -0.311244 +0.0252458 -0.506705 0.204044 +-0.00151004 -0.501761 0.185192 +0.477847 -0.248739 -0.468263 +-0.087604 -0.498317 -0.0967768 +-0.00535158 -0.499291 0.218039 +-0.455509 -0.15474 -0.485424 +0.504678 -0.368866 0.423363 +0.510001 -0.391076 -0.074884 +0.50143 -0.380766 -0.124517 +-0.515175 0.212048 -0.347899 +-0.183791 -0.495894 0.0338141 +-0.234283 -0.171818 0.491819 +-0.206077 -0.147377 0.500246 +-0.197818 -0.183558 0.502972 +-0.50744 0.194959 0.402129 +-0.495132 0.209483 0.421867 +0.43607 -0.493984 -0.0545366 +-0.448238 -0.184935 -0.483336 +0.391506 -0.501275 -0.40679 +0.509468 0.134467 -0.417458 +0.510221 0.357561 0.0555318 +-0.202033 0.472272 -0.471915 +0.512918 0.322555 0.0906746 +0.508959 -0.352699 -0.430364 +0.506794 0.343508 0.115315 +0.050447 -0.248439 -0.498396 +-0.314712 -0.472315 0.465028 +-0.493686 -0.128062 0.181295 +0.280382 0.503358 0.0321651 +-0.507483 0.367156 -0.136307 +-0.509185 0.400643 -0.168464 +-0.501418 0.38214 -0.111848 +-0.49983 0.347908 0.0663479 +0.48368 -0.454846 0.0560921 +-0.511693 0.345445 -0.00404005 +0.104678 0.0609086 0.502546 +-0.508739 0.177602 -0.39736 +0.461953 -0.472483 -0.446223 +-0.504076 0.223358 -0.370969 +0.425615 -0.0191721 0.490005 +0.0555508 -0.496785 0.190982 +0.431949 0.00902494 0.501713 +-0.458166 0.476065 -0.260398 +0.0895533 -0.505904 0.151404 +0.0704878 -0.495767 0.130031 +-0.509001 -0.0604573 -0.314027 +-0.493709 -0.0793176 -0.292986 +-0.502049 0.0642353 0.0269652 +0.405255 -0.112941 0.511937 +0.433449 0.493274 0.3665 +-0.501976 -0.10798 -0.27886 +-0.0521319 -0.4476 0.495943 +0.104449 0.0797149 -0.500531 +0.120752 0.0527539 -0.49784 +0.487439 0.454843 -0.195048 +0.499275 -0.302043 -0.41009 +0.0532984 0.358259 -0.51017 +0.0308369 0.305118 -0.504964 +0.0757254 0.337614 -0.501808 +-0.496163 -0.119926 0.0165795 +0.499033 0.391911 -0.253778 +-0.499448 -0.121614 -0.362517 +-0.508751 -0.0843064 -0.324879 +-0.503824 -0.140508 -0.340899 +0.502703 -0.07507 0.302303 +-0.121631 0.503683 -0.403367 +-0.453701 0.00838233 0.478818 +0.118701 -0.493172 0.0364652 +0.148956 -0.507821 0.051154 +-0.33926 -0.50453 -0.171953 +-0.310224 -0.498726 -0.168794 +-0.500531 -0.0248243 0.384294 +-0.320266 -0.498568 -0.19494 +0.296664 0.158665 0.499224 +-0.299814 -0.495672 0.0787373 +0.445512 -0.430851 0.48875 +-0.0145515 -0.490812 -0.0188452 +0.464573 0.448349 -0.469168 +0.424136 0.492313 0.0697044 +0.344154 0.172536 0.51554 +0.330865 0.153634 0.503438 +-0.0557954 -0.239473 -0.502579 +-0.501734 -0.426479 0.0600804 +0.0725494 -0.497107 -0.456001 +0.45776 -0.453184 0.46714 +0.152604 0.0537352 -0.493904 +0.246477 0.493372 0.0959254 +0.410687 0.0741818 0.506961 +0.212537 -0.506156 0.110893 +0.508276 0.379077 0.370404 +0.448878 0.475849 0.444749 +0.170076 0.0250852 -0.489839 +-0.098872 -0.503822 0.0162212 +0.490844 -0.462591 -0.415054 +-0.0707648 -0.498475 -0.00507728 +-0.267303 -0.441531 -0.48713 +0.458754 0.482336 -0.386878 +-0.190495 0.487161 -0.459704 +-0.44806 -0.487724 -0.173946 +-0.496521 -0.42396 0.25591 +-0.514965 -0.20725 0.332984 +-0.506445 -0.230896 0.302515 +-0.504755 -0.193541 0.303101 +0.465166 0.468683 0.44435 +0.489333 0.110498 -0.468112 +0.465709 0.106923 0.482404 +0.426761 -0.0280375 -0.501474 +0.173939 0.507753 0.171955 +0.509982 0.0584545 -0.378489 +0.510014 0.0799327 -0.333601 +-0.0794858 0.5084 0.231721 +-0.496543 0.231614 0.420316 +0.00970726 -0.219481 0.497917 +-0.0114614 -0.19169 0.501734 +0.364545 -0.368509 0.502198 +0.48802 0.418724 0.448271 +-0.287583 0.510895 -0.208403 +0.491635 0.430158 0.4288 +0.49206 0.404643 0.428293 +-0.433845 -0.498722 0.0567021 +-0.111579 0.0994934 -0.506045 +-0.0859155 0.49451 0.199095 +-0.271322 -0.504321 0.163079 +-0.0552894 0.494552 0.447423 +-0.287943 -0.494042 0.100939 +0.374605 -0.188691 0.494974 +-0.158009 0.508568 -0.304463 +0.372864 -0.154162 0.502276 +0.401437 -0.170767 0.503098 +-0.429709 -0.487765 0.0870263 +-0.406998 0.506293 -0.116503 +0.464105 0.343018 0.485217 +-0.0551454 0.485571 0.467582 +-0.489732 -0.437665 -0.0954432 +0.498005 -0.444515 0.0688748 +-0.424042 0.50119 -0.157865 +0.506001 -0.118795 0.192527 +0.487151 -0.450652 -0.0781023 +-0.502696 0.0248184 -0.327452 +0.508448 -0.211386 0.393117 +-0.285766 -0.0129388 0.494736 +-0.288794 0.0487309 0.498943 +-0.171006 -0.00606154 -0.506168 +0.412278 0.318319 -0.503815 +0.426419 0.096496 0.505323 +0.440268 0.203711 -0.485042 +0.452116 0.179887 -0.497443 +0.0610567 0.305274 -0.506726 +0.359442 0.459115 0.483233 +-0.468862 0.102193 -0.491892 +0.479361 -0.461226 0.160657 +0.447636 0.485248 0.272202 +-0.114419 0.49367 0.220571 +-0.508626 0.251118 -0.119756 +-0.504176 0.203076 -0.107171 +0.212162 -0.495458 -0.219328 +0.100906 -0.0664588 0.507823 +0.0875348 -0.0887766 0.49827 +0.061335 -0.0933793 0.502621 +0.503483 0.108383 0.376661 +0.504432 0.0739365 0.377117 +0.0498098 0.424698 -0.495473 +-0.310042 -0.315194 0.518393 +0.0317347 0.487115 -0.438563 +-0.505233 0.381819 0.0777082 +0.00923891 0.461168 -0.488922 +0.486839 -0.348804 0.469835 +-0.502288 0.161557 -0.344317 +-0.160871 0.397431 0.512129 +0.486057 -0.219416 -0.435046 +-0.514802 0.103946 -0.368996 +-0.495383 0.156041 -0.375497 +0.494944 0.13353 0.143548 +0.505681 0.0651707 0.143259 +0.498156 -0.108962 0.12181 +0.333103 -0.252054 -0.500226 +0.505777 -0.131652 0.110398 +0.494032 -0.130404 0.141524 +-0.514043 0.3203 0.240438 +0.183901 -0.223408 0.493612 +-0.123044 0.151318 -0.492975 +0.208475 -0.26847 0.495028 +0.154523 -0.263194 0.498712 +0.400523 0.500769 -0.0262918 +-0.441179 -0.349441 -0.510262 +0.452843 0.213295 0.47992 +-0.463694 0.484719 0.363524 +0.509073 0.368418 -0.433242 +-0.504628 -0.249157 -0.408466 +-0.501776 -0.284695 -0.399066 +0.486048 0.453666 0.225168 +-0.5179 -0.315539 0.299473 +0.451813 0.491767 0.181074 +-0.504405 -0.281829 0.337282 +0.494708 -0.26167 0.0262441 +0.488836 -0.42719 -0.226962 +0.510597 -0.235484 0.00578794 +0.510127 -0.13011 0.358484 +0.504727 -0.128963 0.329023 +0.513778 -0.156163 0.34222 +0.504099 0.175093 -0.0314203 +0.454657 -0.489872 -0.36062 +0.318589 -0.446653 0.505608 +0.00941077 0.229073 0.491406 +0.23929 -0.49775 -0.234583 +-0.497654 0.156286 -0.220201 +-0.494385 0.123464 -0.230844 +-0.493818 0.149476 -0.254013 +0.241076 -0.503653 -0.206802 +-0.0849923 -0.33865 0.49537 +-0.200542 0.180401 -0.495698 +-0.207391 0.129019 -0.505796 +-0.258477 -0.156457 -0.494716 +-0.217259 -0.185667 -0.503299 +0.464946 -0.474838 -0.279749 +-0.439685 0.485711 0.407918 +0.15579 0.492662 -0.460376 +0.0633358 0.496896 -0.453819 +0.498884 0.294556 0.303908 +0.503738 0.319806 0.327912 +0.487137 0.00208146 -0.436944 +0.506523 0.32528 0.293294 +0.424696 -0.218865 -0.494196 +0.439715 -0.193109 -0.498318 +-0.510842 0.355262 0.1917 +-0.501884 0.388832 0.209958 +-0.460954 -0.426132 0.487943 +-0.511106 0.379176 0.248683 +0.490912 -0.0315554 -0.097533 +0.498157 0.24109 -0.235339 +-0.285738 -0.504799 -0.00977095 +0.0610617 -0.45857 -0.490475 +-0.312751 -0.509799 -0.0327718 +-0.454309 -0.45091 0.478152 +-0.315924 -0.510393 0.00368663 +0.490949 -0.054587 -0.166635 +0.507143 -0.0904345 -0.117341 +0.50915 0.0983238 0.101909 +0.493592 -0.0279457 -0.131205 +0.500894 -0.205831 0.0556959 +0.492058 -0.232672 0.0371327 +0.501347 -0.236726 0.0663961 +-0.409977 0.365881 0.499213 +0.495898 0.0772775 -0.267592 +0.494572 0.109457 -0.262792 +-0.00369799 0.501092 -0.218945 +0.225752 0.502719 -0.303513 +0.490231 0.467324 0.11385 +0.306404 -0.0442302 -0.501496 +0.0263514 0.493796 0.429825 +0.287937 -0.0714985 -0.495272 +0.467836 0.462586 0.467612 +-0.496783 0.139507 0.452993 +-0.1135 0.496286 0.0972407 +-0.0808104 0.492829 0.108325 +0.217889 -0.501786 0.425437 +-0.110174 0.503035 0.13265 +0.179669 0.515741 -0.336341 +0.162167 0.499409 -0.307436 +0.512811 -0.287664 -0.393202 +-0.497335 0.260429 -0.160151 +0.511313 0.0460799 -0.324285 +-0.50376 0.289891 -0.158615 +0.452851 -0.479291 0.25329 +0.457812 0.455679 0.474094 +-0.30425 -0.505037 -0.294824 +-0.49502 0.272456 -0.136519 +-0.1297 0.435331 -0.493707 +0.0683762 -0.502045 -0.34433 +0.154271 -0.501739 -0.334321 +0.0162218 -0.468031 0.488532 +0.487814 0.290434 -0.454639 +-0.44756 0.499132 0.195667 +0.492031 -0.0799484 0.0531376 +0.501042 -0.0848152 0.0167112 +0.489456 -0.105333 0.0704236 +-0.0783124 -0.256035 0.505122 +0.509869 0.413156 0.170673 +0.50347 0.438306 0.224566 +0.491273 0.043781 -0.220741 +0.466974 0.477032 0.027089 +0.509961 0.0944905 -0.220182 +0.501297 0.0937605 -0.2441 +0.496978 -0.17838 -0.30422 +0.503117 -0.209874 -0.349903 +0.511066 -0.241942 -0.360923 +-0.503639 0.175799 0.116683 +-0.490387 0.168893 0.0843157 +-0.00878357 0.4326 0.503242 +-0.509159 0.201065 0.0946378 +-0.511852 0.35112 0.128651 +-0.0314009 0.4823 0.481663 +0.333573 -0.103668 -0.510352 +0.320918 -0.0738657 -0.501189 +0.396459 -0.0578667 -0.494626 +0.481753 -0.142571 0.454746 +-0.482323 -0.0316309 0.470323 +0.352832 -0.0780399 -0.498997 +0.395493 -0.111312 -0.500704 +0.492409 0.183423 -0.269604 +-0.0920044 -0.0905125 0.500314 +-0.125014 -0.0783761 0.492963 +-0.0982185 -0.0556697 0.497005 +-0.505317 -0.259624 -0.375696 +-0.503832 -0.264931 -0.341771 +-0.508139 -0.162001 0.12601 +-0.497277 -0.111824 0.154355 +-0.508546 -0.159475 0.151442 +0.506394 0.111291 0.148538 +0.194218 0.500994 -0.314339 +0.233948 0.481313 0.44217 +-0.216661 0.0121059 -0.494195 +-0.242028 0.0217947 -0.496524 +0.505062 0.197577 0.300716 +-0.472487 0.464059 0.446173 +-0.245476 -0.00249334 -0.503817 +-0.35495 0.353132 0.502928 +-0.336866 0.329463 0.500125 +-0.387107 0.344305 0.509816 +-0.0393359 0.512371 -0.399115 +0.0141047 0.495101 -0.387795 +0.0329116 -0.453433 0.489829 +0.246176 0.386464 0.514937 +0.212224 0.421377 0.507074 +0.266491 0.406624 0.512166 +0.514307 -0.383461 0.225661 +0.515911 -0.352761 0.219074 +-0.503501 -0.0462598 -0.291707 +0.498679 -0.370148 0.195154 +-0.444749 0.491527 -0.245099 +-0.173304 0.160069 0.499813 +0.451116 -0.166308 -0.493687 +0.0575796 0.501635 0.0155603 +-0.101762 -0.508047 -0.0179087 +0.0429198 -0.476988 -0.457307 +0.515413 -0.2356 0.376113 +-0.13018 -0.506877 -0.0309761 +0.484624 0.463383 0.0283457 +-0.403613 0.0970136 -0.510503 +-0.384569 0.0516015 -0.509804 +0.040714 0.47009 -0.486533 +-0.373558 0.104918 -0.513023 +0.153102 -0.00430777 -0.508287 +0.168716 -0.0345447 -0.491688 +0.187041 -0.00505262 -0.498498 +0.216817 0.499137 -0.267074 +0.479634 -0.475663 0.1025 +-0.375596 -0.219703 0.508543 +-0.377274 -0.261887 0.503465 +0.500552 -0.423593 -0.354819 +-0.407138 -0.238982 0.504496 +0.50123 0.0966347 0.308365 +0.509229 0.1059 0.255539 +0.420622 -0.503543 0.313115 +0.413612 -0.496063 0.258264 +0.390896 -0.510769 0.277772 +-0.465352 0.130376 0.485411 +-0.265933 0.498211 -0.237244 +-0.493937 0.103704 0.178925 +-0.502406 0.0854523 0.202204 +0.502707 0.0447508 0.248345 +0.426452 -0.126864 0.504653 +0.501131 0.0383412 0.302418 +-0.41692 0.115902 0.49573 +0.487082 -0.458002 -0.169761 +0.446079 -0.166749 0.492059 +0.489038 -0.426715 0.119327 +0.460945 -0.0199038 -0.48523 +0.493228 0.0855428 0.281381 +0.44426 -0.502733 0.152634 +0.0756325 0.06889 0.49547 +0.0993359 0.0892987 0.50624 +0.204104 -0.49955 0.447758 +-0.345203 -0.42532 0.497239 +0.480039 -0.448441 -0.473597 +-0.472298 -0.467705 -0.405122 +0.13443 0.504655 0.331339 +-0.00142785 0.39457 -0.506829 +0.301874 -0.100622 -0.510913 +0.0179091 0.418416 -0.507154 +-0.110445 0.191181 0.490683 +0.33998 0.419795 0.503716 +-0.0892164 0.155727 0.49317 +0.450377 -0.0358642 0.501488 +-0.131887 0.176051 0.508568 +-0.031424 -0.080176 0.497185 +0.498422 -0.433234 -0.151515 +-0.0254977 -0.115642 0.49829 +-0.505488 0.0356051 0.318824 +-0.0589329 -0.102929 0.507448 +-0.495955 -0.321484 0.132645 +-0.497698 -0.376689 0.145287 +-0.34501 0.513044 -0.303486 +-0.365863 -0.159425 0.503778 +-0.182044 -0.495027 0.00228011 +-0.452455 -0.488238 -0.363983 +-0.469647 0.0336507 0.490224 +-0.155871 -0.495782 0.0179717 +-0.155731 -0.507868 -0.0136113 +-0.514098 0.337831 0.0316084 +0.45053 -0.257963 0.486246 +-0.499508 -0.343952 -0.176621 +0.50006 0.443146 -0.327654 +0.496005 0.394141 -0.286045 +0.48666 -0.452101 -0.134273 +-0.469686 0.483448 -0.00564199 +0.487307 0.442442 -0.293305 +-0.348053 0.518712 -0.33733 +-0.400006 0.504592 -0.35858 +0.113163 0.497391 0.353614 +0.485763 0.468144 0.270355 +-0.434352 0.413953 0.493389 +-0.456724 0.421663 0.487487 +-0.160829 -0.286437 0.51264 +0.497776 -0.0928462 -0.0428014 +-0.174002 -0.252737 0.503638 +-0.140003 -0.259099 0.498959 +0.363651 0.5013 -0.332903 +0.379911 0.499407 -0.352651 +0.486412 -0.473284 0.00632862 +-0.400487 -0.512561 0.404374 +-0.49652 -0.385311 0.114734 +-0.495269 -0.362578 0.0907891 +-0.507919 -0.337369 0.0679807 +0.358758 -0.131906 0.505102 +-0.423208 -0.332055 0.499365 +0.142664 0.495384 0.360635 +0.315233 -0.139324 0.502311 +0.459174 -0.489036 0.10473 +0.508509 -0.204492 -0.183136 +0.497536 -0.182104 -0.204756 +-0.510115 -0.285949 -0.179801 +-0.195627 -0.279915 0.49655 +-0.495737 -0.257845 -0.17806 +-0.508329 -0.241717 -0.145513 +-0.490156 -0.450377 0.0144878 +0.314482 0.127488 0.512026 +-0.0459331 0.497509 -0.344308 +0.00780109 0.50567 -0.342584 +-0.265507 -0.500302 0.406108 +0.498955 0.150475 0.319917 +-0.222217 -0.501773 0.384133 +-0.249246 -0.511458 0.383588 +0.194 -0.495855 -0.454366 +-0.236483 0.496344 -0.0159473 +0.484832 0.185004 -0.448486 +-0.0428492 0.503823 -0.371608 +-0.26901 0.504761 0.0291192 +0.494291 0.04919 -0.107099 +0.453579 -0.489245 0.397641 +0.499757 0.0912491 -0.0735701 +0.493732 0.073061 -0.118242 +0.301246 -0.508483 0.296837 +-0.107584 0.463029 -0.486868 +0.249963 0.484071 0.470791 +-0.109252 -0.490362 -0.0792936 +-0.105508 -0.505935 -0.0496491 +0.0793522 -0.225447 0.508364 +0.0374875 -0.269436 0.502337 +-0.495506 0.120499 0.429744 +0.470968 0.485676 0.227639 +0.0418343 -0.230554 0.508723 +0.502247 0.34574 0.390083 +0.267842 -0.517562 0.337641 +-0.46347 0.472665 0.0224177 +0.345738 -0.282737 0.500249 +0.375804 -0.282913 0.508665 +0.360235 -0.310605 0.518128 +-0.493748 -0.101866 -0.0668809 +-0.491049 -0.183483 -0.0785849 +-0.494419 -0.105931 -0.0981158 +0.452781 0.283591 -0.491265 +0.462797 0.478538 -0.267847 +-0.107457 0.411209 -0.493101 +-0.088168 0.446045 -0.489768 +-0.501978 -0.0705053 0.190584 +-0.49279 -0.0996162 0.185414 +-0.5033 -0.0806482 0.163588 +0.129683 -0.499466 -0.366656 +0.171719 -0.50107 -0.401302 +0.126792 -0.496548 -0.39708 +-0.435822 -0.191987 0.499917 +-0.495881 -0.273258 -0.451059 +-0.223501 -0.0416961 0.50374 +-0.257964 0.00410542 0.49688 +-0.231962 0.021725 0.50024 +-0.429961 -0.500714 0.119293 +0.490193 -0.130922 -0.15417 +-0.459731 0.0197055 -0.481802 +0.493337 -0.0972551 -0.205826 +0.501245 0.417815 0.407652 +0.49292 -0.130232 -0.197627 +0.275252 -0.493728 0.0783176 +0.219774 -0.492014 0.46175 +0.305049 -0.496966 0.121568 +0.461803 -0.47599 -0.0814908 +0.11835 0.107896 -0.506346 +0.131911 0.13627 -0.503265 +-0.322428 0.496931 0.0368953 +0.404189 -0.429714 0.490115 +0.0166851 -0.493437 -0.455651 +0.121508 0.502909 -0.346404 +0.502654 -0.0500084 0.409947 +-0.486743 -0.32252 -0.452268 +0.499374 0.00994118 0.410145 +-0.0941307 0.511503 -0.34596 +-0.397574 -0.512278 -0.358346 +-0.494852 0.444806 -0.378503 +-0.274314 -0.465514 -0.481523 +0.114982 0.508885 -0.205736 +-0.251055 -0.482865 -0.478484 +0.0899538 0.0522514 -0.50215 +-0.502868 -0.1544 0.176463 +-0.0310074 -0.500677 0.198997 +-0.495336 -0.118004 0.208671 +-0.509159 -0.137256 0.230841 +-0.302689 0.295923 -0.497974 +-0.385988 0.291927 -0.517628 +-0.052296 -0.399518 0.512328 +-0.37074 0.238824 -0.505066 +0.194431 -0.448507 -0.484459 +0.188475 -0.432562 -0.49788 +-0.465898 0.48323 -0.322903 +0.172979 -0.443778 -0.487678 +-0.499282 0.298316 0.188651 +0.50421 0.397611 -0.43357 +-0.502389 -0.343429 0.404654 +-0.135159 0.492848 -0.238134 +-0.0530651 0.502517 -0.312205 +-0.502397 0.274182 0.418732 +-0.489991 0.273888 0.44038 +-0.494318 0.250303 0.429701 +0.00641033 -0.283419 -0.508832 +0.0421212 -0.337028 -0.50853 +-0.0652453 -0.477701 0.466022 +0.0572083 -0.30718 -0.497124 +0.477307 0.269222 0.472258 +0.494595 -0.277421 -0.060959 +-0.284945 -0.0460879 0.507162 +-0.283324 -0.0820176 0.513007 +-0.320591 -0.0633731 0.495685 +0.0350876 0.507769 -0.363251 +-0.506626 0.149865 0.37782 +-0.504133 0.181527 0.426241 +0.257623 0.49412 -0.0129247 +0.208432 0.507512 -0.0126122 +0.32432 -0.508038 0.177339 +0.195554 -0.492685 0.176774 +0.196457 -0.507733 0.228602 +0.213676 -0.503785 0.205404 +-0.0486031 -0.244716 0.501524 +-0.0180673 -0.229662 0.511066 +-0.0207822 -0.265236 0.495216 +0.473112 0.46156 0.240239 +-0.494378 0.223121 -0.131145 +-0.496628 0.173939 -0.158961 +-0.50525 0.232873 -0.158692 +0.476107 -0.370591 0.480057 +-0.323537 0.0938811 -0.503572 +-0.158655 -0.4846 -0.447507 +-0.469366 -0.464715 0.421364 +-0.155111 -0.502007 -0.423466 +0.435968 0.467617 -0.469661 +0.50881 0.184045 0.271305 +-0.488204 -0.0833704 0.448116 +-0.505075 -0.043537 0.42056 +-0.509538 -0.192742 0.0522598 +-0.506438 -0.218257 0.0716077 +-0.0172538 0.102294 -0.505388 +0.474079 -0.479272 0.178373 +-0.505877 -0.198858 0.0206287 +-0.314931 0.281613 0.513741 +-0.138764 -0.494611 -0.173763 +-0.324375 0.306046 0.506197 +-0.36743 0.436404 0.499656 +0.497503 0.156903 -0.152197 +0.495283 0.207235 -0.135571 +0.458234 0.477375 -0.23959 +-0.471414 0.254791 0.481129 +0.491915 0.189281 -0.164287 +0.508471 -0.300817 -0.432991 +0.138674 0.490598 -0.0613472 +0.265614 0.495857 0.210191 +0.189345 -0.491253 -0.245312 +0.178329 -0.492114 -0.215275 +-0.138035 -0.00876061 0.496059 +-0.260831 0.473868 -0.473257 +-0.111091 0.0147091 0.506517 +-0.104596 -0.0206955 0.507332 +-0.333642 -0.376163 0.516715 +-0.497781 -0.352323 0.26129 +-0.515644 -0.373976 0.280673 +-0.505937 -0.379265 0.250538 +-0.262737 -0.492893 -0.443225 +-0.211311 -0.504004 -0.0938338 +0.0671088 -0.147031 0.50491 +0.100184 -0.109505 0.490939 +0.111538 -0.132638 0.502889 +-0.483933 -0.270032 -0.46911 +0.143104 0.5073 -0.221867 +0.16293 0.499478 -0.272484 +0.385863 0.501678 0.180193 +-0.485187 0.204887 -0.472915 +-0.00832723 0.471419 -0.48288 +0.489328 -0.464438 -0.387621 +0.0952086 0.500437 -0.359353 +0.310439 -0.493236 0.426281 +-0.0744919 -0.22581 0.490709 +-0.100983 -0.211993 0.498997 +-0.0761291 -0.193493 0.501975 +-0.494434 -0.254626 -0.0205991 +0.43132 0.493701 -0.26132 +0.00890044 0.507505 -0.312525 +-0.334608 -0.494183 0.434705 +-0.296851 -0.500715 0.409718 +-0.325906 -0.509443 0.417865 +-0.468829 -0.275927 0.482594 +-0.484493 -0.469972 0.210111 +-0.119076 0.0754421 -0.501989 +-0.352635 0.495715 0.445903 +-0.338803 0.486194 0.466915 +-0.135206 0.10004 -0.502133 +-0.251698 0.500454 -0.203413 +-0.149513 0.071648 -0.489433 +-0.489983 -0.0808623 0.106052 +-0.493775 -0.420316 0.374605 +-0.505302 -0.0434077 0.0673205 +-0.491647 -0.0299056 0.118863 +0.120651 -0.00356344 -0.504944 +0.103895 -0.031268 -0.49649 +0.265115 -0.508694 -0.431631 +0.283604 -0.497106 -0.407793 +0.294861 -0.50312 -0.434484 +-0.255529 -0.506953 0.26327 +-0.23015 -0.506898 0.239678 +-0.262329 -0.501434 0.230154 +0.498473 -0.450479 0.14119 +0.498053 -0.446308 0.170686 +-0.449341 0.196981 -0.492754 +-0.0947223 0.486433 -0.45126 +-0.299879 -0.374609 0.506645 +-0.265859 -0.481522 0.468361 +-0.322288 -0.346453 0.512403 +-0.267461 -0.365013 0.499189 +-0.435852 0.385247 0.501074 +0.514293 0.372007 -0.0736594 +-0.500661 -0.158515 -0.443235 +-0.49658 -0.180458 -0.427727 +0.443615 0.484042 -0.454591 +-0.136337 -0.493519 0.442369 +-0.101454 -0.500713 0.440791 +-0.477105 0.461731 0.0332551 +-0.302495 0.45087 -0.483252 +0.482729 -0.139093 -0.451338 +-0.203213 0.493802 0.205431 +-0.475181 -0.453438 0.446701 +0.15738 0.00894269 0.494932 +0.512888 -0.106484 0.404305 +0.494105 -0.110306 0.427534 +0.491671 -0.081022 0.417878 +-0.0530274 -0.495903 -0.061012 +-0.0623266 -0.493635 -0.0894508 +-0.0823521 -0.492435 -0.0691827 +0.516468 0.276481 -0.305014 +-0.232859 -0.507437 -0.000988614 +0.512516 0.268995 -0.272209 +0.401756 -0.394648 -0.50283 +-0.33048 -0.290307 0.512904 +-0.502374 -0.265804 0.431602 +-0.51405 -0.274362 0.362047 +-0.206626 -0.490156 -0.0668973 +0.495117 0.39561 -0.0541977 +-0.45107 -0.237645 0.486488 +0.0222643 0.246271 -0.503894 +-0.256695 0.493808 0.223724 +0.0855687 0.238891 -0.492585 +0.0799053 0.273793 -0.503306 +-0.38387 -0.515074 -0.263856 +-0.477366 0.409297 -0.469161 +-0.140327 -0.418194 -0.494946 +-0.276702 0.420777 0.499244 +-0.410257 -0.499085 -0.275485 +-0.407383 -0.500983 -0.238638 +0.31636 0.503921 -0.408704 +-0.265315 0.0168281 -0.500672 +-0.222675 0.502884 0.234935 +0.288462 0.476073 -0.476467 +0.317622 0.499652 -0.441679 +0.434332 0.208967 0.498131 +0.509767 0.265244 0.222473 +0.505726 0.253303 0.168066 +0.506879 0.219964 0.177248 +0.126784 0.187374 -0.489713 +0.457352 -0.344269 -0.500748 +0.286916 -0.510743 -0.23855 +0.312276 -0.511803 -0.194201 +-0.150724 0.191575 -0.504239 +-0.148252 0.16286 -0.493246 +-0.126672 0.179877 -0.500796 +-0.237125 -0.482991 0.460922 +0.348444 -0.304043 -0.499599 +0.343913 -0.336905 -0.511651 +0.372471 -0.321965 -0.508257 +0.341632 0.501805 0.131543 +0.358312 0.500313 0.185519 +0.296326 0.401134 0.507188 +-0.451734 0.0499319 0.491272 +-0.49646 0.0603437 -0.454638 +-0.367286 -0.410215 0.504329 +-0.507192 0.0888903 0.118222 +-0.489668 0.0635395 0.107452 +0.389311 0.513356 -0.325024 +-0.492451 0.0595827 0.138377 +-0.497421 0.0729101 0.173099 +0.232312 -0.219064 0.495824 +-0.50145 0.0393786 0.169936 +-0.0319334 0.509245 0.063766 +-0.16001 -0.499348 0.450513 +-0.106433 -0.180715 0.495413 +0.226325 -0.503429 -0.277658 +-0.448388 0.495373 -0.129997 +0.239857 -0.493275 -0.258383 +0.253872 -0.501186 -0.277238 +0.105386 -0.159515 -0.503188 +0.13797 -0.166506 -0.506985 +-0.496995 0.055697 0.375544 +0.147841 -0.139224 -0.500255 +-0.251384 -0.50379 0.10127 +-0.217228 -0.497222 0.118221 +0.468945 -0.455326 0.457574 +-0.21653 -0.490397 0.0829824 +-0.437216 0.491292 -0.078863 +-0.0588093 -0.504815 0.211181 +-0.0658234 -0.499769 0.240123 +-0.0358791 -0.505442 0.230483 +0.496511 0.456371 0.430346 +0.223137 -0.480887 -0.48021 +-0.108199 -0.492642 0.149318 +-0.135611 -0.50436 0.162573 +-0.111729 -0.49613 0.183465 +0.116328 0.492379 0.23716 +0.117129 0.505307 -0.00745814 +-0.477029 0.407527 0.458879 +-0.41805 0.182454 0.496054 +-0.115928 -0.492822 -0.164909 +-0.139519 -0.495878 -0.149194 +0.217326 0.484018 0.469169 +-0.113528 -0.492279 -0.136537 +-0.480095 0.457192 0.230144 +0.497025 0.238245 -0.393237 +0.505859 0.266172 -0.413921 +-0.39358 0.471328 -0.486745 +0.145385 0.494261 0.24926 +-0.00247658 0.509767 0.0731087 +0.125136 -0.340715 0.505427 +0.120337 -0.286901 -0.493433 +0.0668538 0.497099 -0.313641 +0.496631 0.346594 0.145514 +0.16123 -0.50214 -0.150067 +-0.106676 -0.452898 -0.49019 +0.499075 0.244859 0.278822 +0.21742 -0.503196 -0.168282 +0.163887 -0.506839 -0.183787 +0.42084 0.488799 -0.468192 +0.0977298 0.495593 -0.297966 +-0.0919491 0.501675 -0.194672 +0.507756 0.142501 -0.0421664 +0.319576 -0.418784 0.494865 +-0.0999795 0.506163 -0.227779 +-0.258698 -0.495968 0.450234 +0.494274 -0.437364 0.0458255 +0.0561235 0.507173 -0.214881 +-0.134606 -0.501892 0.285081 +-0.278446 -0.499262 0.431286 +0.497774 -0.239985 0.402431 +0.451764 0.49433 0.0258338 +-0.505998 0.316259 -0.437348 +0.512291 -0.295695 0.427852 +0.507361 -0.242882 0.43039 +-0.495906 -0.351352 -0.118411 +-0.496222 -0.35891 -0.0668879 +0.0135765 0.00123236 0.499463 +0.0450397 -0.00670156 0.506908 +0.0224819 -0.0318545 0.493704 +-0.476791 -0.469936 0.1129 +-0.505358 -0.334571 -0.279444 +-0.499498 0.382187 0.171635 +-0.0583972 0.329501 0.507255 +-0.504565 -0.310988 -0.22604 +0.467144 -0.124105 0.491076 +-0.49887 -0.334732 -0.237762 +0.46017 0.489429 0.129103 +-0.503037 0.260753 -0.019465 +-0.491047 0.236878 -0.0184283 +-0.503587 0.241654 -0.0407792 +-0.319522 -0.507706 0.0359991 +0.485959 0.260557 -0.465768 +-0.324062 -0.505403 0.0684861 +-0.29568 -0.507377 0.0535933 +0.440883 0.493102 -0.0481467 +0.488485 -0.163286 -0.439287 +0.0956968 0.496713 -0.330188 +-0.105528 -0.498944 0.380812 +0.486338 0.370605 -0.471069 +-0.126981 -0.502621 0.413393 +-0.16919 -0.502118 0.380083 +-0.182401 -0.49833 0.419227 +-0.494715 0.0472692 0.42891 +-0.139774 -0.499821 0.381447 +0.188396 0.289138 0.496614 +0.167925 0.262203 0.500821 +-0.489214 -0.184334 -0.446642 +0.506229 -0.0201012 0.398 +0.501241 0.013102 0.360427 +0.505226 -0.0478882 0.38018 +0.443217 0.156186 0.483977 +0.123046 -0.421083 0.503828 +-0.324272 -0.511959 0.271323 +0.456546 0.253526 -0.494162 +-0.322023 -0.498463 0.23889 +-0.0775018 -0.501499 0.103431 +0.105636 0.506212 -0.0551889 +-0.373052 -0.511645 -0.206171 +-0.494358 0.102573 0.404709 +0.49704 0.45446 -0.146637 +-0.232261 -0.498565 -0.0734952 +0.507305 -0.193262 0.236822 +0.500592 -0.175402 0.259975 +-0.452567 0.491011 0.454745 +-0.436705 -0.134187 0.494929 +0.180638 0.112662 -0.505729 +0.287198 0.0697886 0.495608 +0.149365 0.110101 -0.500897 +0.167132 0.0831409 -0.49073 +0.341481 -0.0453546 -0.511761 +-0.0848043 -0.445985 0.485397 +-0.506549 0.317061 0.273925 +0.489384 -0.44201 -0.370969 +-0.511732 0.342822 0.292334 +-0.512947 0.313455 0.306252 +0.495686 0.186616 0.0767653 +0.489998 0.159616 0.0740793 +-0.472289 0.486672 0.278792 +-0.393078 0.49124 0.473351 +0.046942 0.0767734 -0.496363 +0.0330651 0.0542308 -0.500013 +-0.49272 0.0344136 0.399388 +0.060482 0.0524367 -0.509592 +-0.489355 -0.225798 -0.444682 +0.503604 -0.190256 0.434419 +0.49682 -0.159712 0.397203 +0.502008 -0.218223 0.445044 +0.506806 -0.320597 0.167818 +-0.225288 0.104945 -0.507603 +0.514774 -0.332082 0.139511 +0.503901 -0.353488 0.165905 +-0.480225 -0.459725 -0.162473 +-0.402447 0.493895 -0.453922 +0.495508 0.460364 -0.121645 +0.498533 0.401296 -0.0835429 +0.369308 0.501891 -0.226765 +-0.435641 0.502295 -0.17614 +0.461496 0.471277 0.459484 +0.114965 0.161428 -0.506902 +0.100488 0.185574 -0.504574 +0.0315548 -0.496549 0.414103 +-0.442856 -0.485352 -0.392193 +0.498778 0.178966 -0.347197 +0.502634 0.144355 -0.363959 +-0.509329 -0.290423 0.400276 +-0.459378 -0.493028 -0.151359 +-0.228214 -0.504227 -0.0295546 +-0.495997 -0.448445 -0.177834 +-0.246761 -0.508137 -0.0492208 +-0.25543 -0.504193 -0.0202608 +0.494015 0.411981 0.29238 +0.505747 0.379778 0.336123 +0.301991 -0.259723 -0.509321 +0.293619 -0.292613 -0.497285 +0.324737 -0.282661 -0.509525 +-0.069219 -0.423808 0.497288 +0.118294 -0.497195 -0.332615 +-0.50482 0.289197 0.255924 +-0.492888 0.227278 0.21993 +-0.493353 0.261155 0.197742 +0.209625 -0.0472181 0.498162 +0.499086 0.044168 -0.189113 +0.169455 -0.0601851 0.495606 +0.342167 -0.467588 -0.475573 +0.381813 0.131326 0.501121 +0.16356 -0.0382311 0.500301 +-0.486825 0.457821 -0.244536 +-0.03737 -0.42344 0.489464 +-0.512725 -0.394456 -0.146483 +0.478313 0.468807 0.0931504 +-0.393164 0.311235 0.511745 +0.415764 0.494351 0.0474003 +-0.341273 0.285853 0.507322 +-0.396797 0.273264 0.514098 +0.259129 0.24597 0.503313 +-0.361111 0.499886 0.367668 +-0.416339 0.506106 0.401436 +-0.385186 0.499232 0.341873 +-0.358262 0.00313083 -0.511989 +-0.392294 0.00142814 -0.507838 +-0.38549 -0.0570257 -0.510297 +-0.354287 -0.515077 -0.254632 +-0.323754 -0.497698 -0.244206 +0.228966 0.506922 -0.363262 +0.211925 0.513304 -0.389555 +0.263701 0.327082 0.510241 +0.294191 0.318746 0.517245 +-0.206953 0.46848 0.469928 +0.0198665 -0.482243 0.452399 +0.379847 -0.0192163 0.513684 +-0.484951 -0.440447 -0.151271 +-0.476984 0.178526 -0.474472 +-0.476203 0.469358 0.253206 +-0.49271 0.439231 0.233581 +-0.109082 -0.506395 0.29386 +-0.08069 -0.507584 0.272822 +0.198099 -0.364905 0.51232 +0.256089 -0.40499 0.497121 +0.192411 -0.396238 0.509116 +0.512841 -0.363183 0.280436 +0.510154 -0.362587 0.313879 +0.508942 -0.301169 0.271972 +0.0772938 -0.428673 0.50711 +0.431227 0.299549 -0.491423 +0.23511 0.464798 -0.484059 +-0.0741817 -0.489599 -0.444734 +0.404042 -0.0318846 0.496321 +0.40278 0.000605222 0.500766 +-0.507862 -0.379992 -0.400054 +0.0844805 0.160779 -0.489554 +-0.468676 0.226106 -0.47479 +0.499897 -0.218652 -0.411477 +0.0487447 0.162381 -0.507147 +0.0696901 0.132052 -0.492269 +-0.277776 -0.310289 0.515204 +-0.134457 0.504318 0.113556 +0.429606 0.504187 -0.024671 +0.507863 0.260411 0.0201879 +0.490538 -0.459509 0.252366 +-0.220625 0.390508 0.51124 +0.380993 -0.46913 0.49073 +-0.249135 0.40635 0.50976 +-0.193172 0.40634 0.498559 +-0.0859395 -0.125244 0.4931 +0.476778 -0.278636 0.466783 +-0.0804024 -0.159667 0.508402 +-0.112464 -0.147181 0.508373 +0.370963 0.205154 0.515852 +0.392734 0.208808 0.498157 +0.389843 0.186573 0.510527 +0.507351 -0.261242 0.181163 +0.493206 0.0307503 -0.452048 +0.47511 -0.397119 0.472926 +0.502892 -0.211144 0.142628 +-0.413855 -0.508457 0.377759 +-0.498348 -0.453166 -0.399272 +0.494773 0.0987876 -0.316638 +0.475966 -0.268376 0.488487 +0.500262 0.150335 -0.302468 +-0.221294 0.467769 -0.48574 +0.513644 0.14658 -0.330823 +-0.118884 0.352676 0.503376 +0.501497 -0.300348 -0.456506 +-0.072114 0.388392 0.511479 +-0.0466216 0.379151 0.507389 +0.505442 -0.189915 -0.429052 +0.471082 0.061653 -0.47815 +-0.0662154 0.360508 0.502631 +0.216777 0.508681 0.384762 +-0.0808939 0.462011 0.483488 +0.49772 -0.301498 -0.0494067 +0.50504 -0.363291 -0.0290991 +0.14122 0.499205 -0.360224 +0.434545 -0.495494 0.41009 +0.178761 0.508292 -0.386745 +-0.421123 0.496592 0.0446529 +0.442032 -0.48723 0.435849 +0.236144 -0.0996562 -0.502514 +-0.462232 -0.371288 -0.483724 +0.126771 -0.0697835 0.500218 +-0.496419 -0.0756895 -0.085926 +0.26084 0.450754 -0.500961 +-0.173784 0.497838 0.290266 +0.507833 0.0173317 -0.304893 +0.505023 0.0151851 -0.280774 +0.512768 0.043096 -0.284634 +-0.433356 0.500478 0.000621944 +-0.438273 0.499978 0.0269036 +0.512731 -0.398987 -0.103097 +-0.505002 -0.131505 0.440065 +-0.266695 -0.280036 0.500836 +-0.450546 -0.490657 0.44965 +-0.431475 0.496657 0.0684032 +0.263346 0.459491 0.478756 +-0.420552 0.505285 0.0902231 +0.479511 0.316709 0.484229 +-0.443761 0.481247 0.431782 +-0.120655 0.472331 0.473965 +-0.000528688 -0.49631 -0.138151 +-0.0472578 -0.505025 -0.112528 +-0.0518129 0.404745 0.507125 +-0.0178907 -0.499884 -0.112637 +-0.229141 0.497174 -0.229617 +-0.216534 0.507477 -0.196898 +0.506834 0.0646655 0.433676 +0.497662 0.0787327 0.450636 +0.4968 -0.3403 -0.094073 +0.292585 -0.448811 0.491743 +-0.472431 -0.394435 -0.480227 +0.499684 -0.295453 -0.0775694 +0.512803 -0.319859 -0.119734 +-0.0557071 0.505412 0.0854151 +0.141233 -0.115361 -0.49465 +0.113948 -0.111123 -0.492395 +-0.250148 0.506502 -0.296899 +-0.215489 0.512752 -0.287136 +0.496478 -0.187778 -0.398876 +-0.299492 -0.28479 0.499867 +0.504529 -0.187072 0.408618 +-0.240746 0.496393 -0.263348 +0.379446 0.49868 -0.271578 +0.364204 0.514363 -0.301442 +0.398889 0.514954 -0.295493 +-0.181169 0.503346 -0.279373 +-0.145646 0.492969 -0.272351 +-0.281819 0.50772 0.263554 +-0.285469 0.5053 0.288973 +-0.307595 0.498272 0.275206 +0.0226332 0.514165 0.348873 +0.127358 0.509462 0.299974 +-0.131331 -0.0436872 0.506927 +0.314881 -0.507484 -0.224671 +0.363665 -0.501913 -0.183343 +0.347219 -0.498863 -0.243019 +0.476769 0.0189672 0.469313 +0.498313 -0.268942 -0.00394525 +0.11279 0.204674 -0.508193 +-0.480385 -0.468861 -0.292181 +-0.0259378 0.502716 0.185388 +0.346913 -0.191562 -0.502598 +0.416089 -0.192558 -0.506464 +0.377545 -0.142955 -0.504938 +0.135763 -0.0325904 -0.493093 +-0.484392 0.169816 0.443969 +-0.252281 -0.0324758 -0.505894 +-0.330588 0.508657 0.00450019 +-0.229229 -0.0534331 -0.509546 +-0.133048 -0.457057 -0.49672 +-0.0635098 0.50542 0.0536984 +-0.0961284 0.499066 0.042041 +-0.0720625 0.508678 -0.00366331 +0.485605 -0.47264 -0.0930427 +-0.284378 0.503523 -0.308489 +-0.502317 0.442464 0.180829 +-0.312622 0.505661 -0.286824 +-0.317019 0.505127 -0.32214 +-0.0587177 0.102615 0.500511 +0.51205 -0.370633 -0.0970319 +-0.0236417 0.0814536 0.497232 +-0.481445 0.464232 -0.159082 +-0.0545433 0.0613328 0.501962 +0.430968 -0.278725 0.494842 +-0.182206 -0.123169 -0.491598 +0.494099 -0.273589 -0.465113 +0.441384 -0.310857 0.494894 +0.431931 -0.244969 0.498773 +0.434885 -0.489988 0.209507 +0.354314 0.500992 -0.131495 +0.435122 -0.486089 0.179765 +0.414805 -0.507964 0.193645 +0.428591 0.502965 0.333473 +-0.175776 -0.491238 0.463274 +-0.220829 0.442259 0.494787 +-0.219384 0.511932 0.312081 +-0.23674 0.511209 0.29636 +-0.262369 -0.184923 -0.494412 +-0.106103 0.494632 0.448138 +-0.177219 -0.349371 0.510651 +-0.322035 -0.198576 0.515038 +-0.291377 -0.213357 0.500579 +-0.319372 -0.23046 0.500895 +-0.0725563 0.509937 -0.251109 +-0.482005 0.453847 0.412518 +-0.0337397 0.500767 -0.239395 +-0.492079 0.454947 -0.110253 +0.00414267 -0.125957 -0.500095 +0.0340385 -0.118168 -0.504942 +0.496087 -0.432703 -0.0667394 +0.0507356 -0.496728 -0.0642826 +-0.29606 0.50193 -0.370911 +-0.0374684 -0.48129 0.478716 +0.389253 0.513323 -0.0541468 +0.0720496 -0.0306182 -0.497857 +-0.508742 0.141498 -0.430685 +-0.49821 0.435197 -0.442875 +0.383133 0.509543 0.00237361 +-0.477114 0.470392 0.305864 +0.238287 -0.497796 0.316505 +0.454803 -0.255999 -0.477985 +0.270586 -0.505219 0.260341 +-0.142254 0.507263 -0.427815 +0.369739 -0.478759 -0.479493 +-0.0891936 0.498535 -0.406012 +0.50043 -0.295866 -0.191112 +0.477895 -0.020776 -0.471617 +-0.259544 -0.0630165 -0.494252 +0.107855 -0.0161621 0.498782 +-0.472167 0.127944 0.466772 +0.121458 0.509839 0.268157 +0.479626 -0.0656583 -0.465306 +-0.502273 0.134461 0.350949 +0.0676774 0.495035 0.277344 +0.48035 0.139198 -0.464642 +-0.478316 0.470008 0.107878 +-0.311025 0.506529 0.149591 +-0.340844 0.498722 0.15483 +-0.496869 0.23525 -0.396223 +-0.323186 0.502422 0.129625 +-0.283074 0.496488 0.446568 +-0.277697 0.500939 0.106917 +-0.0355965 0.500124 0.151039 +-0.0457947 0.498462 0.11754 +-0.0455876 0.499828 -0.275425 +-0.314247 0.512936 0.205014 +-0.505817 -0.233364 -0.354286 +-0.283629 0.498178 0.213801 +0.436388 -0.502114 -0.377176 +-0.35039 0.514858 -0.0878746 +-0.409283 0.499846 -0.00775609 +-0.51069 -0.207865 -0.334701 +-0.208397 0.502937 0.290985 +0.459823 0.136877 0.477842 +0.251065 0.274466 0.503569 +-0.48583 0.461601 -0.0797285 +0.499925 -0.432829 0.0168095 +0.313272 -0.346076 0.499421 +0.499259 -0.323897 0.461505 +-0.419815 0.483627 -0.426746 +-0.266379 0.494376 0.421777 +-0.27216 0.508686 -0.176072 +0.215839 0.497597 0.424558 +0.14879 0.496526 0.427586 +0.226851 0.50798 0.05589 +0.191681 0.506354 0.118598 +0.168961 0.489753 0.059047 +0.500901 -0.21386 0.0897638 +-0.170862 0.496487 -0.334819 +0.450036 -0.483871 -0.0447375 +-0.151613 0.514112 -0.356431 +-0.505561 -0.0144658 -0.295574 +-0.50108 -0.00106607 -0.240848 +-0.379731 0.50395 -0.0941374 +0.120245 -0.459912 -0.471824 +-0.509271 -0.0274131 -0.261915 +-0.0134106 0.498136 0.223047 +0.357574 0.507675 0.387412 +-0.0461921 0.493697 0.245682 +-0.136751 0.495898 0.326879 +-0.165723 0.50349 0.321585 +-0.0147786 0.501173 0.261231 +-0.463707 -0.483553 -0.450454 +0.266396 0.325251 -0.515812 +0.155469 0.464488 -0.490024 +0.501758 -0.321416 0.412925 +-0.502563 0.119551 0.128324 +-0.49567 0.150885 0.139088 +-0.494349 0.125833 0.159159 +-0.0828414 0.500525 -0.0792144 +-0.473305 0.472337 0.380841 +0.0816659 -0.49717 0.209524 +-0.144856 0.495724 0.0887165 +0.0968155 0.506865 -0.0248881 +-0.00619353 0.506818 0.416667 +-0.0551665 0.494453 0.42718 +-0.400416 0.510471 -0.304226 +-0.343484 0.515537 -0.268083 +-0.400769 0.510392 -0.272387 +0.505171 -0.422307 0.288798 +-0.495804 0.462738 0.384976 +-0.482824 0.468677 -0.273549 +-0.492731 -0.444485 0.133612 +-0.0581982 0.489968 -0.450096 +-0.458225 0.477204 -0.23154 +0.304153 0.496284 0.434021 +0.504862 -0.261662 0.356546 +0.0969318 0.504926 -0.386449 +-0.511903 -0.364742 -0.424344 +0.508259 -0.293466 0.370338 +0.508993 -0.265479 0.387192 +0.323602 -0.17413 -0.501101 +0.494764 0.456627 -0.228963 +0.325674 -0.502583 0.214059 +0.29465 -0.499551 0.199162 +0.292327 -0.50773 0.233675 +0.204743 0.501768 -0.160115 +0.183182 0.508478 -0.0995956 +0.306555 -0.513129 0.0917675 +0.310873 0.10844 -0.511073 +0.239725 0.48203 -0.465804 +0.389009 -0.500227 0.0718229 +0.396085 -0.497636 0.140561 +0.404039 -0.508579 0.105861 +-0.295738 -0.179837 0.498243 +0.298773 -0.18449 -0.494093 +0.472984 0.462491 0.212922 +0.299517 -0.155253 -0.511068 +0.26425 0.474702 -0.48528 +0.0618967 0.505658 -0.424035 +-0.121188 0.442437 0.498325 +0.272073 0.489549 -0.468733 +0.0743051 0.503235 -0.398539 +-0.347782 -0.243399 0.497234 +0.051627 0.495536 -0.183737 +-0.100313 0.478367 -0.474037 +0.0831389 0.498058 -0.19461 +0.290759 0.511261 -0.364659 +0.0465251 0.413174 0.492786 +0.316285 0.50525 -0.377645 +-0.0500084 0.260465 0.493367 +0.508216 0.356007 0.22157 +0.509289 0.384606 0.219831 +0.475008 0.487014 0.177006 +0.514415 0.369087 0.191808 +0.419749 0.46441 0.489781 +-0.471564 -0.0961781 0.479388 +0.14635 -0.500468 -0.00317001 +0.167692 -0.507975 0.0354709 +0.17458 -0.501397 0.00921301 +-0.499058 0.00321982 0.22574 +-0.498723 0.0214192 0.198344 +-0.473023 -0.0689793 0.486526 +-0.503474 0.0363144 0.228425 +0.494842 -0.429463 -0.0398118 +-0.474132 -0.464604 0.283374 +-0.00531012 0.40834 0.507697 +-0.482224 -0.399546 0.459444 +-0.19422 0.492492 -0.222076 +0.0672268 -0.475029 -0.473329 +-0.170278 0.494268 -0.246762 +0.0975493 0.507226 0.288866 +-0.467642 -0.476518 -0.0894939 +0.00165972 0.505769 0.386625 +-0.411322 0.48023 -0.47265 +0.4538 0.397431 0.49471 +0.493479 -0.22868 -0.0785207 +0.471509 -0.140828 -0.466097 +0.497891 -0.189128 -0.0420349 +-0.0869201 0.43847 0.489607 +0.49989 -0.197808 -0.0699516 +-0.482201 -0.2107 0.46293 +-0.187504 -0.505012 0.100069 +-0.306783 0.499021 -0.180943 +-0.352751 0.505783 -0.20237 +-0.486081 0.4474 -0.45456 +-0.322845 0.499685 -0.209347 +0.219886 0.0585843 -0.491651 +0.185566 0.0554411 -0.495171 +0.488628 -0.425485 0.418604 +0.204877 0.0260789 -0.503274 +0.414152 0.0298737 0.504744 +0.0846868 0.500619 0.221495 +0.0381499 0.502571 0.239287 +-0.494789 0.436681 0.377187 +-0.513333 0.396678 0.356728 +0.509826 -0.184197 -0.370497 +0.492952 -0.126348 -0.402073 +-0.264613 0.498066 0.306073 +-0.284991 -0.372715 -0.513081 +0.0498265 0.382213 0.507223 +-0.0507101 0.493947 -0.0754461 +-0.400545 -0.505187 -0.388051 +0.181558 0.424048 -0.490849 +0.492961 0.320168 0.462482 +-0.433998 0.488942 0.374429 +0.168288 0.449505 -0.499511 +0.152307 0.430187 -0.507041 +-0.210623 0.50407 -0.370904 +-0.2132 0.495202 -0.042182 +-0.193508 0.491855 -0.0643518 +0.387105 0.513373 0.233958 +0.0910731 -0.497657 0.444884 +-0.177353 -0.508037 0.223873 +-0.244726 0.492767 -0.0508673 +-0.274217 0.495783 -0.0644041 +0.197818 0.187643 -0.501756 +-0.194752 -0.0121383 -0.494579 +-0.200485 -0.041864 -0.494369 +-0.173541 -0.0303879 -0.507471 +0.504681 0.330279 -0.285157 +0.516672 0.346297 -0.30699 +0.508348 0.300208 -0.281217 +0.0486167 0.506595 0.045062 +0.473995 -0.295268 0.479183 +-0.0886939 0.507101 0.0753353 +-0.450097 0.493606 0.121347 +0.155322 -0.494063 -0.241736 +0.487026 0.469586 -0.318196 +-0.400274 0.448888 -0.495233 +-0.509436 0.299316 0.433385 +-0.188691 0.499232 0.180795 +-0.147221 0.507636 -0.0840248 +-0.161436 0.49744 -0.104715 +-0.133593 0.500388 -0.114054 +-0.380639 0.509915 -0.129163 +-0.405515 0.506701 -0.146098 +-0.480314 0.130409 -0.467457 +-0.381273 0.508835 -0.160248 +0.433575 -0.487225 -0.193432 +-0.226463 -0.211941 0.505375 +0.448578 -0.497909 -0.217542 +0.427239 -0.508068 -0.217349 +0.398961 0.499305 -0.183829 +-0.150328 0.503076 0.226217 +-0.497481 -0.422723 0.453835 +0.233943 0.502186 0.18921 +-0.286529 0.498735 0.0656778 +-0.000276663 -0.228299 -0.494577 +-0.29167 0.508572 0.0444736 +-0.393959 -0.453521 -0.484103 +0.177839 0.500051 -0.4295 +0.504884 -0.399419 0.126955 +-0.470725 0.12541 -0.485811 +0.062492 -0.290902 0.500247 +-0.40163 0.494428 0.138857 +0.501049 -0.423465 0.151076 +0.512647 -0.392153 0.165251 +0.499653 0.37424 -0.192118 +0.50138 0.41567 -0.168999 +0.504724 0.413973 -0.23183 +-0.151265 0.492732 -0.0322172 +-0.132991 0.509036 -0.056764 +0.00648834 -0.198639 -0.502076 +-0.0864805 0.501433 -0.0257443 +-0.0747087 -0.126298 -0.500562 +0.0579573 -0.197077 -0.496478 +-0.202358 0.50106 -0.341935 +0.29877 -0.435212 0.510037 +-0.0796571 0.498316 0.461124 +-0.484485 0.109224 0.451572 +0.316787 0.507612 -0.195092 +0.268407 0.507186 -0.193496 +-0.234778 0.499153 0.385861 +0.129709 -0.437857 0.4855 +-0.245823 0.504973 0.354885 +0.202246 0.493592 -0.234855 +0.42667 0.499526 0.171174 +0.167859 0.5042 -0.242225 +-0.139227 0.501077 -0.330055 +-0.119336 0.499586 -0.300825 +-0.449376 -0.341266 0.501086 +-0.423062 -0.490629 -0.459527 +0.0223742 0.507329 -0.172499 +0.0186611 0.500053 -0.145736 +-0.00341297 0.492417 -0.160775 +0.239202 0.512287 -0.240732 +0.281023 0.497945 -0.244224 +0.211969 -0.275527 -0.495168 +0.258287 0.496509 -0.215383 +-0.0106573 -0.0701124 -0.502625 +0.216115 0.506137 -0.186454 +0.201108 0.497463 -0.206183 +0.502295 0.188194 -0.0630382 +0.345769 0.502841 -0.181251 +0.344582 0.515619 -0.240058 +0.45262 0.437233 -0.477833 +0.373825 0.508557 -0.168277 +-0.500092 0.313036 -0.266376 +-0.497605 0.150068 0.322332 +-0.505685 0.106951 0.271954 +-0.454273 -0.115441 0.485464 +-0.368623 0.511149 0.173701 +-0.396439 0.501776 0.166203 +0.216579 0.506935 0.327058 +-0.455219 -0.086582 0.49467 +0.429767 0.504945 0.0248138 +-0.508502 -0.363974 -0.146494 +0.349229 0.502222 -0.00575517 +0.023851 0.498765 0.0839424 +0.317769 0.512821 -0.0105405 +-0.314609 0.509872 0.402869 +-0.367354 0.497244 0.423258 +-0.326428 0.513598 0.377704 +-0.149887 -0.501239 0.230516 +-0.161055 -0.508189 0.279938 +-0.00904182 -0.315621 -0.512245 +-0.371867 -0.0851604 0.505785 +-0.142002 -0.509966 0.257763 +0.164431 -0.496083 0.370107 +-0.510358 0.334021 -0.240784 +0.181863 -0.50107 0.424923 +-0.272259 0.512921 -0.391299 +-0.283312 0.494015 -0.416239 +0.494092 0.174393 -0.222315 +-0.0781058 0.41233 0.496173 +-0.0333259 0.444622 0.505683 +0.480311 0.404055 0.464613 +-0.516433 0.324153 -0.293641 +0.483993 0.169875 0.442265 +-0.247144 0.502713 0.0415646 +-0.390472 -0.470789 0.482021 +-0.177702 0.50075 0.0881956 +0.0888159 -0.00280503 -0.49702 +0.0741413 0.0253929 -0.489938 +0.0568589 -0.00161824 -0.492147 +0.30477 0.373764 -0.50191 +-0.00131753 -0.0301743 -0.506047 +-0.0188829 0.508574 -0.295851 +0.502128 0.19193 -0.243337 +0.134251 0.406636 -0.497154 +0.0786673 0.508793 0.347244 +0.0461753 0.498821 0.330305 +0.0727298 0.503984 0.310326 +0.484872 0.461369 0.406946 +-0.489567 0.463912 0.182901 +-0.290199 0.456394 0.486746 +0.499328 -0.423253 -0.384252 +0.373214 -0.499871 -0.423039 +-0.301086 0.503475 0.339361 +-0.471353 -0.12358 0.472425 +-0.351892 0.518234 -0.373259 +-0.329752 0.515172 0.349841 +0.433069 -0.493386 -0.345453 +0.0825042 0.489752 -0.0792936 +0.0487589 0.489959 -0.0730119 +0.0601612 0.496845 -0.10348 +0.0888619 0.510158 -0.225714 +-0.452617 0.485389 -0.103698 +0.0999911 0.497142 -0.260379 +0.0956706 0.0121464 0.492745 +0.0850301 0.0400394 0.508907 +0.469183 0.194582 -0.48903 +0.126172 0.00884089 0.503862 +0.309144 0.501553 0.407104 +0.317874 0.51722 0.36312 +0.328184 0.514878 0.385866 +0.492342 0.127763 -0.449218 +0.111057 0.503097 0.0364618 +0.326618 0.505731 0.0866975 +-0.485881 0.437288 -0.192706 +0.359172 0.513505 0.0818785 +0.174142 0.498001 0.261197 +0.201316 0.499042 0.275314 +0.0389555 0.114695 0.498301 +-0.507282 0.418023 -0.380515 +0.144719 0.164836 -0.489771 +0.177462 0.170805 -0.503847 +0.154318 0.193913 -0.491061 +0.491823 -0.442218 -0.399033 +0.26408 -0.151881 0.510704 +0.277315 -0.0953218 0.501245 +0.179375 0.321299 0.500593 +0.171151 0.35261 0.511103 +-0.320754 -0.507223 -0.0844207 +0.20224 0.343772 0.50198 +0.506125 0.0142574 0.207659 +0.491861 -0.00897782 0.253579 +0.496375 0.0404713 0.220802 +0.257596 -0.175181 -0.494945 +0.474431 0.246312 0.468585 +0.25461 -0.234034 -0.501253 +-0.478533 -0.103742 0.458471 +0.296603 0.497454 0.192017 +0.39872 0.412511 0.493337 +0.0693623 0.100289 0.499132 +0.351861 0.397008 0.498475 +0.270001 -0.214903 -0.511756 +0.369895 0.421293 0.511844 +-0.331942 0.510302 0.26107 +0.500942 0.0110938 0.0725405 +-0.327593 0.496189 0.233743 +-0.340278 0.387426 0.509365 +-0.437755 0.133489 0.505614 +-0.465766 -0.352643 0.479814 +-0.408553 0.148042 0.494524 +0.509783 -0.292879 0.305441 +0.0396002 0.499291 0.264412 +-0.0203519 0.510958 0.321123 +-0.507803 -0.310162 -0.0867917 +-0.508741 -0.331401 -0.141954 +0.474949 0.432887 -0.481805 +-0.449716 0.482951 -0.389885 +-0.415643 0.512292 -0.378352 +-0.505341 -0.299899 -0.133894 +-0.037239 0.505537 -0.0473635 +-0.49396 0.383576 -0.431744 +-0.0559349 0.497433 -0.0237252 +-0.511118 0.320668 -0.211376 +0.193161 0.504464 -0.412136 +-0.0967064 -0.237351 0.502624 +-0.131609 0.490767 0.164569 +-0.179469 0.489356 0.158694 +-0.194325 0.504438 -0.137432 +-0.203546 0.494696 -0.0907808 +0.413377 0.496893 0.274452 +-0.442826 0.187722 0.49006 +-0.468019 -0.474189 0.223467 +-0.449984 -0.39601 0.484024 +0.205955 -0.0930222 0.494068 +-0.401898 -0.482743 -0.480052 +0.253399 -0.123534 0.505 +0.220241 -0.121521 0.495267 +0.440263 0.493133 -0.43071 +-0.0442814 0.50034 -0.126225 +-0.489076 -0.346296 -0.467115 +0.475251 -0.47818 -0.404925 +-0.0636774 0.491967 -0.103589 +0.510411 0.136668 0.24656 +0.500417 0.190109 0.184169 +0.505627 0.124643 0.194228 +0.450659 -0.494089 0.0810743 +0.345416 0.501609 -0.112359 +0.389186 0.513007 -0.0987094 +0.0669644 0.132514 0.501793 +-0.213033 0.507974 -0.116575 +-0.249444 0.505966 -0.0796403 +-0.267453 0.510235 0.0802714 +-0.00230567 0.495283 -0.0973645 +0.0145181 0.50034 -0.0705228 +-0.0187304 0.499024 -0.0722508 +0.354444 0.500393 -0.450695 +-0.457717 -0.449883 -0.485006 +0.468319 0.26004 0.481166 +0.444545 0.46615 0.47826 +-0.325731 0.512725 -0.128966 +-0.25649 0.505036 -0.146322 +0.0968877 -0.482749 -0.471554 +-0.269991 0.495561 -0.119949 +-0.128868 0.497652 -0.450721 +0.156352 0.495266 0.310819 +0.4935 0.201582 -0.217962 +0.44873 0.0881084 0.4899 +-0.466945 0.47597 -0.17024 +0.0795623 0.505691 0.0394845 +0.130994 0.490536 0.0619642 +-0.440614 0.353208 0.5036 +0.463817 0.475445 -0.451739 +-0.237092 0.494959 0.0674688 +-0.0762294 0.509593 0.268177 +-0.372224 -0.498668 0.267059 +-0.348135 -0.517313 0.254497 +-0.361278 0.506136 0.243757 +-0.414443 0.497973 0.257444 +0.245723 0.514861 -0.390803 +0.260424 0.496997 -0.410428 +0.474489 0.432447 0.463669 +0.282585 0.509921 -0.392339 +0.317906 0.49507 -0.110978 +0.289177 0.504112 -0.0612287 +-0.26304 0.0633642 0.495561 +0.287678 0.502933 -0.11072 +0.29167 0.505825 -0.282396 +0.496143 -0.438207 -0.445456 +0.245571 0.517184 -0.33592 +0.302824 0.499698 -0.316147 +0.345833 -0.434903 0.504183 +0.379075 -0.426443 0.504192 +-0.183105 0.257091 0.509072 +-0.242801 0.273864 0.510694 +-0.137771 -0.475198 0.473961 +-0.188273 0.286992 0.511604 +0.498591 -0.191783 -0.455207 +0.39672 0.515506 0.293636 +0.400714 0.501121 0.323514 +0.390764 0.512306 0.26404 +0.140111 -0.491165 0.247374 +-0.266673 0.496021 0.0547645 +0.101918 0.495303 -0.141312 +-0.460849 0.477615 -0.291272 +0.0695051 0.490481 -0.133129 +-0.245553 -0.498258 0.139824 +0.420916 -0.495484 -0.0374786 +0.0771342 0.501127 -0.163406 +0.43478 -0.503007 -0.0807066 +-0.0295693 0.492053 -0.172827 +-0.0594661 0.504498 -0.184032 +-0.0326273 0.490333 -0.20359 +-0.15963 0.506463 -0.213373 +-0.125643 0.505838 -0.204386 +0.453663 0.491054 0.343318 +0.513581 0.402667 0.0500775 +0.497761 0.415578 0.0257658 +0.0375156 0.490441 -0.00563163 +0.0347472 0.506039 -0.038289 +-0.499964 -0.404002 0.136444 +0.490895 0.0242052 -0.140737 +0.499502 0.00265395 -0.116832 +0.508329 0.0304614 -0.118693 +0.023238 -0.0621652 -0.508744 +0.348528 0.462861 -0.479122 +0.225313 0.502573 0.293673 +0.265173 0.51255 0.2508 +0.253689 0.503492 0.314922 +-0.430688 0.395507 -0.493992 +0.0516838 0.492999 0.219761 +-0.487001 0.445393 0.356168 +0.00791422 0.496619 0.192503 +0.0502992 0.495773 0.177614 +0.0127165 -0.0946721 -0.498414 +0.172912 0.500226 -0.0674119 +0.182008 0.497104 -0.00947236 +0.515279 0.322597 -0.350979 +0.482745 0.461249 -0.462236 +0.455 -0.474776 0.476691 +-0.214226 -0.344311 -0.505967 +-0.478317 0.202746 0.483238 +0.503736 -0.425145 0.208152 +-0.478339 -0.422912 0.468972 +0.456221 -0.371649 -0.496435 +-0.473082 0.176213 0.479464 +0.357203 0.484822 0.45027 +0.361221 0.48048 0.473767 +0.509534 -0.40196 0.20107 +0.472331 0.123442 0.463673 +0.469577 -0.327669 -0.48134 +-0.430553 -0.467914 -0.468133 +-0.466625 0.458239 0.460517 +0.482411 0.479961 -0.346031 +0.462718 0.456984 -0.464586 +0.470306 -0.46933 0.312058 +-0.46654 -0.466945 -0.457771 +3 2152 2918 962 +3 1251 3834 569 +3 2145 2917 782 +3 3923 3900 4739 +3 20 3070 2765 +3 3979 3932 2302 +3 3349 1139 178 +3 317 3597 2299 +3 23 4245 2359 +3 4747 3471 37 +3 7044 1657 2786 +3 1754 1677 1680 +3 4003 3999 320 +3 988 1269 3027 +3 4081 4041 450 +3 0 248 51 +3 2134 4116 5115 +3 2133 1769 7297 +3 285 741 1888 +3 2823 29 108 +3 316 4316 12 +3 2797 20 7093 +3 18 7 669 +3 4355 4343 2649 +3 3693 2127 4380 +3 2126 4393 6754 +3 3131 38 182 +3 2123 2911 7229 +3 4517 4491 5004 +3 4594 2910 2859 +3 44 2362 4315 +3 2100 4674 6888 +3 4693 5666 7443 +3 2097 4778 1109 +3 39 6007 186 +3 4870 4825 2511 +3 38 3257 206 +3 220 43 2224 +3 2983 5021 4439 +3 1336 4972 1411 +3 3834 5055 954 +3 3025 2401 2109 +3 5095 5069 2087 +3 6736 7 1591 +3 5136 2083 79 +3 744 59 232 +3 243 419 2239 +3 2049 4201 377 +3 2151 5869 2149 +3 485 5270 6117 +3 12 9 4282 +3 53 2318 940 +3 4282 9 6617 +3 5285 1058 6605 +3 2029 2988 4708 +3 5344 5327 56 +3 12 4282 316 +3 5418 5412 7022 +3 2067 5477 165 +3 2008 266 2256 +3 5562 7281 6302 +3 5647 2901 181 +3 57 2260 58 +3 2901 5666 4693 +3 2900 7367 2076 +3 270 64 2262 +3 1888 3597 285 +3 313 1114 1028 +3 65 5772 5755 +3 3 2480 3943 +3 2480 3 4793 +3 2211 203 364 +3 9 12 2935 +3 5564 4 389 +3 5115 4116 5698 +3 389 4 3004 +3 5756 5727 2511 +3 5787 5785 4866 +3 4461 6435 7 +3 67 2092 399 +3 2159 6 419 +3 419 6 2239 +3 317 2277 3597 +3 2354 428 429 +3 2694 147 7033 +3 155 4078 5643 +3 23 442 7506 +3 7506 442 8 +3 2039 7006 1143 +3 6053 6022 1328 +3 6109 6105 4657 +3 952 3744 3811 +3 2318 53 2280 +3 2169 2304 509 +3 1739 6246 6147 +3 6327 6310 5862 +3 2036 6339 45 +3 152 6338 6429 +3 551 46 4523 +3 4541 564 408 +3 6506 50 7091 +3 2531 3257 3256 +3 5120 49 4747 +3 657 89 4752 +3 2423 2348 657 +3 2362 44 2105 +3 44 4368 2101 +3 6586 6575 1625 +3 5559 2049 377 +3 2442 78 2445 +3 497 4384 2382 +3 496 4893 5365 +3 4282 6654 1931 +3 742 80 743 +3 1493 47 4616 +3 2160 2235 3726 +3 47 748 2102 +3 6702 6665 1308 +3 1743 76 2835 +3 147 5790 5789 +3 2024 6724 1652 +3 4933 83 760 +3 6833 6832 5940 +3 6923 6896 2727 +3 7011 6952 2463 +3 2453 83 4931 +3 2835 76 7305 +3 1169 4004 7035 +3 79 5153 1278 +3 5153 79 2276 +3 7065 7062 145 +3 796 2051 5671 +3 84 3210 4849 +3 836 34 2385 +3 2190 49 5120 +3 7113 6064 544 +3 84 3208 3670 +3 5082 2259 5208 +3 2017 7140 2170 +3 61 19 2503 +3 4375 6555 5824 +3 3057 7240 119 +3 2503 19 2198 +3 4893 4896 645 +3 2006 7294 2415 +3 5383 91 2309 +3 91 5429 995 +3 6763 92 6152 +3 2556 93 1036 +3 7418 7369 5555 +3 104 5375 115 +3 1123 1053 1050 +3 7264 7503 1736 +3 7038 1546 4096 +3 2250 1050 1053 +3 5592 95 5595 +3 5132 2500 5133 +3 5375 104 4760 +3 1965 1994 52 +3 4186 4056 3736 +3 2504 90 5213 +3 2565 95 5591 +3 424 3143 2198 +3 71 4287 4294 +3 5805 3043 5366 +3 4451 2710 1335 +3 1139 51 178 +3 4947 3844 3389 +3 1979 4740 7306 +3 1618 191 7523 +3 1124 3321 5242 +3 936 5260 1348 +3 4691 2880 112 +3 2351 115 5418 +3 6065 1188 1191 +3 224 2429 1192 +3 4935 4915 4834 +3 6009 97 1229 +3 2635 97 1230 +3 43 1130 1244 +3 567 3982 1525 +3 39 609 5748 +3 5418 115 5412 +3 1347 6278 2682 +3 6374 100 1378 +3 100 1379 6168 +3 6479 112 2533 +3 3685 5107 3117 +3 5203 5103 6948 +3 7240 1207 4459 +3 6446 101 1926 +3 1440 6460 5809 +3 2323 119 7240 +3 119 7237 3057 +3 1570 1178 2635 +3 5250 2533 5394 +3 52 5389 2577 +3 2752 103 6805 +3 3736 6657 2874 +3 1641 20 2765 +3 1600 1598 7380 +3 3930 3360 610 +3 120 6276 959 +3 5565 4061 6938 +3 7044 1798 29 +3 7285 30 29 +3 7024 30 2783 +3 1680 105 1754 +3 6276 120 6861 +3 6726 6571 4812 +3 3722 6894 5908 +3 7145 7014 2107 +3 7067 109 1689 +3 2797 107 3070 +3 1953 2869 870 +3 3845 1496 7105 +3 1338 4824 7182 +3 75 411 2383 +3 2732 102 3982 +3 7435 7313 640 +3 2376 4377 491 +3 1277 2633 21 +3 3883 4159 4920 +3 1277 21 7165 +3 4035 6899 5537 +3 2360 23 4246 +3 1087 6470 6051 +3 123 1942 6878 +3 6973 1756 1757 +3 108 7249 1773 +3 2233 26 1790 +3 5124 4928 5037 +3 2886 5425 3869 +3 1790 26 2243 +3 2820 27 252 +3 252 2675 2820 +3 7247 1798 2786 +3 1798 7247 108 +3 108 29 1798 +3 2783 30 1800 +3 2830 109 7310 +3 1942 123 6880 +3 1874 7413 2227 +3 2324 5270 4755 +3 2850 110 7412 +3 6117 1078 5067 +3 96 1154 6215 +3 132 150 7442 +3 2675 99 1897 +3 1932 5044 2905 +3 2107 7014 6641 +3 1932 111 2095 +3 7078 2536 6150 +3 2870 2095 111 +3 7078 7147 1953 +3 2799 1965 2052 +3 1967 2877 870 +3 7496 127 1920 +3 2710 101 6445 +3 2040 2039 2132 +3 2053 5593 2901 +3 169 3072 2180 +3 2330 33 2092 +3 2092 33 2355 +3 2095 6150 1932 +3 6922 6871 5763 +3 1316 2108 4550 +3 127 7347 7495 +3 6127 3893 7512 +3 7447 1890 1893 +3 5115 1890 2134 +3 828 2351 2263 +3 6008 5754 1940 +3 7429 2301 2246 +3 2300 129 7419 +3 3015 1611 2170 +3 2171 6112 1282 +3 5366 3043 827 +3 161 879 2173 +3 704 902 4826 +3 7077 6722 1120 +3 3054 209 5114 +3 2178 34 836 +3 1931 316 4282 +3 1928 7504 6482 +3 1922 7501 1408 +3 3070 1692 2765 +3 2765 6826 1641 +3 2180 2178 3242 +3 2180 3071 169 +3 7496 6483 3281 +3 1416 36 3328 +3 129 7420 198 +3 7490 7491 5031 +3 16 4316 7488 +3 3106 759 2185 +3 390 3119 2189 +3 1139 3349 223 +3 838 37 5521 +3 5521 37 114 +3 1910 1972 4534 +3 3131 5473 2193 +3 267 3132 2195 +3 6007 39 5748 +3 5177 133 3374 +3 3895 4355 7482 +3 189 3850 6637 +3 3374 133 3525 +3 6703 227 1544 +3 364 203 839 +3 3257 38 2193 +3 3256 3257 2193 +3 1288 3273 2219 +3 213 211 2220 +3 276 3319 579 +3 2224 3321 220 +3 3436 6894 5524 +3 2224 43 1244 +3 5242 3321 2224 +3 2068 224 1192 +3 5277 3360 3930 +3 2136 3373 2231 +3 6344 189 1382 +3 806 3412 891 +3 7479 7480 2197 +3 2237 46 551 +3 235 46 2237 +3 3433 1580 2238 +3 7472 7474 486 +3 245 2245 2459 +3 1263 7468 6976 +3 49 0 3471 +3 150 132 4772 +3 114 51 1139 +3 136 3380 4977 +3 2253 973 6896 +3 6233 199 7487 +3 2583 788 5709 +3 136 1037 4381 +3 54 1595 2256 +3 7359 140 7357 +3 1905 7463 4822 +3 2275 6723 176 +3 3597 1888 743 +3 7357 140 2572 +3 7334 141 7335 +3 3625 1707 1856 +3 141 2723 5936 +3 3648 552 2287 +3 3726 59 744 +3 2299 5222 317 +3 1377 64 270 +3 1348 3778 936 +3 2470 3792 2305 +3 148 3428 3113 +3 1032 3840 2312 +3 3845 3844 5792 +3 3428 148 3426 +3 2491 7458 6147 +3 349 3864 2317 +3 2320 66 65 +3 3965 1059 2579 +3 2322 4547 567 +3 7288 151 7292 +3 7292 151 244 +3 7111 843 1708 +3 2092 67 2330 +3 252 1898 2857 +3 1562 680 2209 +3 7448 7449 5046 +3 2655 411 1001 +3 413 1255 2342 +3 921 2914 2855 +3 1889 7444 286 +3 199 1120 7488 +3 429 428 3445 +3 2359 4246 23 +3 449 4255 2361 +3 2251 1428 7276 +3 7443 415 2906 +3 462 1716 2366 +3 2854 7438 2484 +3 2374 1224 470 +3 716 4358 970 +3 4373 1217 2376 +3 2491 250 7458 +3 7458 250 48 +3 535 4412 2384 +3 158 378 2308 +3 3671 284 7429 +3 7433 4212 6540 +3 2392 4481 2729 +3 7238 1149 173 +3 7422 7423 3086 +3 2300 2372 7430 +3 1995 1546 7038 +3 1878 7416 1898 +3 560 1584 561 +3 1416 4541 6420 +3 1416 2401 4541 +3 572 4563 2402 +3 980 4615 1868 +3 4627 1388 2407 +3 609 1296 2411 +3 237 6954 9 +3 179 173 7236 +3 173 1149 7073 +3 284 7430 7045 +3 2197 3923 7408 +3 114 37 3471 +3 657 7303 2423 +3 2271 5511 6811 +3 4785 4454 332 +3 2815 179 7235 +3 4816 937 2088 +3 1870 7405 7355 +3 7235 179 7236 +3 931 4856 2440 +3 7510 4160 4691 +3 3426 309 3390 +3 4914 2102 748 +3 497 1660 4896 +3 2450 741 4988 +3 743 80 2451 +3 7400 6644 1975 +3 2452 746 4913 +3 755 4923 2125 +3 5433 7399 1263 +3 4931 83 4933 +3 766 4937 2457 +3 767 1183 1007 +3 4425 180 1762 +3 180 7023 1309 +3 2372 2300 7419 +3 986 4948 2462 +3 7209 1550 2246 +3 2241 2301 7157 +3 1442 5051 2226 +3 6910 5107 3685 +3 5120 89 857 +3 857 89 657 +3 2214 190 7055 +3 5171 1468 2560 +3 5195 1071 2501 +3 5213 90 5212 +3 2881 7395 6157 +3 894 5220 1284 +3 7055 190 3299 +3 7212 685 1680 +3 2507 908 2936 +3 685 2241 7158 +3 941 1031 3765 +3 946 5283 3967 +3 1467 1285 4147 +3 2935 4269 7391 +3 3390 309 4388 +3 2844 1408 7060 +3 1842 5322 2148 +3 1223 5333 2526 +3 6644 3883 7379 +3 6926 1780 1624 +3 5372 4261 6098 +3 5394 917 5250 +3 5400 1094 1552 +3 7335 312 7334 +3 5429 91 2532 +3 1008 5447 2081 +3 1022 5489 3930 +3 312 6683 293 +3 226 325 7254 +3 1036 331 2556 +3 1036 93 2558 +3 4602 7446 2268 +3 1783 202 1631 +3 1046 1420 5190 +3 1053 1123 5575 +3 95 2568 3513 +3 867 1072 2575 +3 1821 212 4672 +3 424 4758 1390 +3 202 3078 6232 +3 1397 5764 2232 +3 5585 5237 7068 +3 1130 1245 2589 +3 5712 1131 1244 +3 1658 1661 2599 +3 1150 5861 2600 +3 1857 2843 2483 +3 1629 229 6938 +3 105 143 2804 +3 2420 296 3587 +3 1848 7361 3963 +3 1051 7356 2264 +3 1870 7355 964 +3 1185 5923 2614 +3 7350 7351 5148 +3 229 4022 4 +3 2131 1201 6873 +3 6688 234 6873 +3 1230 97 6009 +3 7346 7347 5442 +3 2839 1515 1793 +3 6873 234 6870 +3 1834 7339 1987 +3 2642 6054 6455 +3 220 222 2643 +3 186 3157 2656 +3 312 7335 1004 +3 2658 2228 6193 +3 6954 237 6955 +3 1322 1360 2668 +3 1334 6255 2674 +3 3736 4056 7333 +3 7328 7329 1120 +3 1897 99 6445 +3 6261 1847 2678 +3 2682 976 1347 +3 1370 6330 2686 +3 5700 7323 2811 +3 1379 100 6374 +3 1389 6385 2695 +3 1737 7176 6407 +3 1405 6415 5928 +3 1425 6434 2706 +3 2707 6876 6438 +3 6446 1927 2711 +3 7315 7316 1861 +3 6445 101 2711 +3 2273 2543 5463 +3 1461 6497 2716 +3 244 238 6821 +3 1571 1487 2726 +3 1507 1503 6591 +3 6821 238 6634 +3 3982 102 2735 +3 1540 6689 4301 +3 5978 2141 7385 +3 6820 244 6821 +3 6805 6804 2752 +3 176 1588 2757 +3 1606 6864 5487 +3 238 244 151 +3 2786 1798 7044 +3 6798 251 1344 +3 5853 2791 1754 +3 1754 105 5853 +3 2793 7338 1833 +3 2047 1879 2795 +3 3070 107 2798 +3 7507 3634 1576 +3 3587 296 5821 +3 251 6798 2313 +3 2832 4590 7355 +3 1989 1069 4186 +3 1825 2796 42 +3 1781 74 2378 +3 7307 7308 4328 +3 1838 7346 5442 +3 1774 7246 1776 +3 1786 2819 4854 +3 1344 337 6798 +3 3434 866 7129 +3 5382 1806 2824 +3 1809 5572 4253 +3 7338 7089 2833 +3 2833 1835 7338 +3 1857 7365 5587 +3 594 7399 5433 +3 1815 7299 6906 +3 659 279 3612 +3 1865 7384 6680 +3 279 6715 5373 +3 1978 7396 2846 +3 7412 110 2851 +3 6693 291 6695 +3 2028 7283 2069 +3 291 5530 5528 +3 2533 112 2880 +3 112 2657 4691 +3 2901 5647 2053 +3 4253 1811 1809 +3 2905 4729 1932 +3 2910 4594 2108 +3 253 7288 7292 +3 2123 4455 2911 +3 4118 2855 2914 +3 1800 7286 6520 +3 2145 3838 2917 +3 2918 2152 2 +3 2079 293 6683 +3 7254 325 434 +3 2262 269 58 +3 3788 146 509 +3 839 1054 364 +3 329 40 4465 +3 4021 1046 5564 +3 446 400 595 +3 243 2116 419 +3 2278 2299 3597 +3 1099 427 429 +3 1214 2237 551 +3 4469 7276 7021 +3 496 2255 647 +3 1264 1791 4854 +3 7254 434 7253 +3 7253 434 28 +3 1782 7269 1273 +3 1772 7265 3489 +3 7260 7261 3813 +3 743 2451 2278 +3 2454 2415 4931 +3 7257 7258 2937 +3 71 4294 2073 +3 325 226 6429 +3 1962 7266 7250 +3 564 4541 729 +3 2477 2178 836 +3 293 3922 7012 +3 106 294 5985 +3 1771 1273 7261 +3 5705 3613 2259 +3 2183 2260 57 +3 3360 3424 6853 +3 5089 3634 7441 +3 5420 1165 5419 +3 3044 5464 6723 +3 2549 1027 5512 +3 2239 2330 67 +3 3513 5591 95 +3 548 2359 4245 +3 7235 7236 2144 +3 1767 7233 3359 +3 1123 4256 3701 +3 1139 223 3217 +3 1125 2320 65 +3 7226 7230 6267 +3 7421 7221 1563 +3 1759 1543 1085 +3 650 3501 1148 +3 6248 301 3654 +3 2365 86 796 +3 687 2068 1192 +3 2637 1227 1230 +3 1131 2224 1244 +3 3654 301 6984 +3 6198 1296 1297 +3 6634 302 6633 +3 2692 4505 6168 +3 1755 6761 1782 +3 7213 7215 4917 +3 7209 7210 6031 +3 6380 1380 2329 +3 2439 455 3109 +3 2532 91 5383 +3 1520 2731 1524 +3 116 6706 1670 +3 7206 7207 1866 +3 3109 455 2847 +3 492 7238 179 +3 6703 537 6705 +3 6706 116 3087 +3 6633 302 3470 +3 1570 1227 4898 +3 6777 1577 1578 +3 6804 2753 5855 +3 2765 1597 6826 +3 6847 3238 6845 +3 5107 5108 6405 +3 2798 1692 3070 +3 6705 537 6551 +3 2735 1525 3982 +3 2609 2791 5853 +3 4308 607 4307 +3 2359 2321 4246 +3 7195 3161 2588 +3 635 6567 882 +3 634 228 1790 +3 2786 117 7247 +3 7247 117 3812 +3 7191 7192 532 +3 198 7420 7188 +3 1709 1609 70 +3 5558 2793 1619 +3 2814 3962 7467 +3 4984 5396 3213 +3 3068 3666 1090 +3 1740 192 1749 +3 2677 1794 1897 +3 7468 1263 7467 +3 314 6574 1326 +3 7177 7180 4284 +3 2711 1434 6445 +3 1080 2877 1992 +3 6906 3015 1817 +3 7113 2032 7116 +3 6574 314 1678 +3 790 399 2092 +3 7147 7078 2095 +3 4380 4374 3693 +3 2235 2294 617 +3 1093 2579 5962 +3 5872 4748 2423 +3 2786 904 1970 +3 2782 2905 5044 +3 3663 1603 2596 +3 7470 122 3132 +3 1121 2921 3591 +3 2037 1530 2923 +3 2932 313 6166 +3 315 6568 6923 +3 1402 4595 5469 +3 1831 585 2938 +3 2811 2598 5700 +3 1075 5645 5877 +3 2940 5877 6380 +3 6191 367 1189 +3 2457 763 2941 +3 2942 6443 7016 +3 2943 457 4271 +3 2085 2160 744 +3 744 232 2085 +3 2085 232 5095 +3 443 2378 5408 +3 6568 315 321 +3 6568 321 3699 +3 3699 321 6249 +3 7289 2944 128 +3 6758 4182 7043 +3 992 835 5080 +3 427 367 2960 +3 3203 3123 3429 +3 2965 174 4296 +3 457 174 4271 +3 2997 3224 2974 +3 2974 3224 2976 +3 1728 7168 7500 +3 635 995 5429 +3 913 326 3700 +3 3211 6394 3376 +3 2977 579 3633 +3 1923 7166 5706 +3 5909 1016 2979 +3 326 3704 4861 +3 626 2436 5032 +3 800 2722 7425 +3 1038 1438 2987 +3 3945 139 205 +3 205 278 3945 +3 1277 5942 5312 +3 576 1977 6544 +3 142 4513 2166 +3 642 1325 6527 +3 4702 1615 6912 +3 651 642 6527 +3 3186 754 157 +3 7161 7162 5630 +3 1969 565 6528 +3 31 4681 5604 +3 2301 2241 685 +3 1720 7152 4345 +3 332 1458 4785 +3 1325 642 2279 +3 1417 408 6418 +3 3895 7482 7142 +3 388 7478 2480 +3 3508 388 4021 +3 3008 446 4254 +3 1352 416 3011 +3 1481 2932 509 +3 2932 2169 509 +3 509 146 1481 +3 2281 2292 1481 +3 711 3559 3936 +3 3015 6906 6870 +3 7134 7135 4350 +3 1652 280 6626 +3 332 4784 4926 +3 1644 352 3032 +3 1902 7131 2229 +3 4007 2545 5490 +3 7125 7126 3896 +3 155 3035 3295 +3 7451 7123 6584 +3 7349 6408 376 +3 209 210 1209 +3 4439 2189 521 +3 6798 337 6472 +3 1282 157 3033 +3 337 5626 3689 +3 4981 358 3759 +3 2937 7477 7118 +3 5739 159 3043 +3 159 2226 3339 +3 7114 5249 2295 +3 288 161 2173 +3 1969 651 6525 +3 651 6527 1155 +3 288 167 166 +3 167 1444 467 +3 2396 2600 4504 +3 358 988 3760 +3 2175 1764 7096 +3 7096 5955 2175 +3 2276 2296 575 +3 6981 2116 3048 +3 853 2219 3054 +3 3276 362 1417 +3 362 6417 4980 +3 3070 20 2797 +3 1111 169 3071 +3 34 2178 3072 +3 3072 2178 2180 +3 5549 2177 3072 +3 3328 2401 1416 +3 3328 36 2225 +3 36 6420 2064 +3 7109 7111 7095 +3 170 3074 6447 +3 3074 170 1706 +3 3076 2961 1295 +3 7107 7106 2328 +3 2882 7101 7504 +3 3255 1631 202 +3 7097 7098 6447 +3 1826 1025 6378 +3 7090 7093 2221 +3 666 2183 2425 +3 2155 363 6478 +3 457 3087 4296 +3 175 3095 3816 +3 1539 662 1987 +3 712 1976 2681 +3 3098 1216 6337 +3 3098 3097 3099 +3 666 668 3101 +3 1151 2454 3106 +3 759 760 3111 +3 4690 521 5259 +3 391 5278 3119 +3 2326 390 3120 +3 6967 6301 6971 +3 1701 7081 6293 +3 3349 178 6363 +3 2970 1477 6531 +3 365 6370 1820 +3 2801 68 7079 +3 2702 1404 2580 +3 2580 3130 2702 +3 1382 2192 6344 +3 3042 1603 3263 +3 6370 365 4248 +3 7070 7071 1017 +3 38 3131 2193 +3 3131 182 1016 +3 183 3132 267 +3 662 1919 4028 +3 1692 2798 435 +3 3132 183 1121 +3 184 3136 1106 +3 3136 184 267 +3 1693 375 365 +3 2306 329 3138 +3 1579 6311 4841 +3 3141 6751 5372 +3 185 2504 3143 +3 1390 185 3143 +3 3416 701 3151 +3 1687 3489 1986 +3 3153 2085 5095 +3 186 6007 4626 +3 3158 4077 4378 +3 840 187 3164 +3 7063 181 4687 +3 3164 187 1457 +3 3323 2787 5575 +3 2113 933 4517 +3 365 375 1108 +3 384 6369 1693 +3 2970 1382 189 +3 6369 384 5410 +3 2069 2047 2795 +3 3188 4461 6551 +3 456 3194 6749 +3 724 401 6335 +3 401 2966 593 +3 190 2214 887 +3 3200 839 5093 +3 193 3204 3423 +3 3204 193 6742 +3 770 414 6323 +3 6027 7253 7052 +3 194 4536 2489 +3 2390 40 2202 +3 6323 6322 770 +3 3207 347 3861 +3 417 6291 770 +3 6291 417 706 +3 1399 200 2207 +3 200 3019 2207 +3 1399 3020 200 +3 3115 3103 3221 +3 408 564 1415 +3 212 6479 3594 +3 448 6281 2168 +3 6281 448 4042 +3 1674 1676 1675 +3 674 5480 2701 +3 3225 3224 3226 +3 619 606 3229 +3 1216 328 5981 +3 3231 328 6790 +3 195 339 3238 +3 2568 1054 3244 +3 117 52 1994 +3 6174 451 6175 +3 2217 207 3244 +3 557 476 1363 +3 207 675 3250 +3 3250 130 4780 +3 839 203 5093 +3 678 6358 6362 +3 6888 4674 7036 +3 1634 1666 3947 +3 6358 678 5826 +3 6707 2584 5732 +3 4572 206 3257 +3 306 4875 7463 +3 1363 476 1110 +3 41 675 2217 +3 799 463 5941 +3 6071 675 41 +3 2712 722 6353 +3 139 2188 3267 +3 210 209 3273 +3 6169 210 3273 +3 3085 2944 3274 +3 2435 227 3275 +3 1944 1269 3276 +3 5289 213 3279 +3 5401 5318 7026 +3 1839 529 4230 +3 722 5687 2098 +3 3282 3223 211 +3 211 213 3282 +3 3164 3206 3287 +3 7020 7021 622 +3 2296 2083 3288 +3 3287 3286 3288 +3 463 5944 515 +3 216 215 3291 +3 3291 215 5289 +3 3292 3199 1723 +3 1583 1750 466 +3 529 4229 828 +3 215 216 2222 +3 7327 3047 3296 +3 6039 1010 4189 +3 2217 1010 41 +3 724 6332 1863 +3 5456 41 1010 +3 466 5866 1583 +3 7003 4726 3443 +3 1564 4591 791 +3 4261 5372 6751 +3 6997 2515 27 +3 6924 1239 6751 +3 6040 1044 1239 +3 422 276 3318 +3 3319 3561 1443 +3 4834 4915 6995 +3 6993 6038 3724 +3 1736 7503 6991 +3 219 4605 579 +3 6332 724 6334 +3 1069 2201 2172 +3 222 220 3321 +3 6984 6985 7108 +3 222 3321 2627 +3 3059 3060 3324 +3 3327 2910 1316 +3 5866 466 6077 +3 2109 2401 3328 +3 3337 5367 6711 +3 3338 426 4445 +3 7036 6979 1990 +3 3339 3043 159 +3 1055 573 4236 +3 3060 3093 3350 +3 3351 3350 3352 +3 3315 3040 3354 +3 224 2068 2263 +3 6677 104 2351 +3 6972 6974 3284 +3 2951 2966 3361 +3 3362 1475 502 +3 3369 1352 6285 +3 2162 271 3371 +3 3999 2361 3373 +3 1127 1128 3381 +3 1354 363 982 +3 6971 6301 3303 +3 3897 1235 350 +3 3387 171 3897 +3 3381 3019 3389 +3 2233 1790 228 +3 740 6318 69 +3 228 280 2233 +3 6962 6964 1512 +3 280 228 3581 +3 6958 6960 2009 +3 6954 6955 7199 +3 5792 477 1147 +3 6660 6953 3306 +3 6344 3850 189 +3 3402 3058 1207 +3 4277 230 3406 +3 1636 6951 5466 +3 1632 6946 3149 +3 230 2755 5119 +3 373 7060 6944 +3 3408 3407 1103 +3 2775 7190 7351 +3 1629 6938 4061 +3 3726 744 2160 +3 1861 7316 6934 +3 477 3020 5791 +3 3412 233 5210 +3 354 235 3413 +3 6931 6932 1732 +3 3414 4523 46 +3 3956 7144 6929 +3 46 235 3414 +3 2973 2972 3419 +3 3360 1668 3424 +3 3390 3332 3426 +3 3113 3166 148 +3 6927 3687 1780 +3 573 1291 4436 +3 6920 6921 616 +3 1399 236 3431 +3 3431 236 2476 +3 3617 5060 6919 +3 263 6617 6917 +3 1622 6915 4702 +3 665 493 3036 +3 493 4079 4735 +3 2713 6911 6910 +3 3895 7142 6909 +3 494 5722 5725 +3 239 4323 717 +3 3364 6907 6905 +3 240 3433 239 +3 3433 240 2738 +3 2239 67 243 +3 7084 7168 4199 +3 4285 6900 6898 +3 918 1738 3992 +3 1254 1097 3437 +3 2574 3323 4038 +3 121 1714 3455 +3 1790 2243 634 +3 6892 6893 1664 +3 3455 3454 3456 +3 3456 634 4714 +3 3270 3104 3466 +3 5722 494 4976 +3 2245 245 246 +3 5839 246 245 +3 6889 6890 4267 +3 495 2316 1516 +3 3471 0 51 +3 51 114 3471 +3 7166 495 5706 +3 502 5648 3362 +3 502 1877 1371 +3 3475 2021 5874 +3 7187 253 3476 +3 423 6940 1575 +3 2104 691 5325 +3 3476 253 1803 +3 1620 5571 2324 +3 3482 3382 6026 +3 4906 6876 2707 +3 3484 970 3201 +3 3585 978 5010 +3 5206 4887 6875 +3 507 1365 5625 +3 3490 1611 234 +3 1612 2522 1672 +3 2384 255 3491 +3 3491 255 2261 +3 6869 6870 6906 +3 1606 5487 5346 +3 3488 259 3492 +3 3492 259 1913 +3 2254 1148 3501 +3 1148 2254 5794 +3 3081 3420 3498 +3 3501 2988 2029 +3 2342 2917 2140 +3 6853 6854 610 +3 6849 6851 5397 +3 260 404 261 +3 260 271 2162 +3 5032 2436 3651 +3 261 3502 475 +3 3502 261 404 +3 3238 6847 4676 +3 277 388 3508 +3 388 277 2875 +3 3354 3353 3511 +3 2256 266 647 +3 2255 54 2256 +3 2256 647 2255 +3 527 507 5625 +3 469 4882 3018 +3 6835 6838 677 +3 1365 507 1344 +3 1601 1996 3247 +3 1510 526 5622 +3 3519 2761 54 +3 2766 1511 3587 +3 526 3785 3541 +3 54 2255 3519 +3 267 184 183 +3 184 3520 183 +3 1508 527 5622 +3 322 268 3757 +3 3523 268 4723 +3 3375 3374 3525 +3 268 322 1488 +3 527 5625 1510 +3 2922 817 3529 +3 2608 1165 3529 +3 58 269 57 +3 1597 2765 1692 +3 1596 6823 4146 +3 2262 58 270 +3 189 3535 2970 +3 3539 404 260 +3 6673 7292 244 +3 3539 3538 1061 +3 3017 3461 3542 +3 272 3549 1455 +3 3549 272 3555 +3 5311 273 3549 +3 3549 273 3550 +3 6477 274 3550 +3 274 2083 5136 +3 1477 2187 6533 +3 3503 3504 3551 +3 3500 2091 3553 +3 530 5569 2562 +3 3556 563 2527 +3 2266 6307 982 +3 1594 2327 5160 +3 5569 530 6471 +3 982 1764 2266 +3 3319 276 3561 +3 1964 6812 6811 +3 48 7448 6809 +3 5515 7202 7522 +3 1588 176 6723 +3 3419 3418 3565 +3 3333 277 3508 +3 4297 3228 6121 +3 539 5540 1695 +3 2250 1052 5498 +3 3563 3562 3574 +3 3577 599 2048 +3 539 1435 1105 +3 6221 544 5525 +3 278 599 3005 +3 6802 2604 1645 +3 5525 544 547 +3 421 6796 251 +3 3581 6289 583 +3 661 613 3583 +3 3124 3123 5037 +3 2182 2272 281 +3 691 3163 2279 +3 2467 718 2067 +3 6064 547 544 +3 2751 2848 6786 +3 3592 2125 6585 +3 547 4645 3451 +3 5495 1105 1435 +3 740 3687 6927 +3 5970 5584 2273 +3 2855 3600 3012 +3 240 6783 2738 +3 285 3597 2277 +3 2277 286 285 +3 2428 1486 425 +3 285 286 7444 +3 167 288 2173 +3 3511 3512 3604 +3 2357 439 3610 +3 1426 887 5454 +3 5082 5705 2259 +3 553 4206 1478 +3 3613 290 2018 +3 2018 2259 3613 +3 4206 553 829 +3 2888 2283 3843 +3 476 557 7007 +3 2466 788 3619 +3 6778 6779 3854 +3 1912 3487 7390 +3 2583 5709 465 +3 1577 6777 188 +3 6772 6774 4812 +3 465 3620 2583 +3 3618 2670 5192 +3 6768 1813 1605 +3 58 2260 3621 +3 3766 6835 6764 +3 2402 571 3621 +3 7007 3902 476 +3 3625 7109 1707 +3 3630 4945 2843 +3 4204 3630 2284 +3 1418 2013 3635 +3 6528 565 5324 +3 1418 295 619 +3 295 7290 606 +3 1258 1070 3642 +3 2722 800 7494 +3 6753 6755 4542 +3 886 5424 2530 +3 3648 4528 137 +3 1564 6751 3141 +3 3309 3308 3650 +3 3650 795 4886 +3 2596 1603 6545 +3 6745 6746 5483 +3 3003 3246 3653 +3 2200 299 3658 +3 3658 299 4357 +3 6741 6742 410 +3 1110 3126 3832 +3 4979 359 3936 +3 4449 4567 5324 +3 2730 355 3667 +3 5874 576 5321 +3 3670 3210 84 +3 414 770 6291 +3 303 3678 2288 +3 3678 303 606 +3 304 585 2288 +3 304 3676 585 +3 5321 576 6544 +3 868 592 4247 +3 592 824 2176 +3 2933 305 3868 +3 6737 6739 2631 +3 3868 305 5298 +3 593 4249 6335 +3 6731 6733 5148 +3 3689 3688 3691 +3 1887 308 3262 +3 3262 3693 1887 +3 3639 3638 4335 +3 4249 593 821 +3 3697 1346 2234 +3 3703 3700 326 +3 3126 1110 2307 +3 2462 777 3708 +3 7523 191 5978 +3 2291 310 2289 +3 2289 3095 3712 +3 595 4254 446 +3 1114 313 2932 +3 3712 3095 175 +3 177 6725 4624 +3 6336 3742 1551 +3 175 3715 3712 +3 4988 7445 6718 +3 4254 595 449 +3 3296 3295 3717 +3 620 1996 5800 +3 4030 3154 5065 +3 843 845 3725 +3 3723 60 242 +3 3726 617 4446 +3 1996 620 855 +3 621 5229 4738 +3 1566 320 3733 +3 5229 621 1169 +3 3733 320 2136 +3 329 632 3735 +3 3734 3733 3735 +3 3372 340 5156 +3 64 1378 3780 +3 3548 348 3738 +3 2692 1377 3738 +3 1549 6714 3117 +3 1123 1050 3744 +3 3744 1050 5747 +3 3744 4256 1123 +3 3622 3093 3748 +3 1645 860 6802 +3 5275 6712 2926 +3 860 3222 7179 +3 3464 3461 3756 +3 880 602 3757 +3 4867 7356 6710 +3 1372 116 1670 +3 3758 3377 6926 +3 770 6292 417 +3 3269 3120 3768 +3 3768 5021 2983 +3 6705 6550 4995 +3 3658 3657 3770 +3 2141 5978 191 +3 1702 2609 7082 +3 3778 1349 1202 +3 2262 64 3780 +3 2682 1348 2725 +3 3785 3783 3786 +3 509 2304 3787 +3 509 3787 3788 +3 3787 3094 3788 +3 918 919 3789 +3 3789 3094 3787 +3 3253 2747 1565 +3 4506 1714 546 +3 6696 6698 1072 +3 3760 3027 3791 +3 4311 1361 801 +3 3792 803 1924 +3 3331 323 1530 +3 6214 637 1960 +3 7516 7515 2438 +3 3803 3641 323 +3 775 1963 2393 +3 2982 5056 7522 +3 5035 659 5033 +3 4799 247 6079 +3 932 3804 3806 +3 1216 3808 6790 +3 6693 6694 2367 +3 1540 4301 3232 +3 1217 1218 3808 +3 6137 5387 837 +3 330 40 2306 +3 40 330 2202 +3 1707 7095 6945 +3 3818 3816 3819 +3 6682 6683 5545 +3 5434 6680 7281 +3 3700 3199 3823 +3 2556 331 3824 +3 331 2302 1284 +3 3826 5586 6607 +3 3793 5125 3826 +3 1535 6678 3747 +3 2023 5116 3827 +3 659 3612 5965 +3 6542 6670 6600 +3 2023 2025 5479 +3 6428 7483 6669 +3 3830 3318 22 +3 3831 3017 3835 +3 3415 333 3835 +3 6137 825 5708 +3 336 1038 333 +3 336 2559 1038 +3 2890 837 6136 +3 333 3839 336 +3 5528 3862 2642 +3 1454 1313 6218 +3 306 339 3842 +3 1531 6662 3112 +3 3842 1454 538 +3 1001 7128 2732 +3 3843 2283 5385 +3 3844 7105 3389 +3 340 3845 5792 +3 1170 4844 711 +3 879 342 3851 +3 342 5086 4848 +3 2793 4027 7089 +3 6655 5825 1522 +3 681 1479 6650 +3 3528 3527 3857 +3 1398 344 3857 +3 3857 344 3859 +3 345 3859 346 +3 345 3443 4726 +3 5743 346 3859 +3 346 3442 345 +3 3759 3760 3860 +3 3861 341 3207 +3 4334 349 3863 +3 3866 571 3864 +3 348 3866 2203 +3 6645 6646 6473 +3 3864 349 3866 +3 6163 631 1287 +3 928 1287 3869 +3 1125 65 5755 +3 5772 65 5793 +3 3874 3873 3875 +3 2962 3873 3879 +3 3788 3251 3884 +3 4027 945 2876 +3 2876 7089 4027 +3 2951 3208 3887 +3 2984 2941 3889 +3 2148 2149 3889 +3 853 3090 1660 +3 4964 5779 1138 +3 6638 6639 3301 +3 2322 1525 3894 +3 2461 1909 3894 +3 3897 2516 5304 +3 1235 351 5543 +3 5364 851 3899 +3 3901 3899 3903 +3 302 6634 238 +3 1602 3486 1935 +3 355 3908 1705 +3 6628 6629 7475 +3 1082 5033 5030 +3 3874 357 3909 +3 357 2992 2548 +3 3909 1026 3874 +3 86 4292 3911 +3 2822 1794 3911 +3 4844 1170 7461 +3 5280 701 3912 +3 3917 3605 2636 +3 2287 700 4971 +3 1059 3965 3924 +3 613 3933 2545 +3 360 359 3935 +3 3559 3601 3762 +3 700 1868 1871 +3 6620 6622 385 +3 2619 6618 6550 +3 6613 6614 4034 +3 6613 6611 691 +3 359 360 3936 +3 1950 1457 3937 +3 994 1205 1300 +3 6291 706 4929 +3 3938 1950 6130 +3 818 66 3943 +3 2320 3943 66 +3 818 3198 1554 +3 4705 1603 3663 +3 3943 2320 3 +3 3 2320 1420 +3 4929 706 4452 +3 3944 4444 750 +3 2061 523 3946 +3 3949 3552 1092 +3 2902 6604 2838 +3 3951 2360 4246 +3 2486 4071 3953 +3 4717 2321 2488 +3 2321 4066 2456 +3 6601 6602 739 +3 3849 3848 3955 +3 6597 6598 3514 +3 3352 3335 3959 +3 6607 5586 6297 +3 3960 3959 3961 +3 3963 5030 1094 +3 1062 3965 1093 +3 203 2211 3966 +3 1062 1093 3966 +3 4347 2369 1683 +3 3969 1475 5536 +3 3295 3035 3970 +3 2774 6595 1788 +3 2202 3972 5430 +3 907 3480 7009 +3 3016 3226 3976 +3 1854 2777 1664 +3 5057 6588 6584 +3 3178 3052 1173 +3 6578 6582 1252 +3 2960 367 3978 +3 901 3977 3980 +3 6178 2732 3982 +3 4917 3986 7213 +3 902 368 3987 +3 1678 6576 997 +3 3987 368 4463 +3 432 370 3987 +3 3987 370 2714 +3 374 2509 3992 +3 374 3992 7176 +3 2509 374 2862 +3 4379 2686 2366 +3 1198 4217 370 +3 379 4000 4002 +3 4000 379 2976 +3 382 4002 4792 +3 4002 382 2013 +3 6136 837 5384 +3 2111 4550 754 +3 3795 7243 3637 +3 709 723 991 +3 2585 1115 1026 +3 386 4006 1117 +3 4006 386 3878 +3 1117 3645 386 +3 1468 1471 4008 +3 1709 2295 4014 +3 2972 3804 4015 +3 586 589 4281 +3 4017 586 5199 +3 1494 2747 6760 +3 1024 387 4240 +3 387 1900 4240 +3 5657 2748 6570 +3 294 106 6630 +3 5564 389 4021 +3 3594 6479 2621 +3 4021 2267 3508 +3 389 3004 2267 +3 4022 3004 4 +3 4 5564 6938 +3 2561 1044 4031 +3 3119 390 4039 +3 3006 391 4039 +3 4039 391 3119 +3 6785 1091 6425 +3 4043 4042 4044 +3 3577 3810 4045 +3 751 392 4045 +3 4046 1138 392 +3 3753 3749 4047 +3 2396 1839 4047 +3 5956 393 6481 +3 5403 4057 4620 +3 6063 6923 6568 +3 3326 3877 4062 +3 4062 4058 4063 +3 4012 4008 4065 +3 4065 4064 4069 +3 3708 3710 4070 +3 2552 723 709 +3 2651 394 4073 +3 3994 3049 3486 +3 8 7196 6564 +3 6561 6562 4484 +3 3879 3878 4074 +3 6558 6559 3141 +3 5936 7335 141 +3 5643 3035 155 +3 3088 3089 4084 +3 1580 395 4085 +3 395 5651 4088 +3 3056 3920 4086 +3 4084 4080 4088 +3 4085 4088 4868 +3 5813 1151 3106 +3 723 4238 3050 +3 4091 396 5368 +3 4090 4089 4091 +3 4024 3128 4094 +3 4096 1546 5367 +3 4019 4018 4097 +3 5034 397 4097 +3 4097 397 562 +3 3562 4098 3340 +3 4829 726 4806 +3 2037 398 4099 +3 398 4657 1628 +3 4094 4095 4101 +3 3379 3430 4103 +3 170 2232 4108 +3 4108 1706 170 +3 3734 3347 4111 +3 4838 4197 3452 +3 4110 4109 4111 +3 400 4113 595 +3 400 383 6046 +3 3105 3449 4114 +3 400 446 4114 +3 3337 3338 402 +3 3401 2332 403 +3 3401 4096 2332 +3 4806 726 1733 +3 402 4115 403 +3 403 2332 402 +3 727 4788 5932 +3 4995 1545 6705 +3 1346 5253 4005 +3 261 4120 260 +3 2926 6712 6547 +3 5207 416 4121 +3 4121 4120 4122 +3 727 5286 3599 +3 4123 405 4759 +3 3128 3731 4125 +3 3925 3927 4128 +3 3855 3673 4130 +3 3537 3556 4131 +3 4132 3271 3364 +3 3483 3482 4133 +3 1640 6967 4134 +3 6287 6305 6265 +3 3944 2336 523 +3 6541 6543 6490 +3 734 4892 7426 +3 407 1401 4138 +3 406 4139 2336 +3 4139 406 566 +3 1401 407 4139 +3 4139 407 523 +3 4892 734 1590 +3 166 467 2167 +3 2947 3157 4626 +3 4123 4148 1162 +3 2576 1345 4149 +3 4498 4853 1327 +3 410 6742 193 +3 562 2340 680 +3 6267 7230 6537 +3 2383 411 6179 +3 6179 411 2655 +3 6091 412 6179 +3 6179 412 2383 +3 6534 6535 1107 +3 1476 6532 3362 +3 6998 7307 6530 +3 3453 1712 7040 +3 4154 566 2339 +3 2748 1077 6770 +3 2343 413 2342 +3 747 4769 1367 +3 4502 3603 545 +3 2652 545 3322 +3 1584 2344 4165 +3 2344 3719 4165 +3 3564 3820 4166 +3 6527 4665 1155 +3 3011 416 4167 +3 6519 6522 6021 +3 4167 4166 4168 +3 852 458 4171 +3 4769 747 3084 +3 758 4638 4718 +3 4171 458 3421 +3 4173 4172 4174 +3 6136 2858 2890 +3 7248 418 4181 +3 4181 418 3672 +3 420 2090 4185 +3 420 2419 933 +3 4638 758 4890 +3 6196 791 4591 +3 2419 420 4185 +3 4185 6 2419 +3 1315 4187 3007 +3 1315 2505 4187 +3 4758 424 4190 +3 1474 6515 6674 +3 4190 424 2198 +3 4192 4190 4193 +3 2395 1621 4195 +3 3270 4115 4203 +3 4770 1765 6512 +3 4206 4203 841 +3 540 1824 4207 +3 791 6750 1564 +3 2960 2354 429 +3 429 427 2960 +3 428 5693 3445 +3 428 2354 4208 +3 4213 790 5138 +3 2567 749 4510 +3 430 433 431 +3 2356 430 868 +3 5145 797 5967 +3 431 4164 3061 +3 4215 433 4738 +3 797 3344 2339 +3 370 432 1198 +3 798 4570 3906 +3 3772 4218 4399 +3 1748 3284 1802 +3 6508 6509 7394 +3 4078 155 4219 +3 4219 4218 4221 +3 3534 437 4223 +3 4223 437 558 +3 1748 1802 2853 +3 2830 1824 4227 +3 4226 4224 4227 +3 3487 3343 4231 +3 4570 798 4572 +3 3356 3753 4230 +3 4229 4231 6677 +3 3013 4895 1690 +3 4236 4019 1055 +3 2717 73 2072 +3 6266 2639 2770 +3 1962 1194 7266 +3 1900 1213 4240 +3 2974 3484 3201 +3 3975 3976 4242 +3 1987 4028 1834 +3 1091 6783 6079 +3 440 4243 2357 +3 1461 2716 5191 +3 440 4241 2298 +3 1173 3977 3178 +3 2298 4243 440 +3 7506 4245 23 +3 2176 4249 4248 +3 3728 445 5538 +3 3165 801 1361 +3 5538 3714 3728 +3 3298 4032 4252 +3 5437 602 1002 +3 7186 1002 4253 +3 4254 5 3008 +3 3701 449 595 +3 801 4313 815 +3 4255 4256 952 +3 3744 952 4256 +3 4255 449 4256 +3 3227 3163 4258 +3 1892 1893 4262 +3 2934 3474 4264 +3 915 2191 5680 +3 2413 2294 5760 +3 4266 4265 4268 +3 6491 6492 264 +3 915 808 4763 +3 6486 6488 4338 +3 385 6056 6484 +3 824 1818 6335 +3 6383 456 452 +3 4273 6069 852 +3 4171 4273 852 +3 6867 1609 4273 +3 1626 6869 7299 +3 7299 70 1626 +3 6375 3026 4276 +3 7496 2073 6483 +3 459 4277 6252 +3 459 6341 230 +3 5973 2757 1215 +3 3385 1215 4278 +3 1813 460 4280 +3 4249 821 4248 +3 4289 1595 1601 +3 273 6476 6480 +3 6247 849 4104 +3 821 3888 6370 +3 4152 4153 4293 +3 3190 3272 4295 +3 6798 6474 2313 +3 4308 4177 6887 +3 4307 4284 4177 +3 4311 815 2632 +3 592 3061 1818 +3 2686 461 2366 +3 461 462 2366 +3 6467 6468 311 +3 4317 2763 3494 +3 1597 2154 3853 +3 2154 1597 3802 +3 1447 6465 3865 +3 6660 5199 620 +3 5040 1642 3954 +3 2176 4247 592 +3 239 3432 240 +3 3433 2238 4323 +3 6456 871 1242 +3 2819 1785 4323 +3 4104 849 4961 +3 912 4162 4247 +3 2969 4063 4332 +3 4158 4013 4336 +3 6451 6452 3752 +3 2236 3384 7511 +3 822 1451 4337 +3 876 6406 325 +3 6872 1052 5574 +3 2371 2368 4347 +3 2167 467 4356 +3 3293 4356 3155 +3 1224 4356 3293 +3 472 4357 470 +3 6448 1917 2184 +3 3977 1173 3980 +3 719 473 4358 +3 4358 473 5354 +3 3268 4361 7173 +3 6006 769 2700 +3 2375 1163 4363 +3 3502 3786 4366 +3 1335 1984 4451 +3 1363 3832 1642 +3 4366 596 1945 +3 475 3248 261 +3 4367 891 6656 +3 828 4230 529 +3 6406 876 2894 +3 4230 828 3356 +3 3371 3369 4371 +3 4206 829 4203 +3 4371 1145 3371 +3 2005 478 4372 +3 4372 478 1097 +3 21 2633 5988 +3 1431 1433 1432 +3 4203 829 3270 +3 2984 5248 490 +3 297 841 4200 +3 490 3099 482 +3 491 4373 2376 +3 6439 6440 2381 +3 841 4203 4445 +3 4377 923 491 +3 2707 6941 4906 +3 74 4378 2378 +3 4378 74 7417 +3 458 852 4170 +3 5498 409 2586 +3 5747 5498 5749 +3 3905 2994 4379 +3 3481 3480 907 +3 852 6848 6845 +3 1557 2397 1410 +3 247 3980 6425 +3 647 266 4384 +3 4384 266 2382 +3 4893 496 4384 +3 4384 496 647 +3 5704 1288 4385 +3 1660 497 4385 +3 4385 497 2382 +3 4386 2297 4699 +3 3942 3941 4387 +3 1573 75 2383 +3 503 5502 387 +3 4295 4293 4391 +3 4391 503 4392 +3 4392 503 1024 +3 3278 3485 4395 +3 1425 2706 7290 +3 4395 4394 4397 +3 504 5875 1578 +3 5875 504 3615 +3 3047 4486 4399 +3 2691 4908 4402 +3 4402 3303 2691 +3 4407 4405 4408 +3 3414 3530 4409 +3 4479 505 4412 +3 4412 505 5071 +3 506 535 2384 +3 535 506 216 +3 836 2385 4669 +3 6430 6431 7204 +3 6296 915 4589 +3 939 2477 836 +3 4589 959 6296 +3 1314 2950 4417 +3 2304 2169 4423 +3 909 855 3775 +3 3775 855 5199 +3 4423 512 514 +3 512 4420 514 +3 514 510 4423 +3 514 1404 510 +3 658 517 4429 +3 3233 4430 517 +3 5944 4430 3233 +3 3591 4433 2184 +3 517 4433 3233 +3 4235 4236 4436 +3 1291 518 4436 +3 6421 6422 3403 +3 4436 518 2708 +3 519 4437 520 +3 519 282 2387 +3 1291 520 4437 +3 520 3948 519 +3 2061 522 4442 +3 4442 522 1429 +3 3944 523 2061 +3 868 4162 2356 +3 4403 525 4444 +3 4444 525 2272 +3 4328 7308 6412 +3 3041 7331 6410 +3 3024 1039 334 +3 3995 4405 4448 +3 3062 546 4450 +3 868 4247 4162 +3 543 7494 3624 +3 4453 4452 4454 +3 1039 4244 1079 +3 1087 2496 1802 +3 6005 2512 4432 +3 4456 528 7201 +3 3037 3410 1103 +3 4417 2907 641 +3 4097 877 4019 +3 632 329 4465 +3 877 1042 1055 +3 6879 3664 2212 +3 3872 3871 4466 +3 5454 887 3989 +3 863 5068 4688 +3 6643 1650 3964 +3 531 3246 2391 +3 533 531 2391 +3 533 4466 534 +3 534 531 533 +3 534 3526 531 +3 3315 4174 4473 +3 4472 4471 4473 +3 3655 2961 4477 +3 4412 535 4479 +3 2264 4480 1051 +3 1183 1184 4482 +3 887 2214 895 +3 96 3297 6729 +3 4961 1083 3532 +3 895 3989 887 +3 895 4095 5878 +3 50 6506 6402 +3 4490 1608 2025 +3 6747 577 2022 +3 540 4207 4492 +3 7347 5491 7495 +3 4492 543 540 +3 901 3978 6191 +3 4493 1921 7494 +3 4493 543 4492 +3 3010 3698 4495 +3 139 4503 1462 +3 2196 1522 4503 +3 2174 6408 4504 +3 3770 3769 4507 +3 4507 4506 4509 +3 194 2166 4513 +3 1047 5615 3108 +3 4516 1814 7300 +3 1814 5309 2827 +3 4245 441 4519 +3 4519 441 2398 +3 4519 548 4245 +3 973 549 4521 +3 4521 549 7214 +3 4523 5584 551 +3 2273 5584 4526 +3 2397 1557 2919 +3 137 552 3648 +3 6892 1664 7034 +3 3978 901 6687 +3 5148 6733 6398 +3 4529 1973 6892 +3 1668 554 2400 +3 2400 4530 1668 +3 555 554 5831 +3 554 555 3465 +3 3247 1996 855 +3 5831 3401 555 +3 4535 2544 7211 +3 2386 5694 5697 +3 676 558 2188 +3 3945 561 2188 +3 1400 6395 2654 +3 4537 560 561 +3 397 4538 2340 +3 4539 563 3555 +3 3665 4577 4540 +3 1860 1393 6392 +3 3048 3824 1284 +3 3247 909 5450 +3 6113 6981 3048 +3 406 4543 2339 +3 3955 3957 4544 +3 2695 2381 6384 +3 4555 567 4547 +3 4943 2497 5101 +3 4291 4290 4556 +3 3353 3799 4558 +3 3101 3100 4561 +3 2364 570 4561 +3 4561 570 572 +3 3864 571 4563 +3 2317 4563 570 +3 4563 572 570 +3 570 4564 2317 +3 3906 3905 798 +3 2460 774 4571 +3 3257 2531 4572 +3 4571 4570 4572 +3 4162 912 4828 +3 966 3151 4574 +3 2338 6382 5219 +3 912 4827 4826 +3 966 967 4575 +3 498 1077 4582 +3 2930 3758 4587 +3 7217 4026 4587 +3 7386 1410 3560 +3 294 6630 2117 +3 1380 6380 5877 +3 6376 6377 1406 +3 3109 6750 791 +3 3045 575 4592 +3 384 1820 372 +3 575 3286 2403 +3 4592 6546 1164 +3 4044 913 3823 +3 1081 6546 4592 +3 4597 4596 4598 +3 6366 6367 1758 +3 4600 5005 4603 +3 678 6359 7228 +3 5904 6563 6356 +3 6914 1590 1599 +3 2022 577 4604 +3 4606 583 3454 +3 581 3769 2404 +3 582 4606 2404 +3 4606 582 4604 +3 4604 583 4606 +3 3454 581 4606 +3 3823 913 3700 +3 586 4017 4609 +3 4609 589 586 +3 4608 587 4609 +3 2496 6844 2853 +3 587 4607 589 +3 589 4609 587 +3 3330 3418 4611 +3 4462 4546 4612 +3 4611 4610 4612 +3 1376 6351 5034 +3 1257 590 980 +3 980 4613 1257 +3 5381 4615 590 +3 1822 6345 3409 +3 5381 1841 7354 +3 1071 2864 4618 +3 2837 7061 4347 +3 3458 3457 4621 +3 5615 1047 5828 +3 932 3805 1176 +3 712 4532 2689 +3 4623 4369 4622 +3 4622 4621 4623 +3 1945 4628 475 +3 3913 7404 7224 +3 3805 932 2641 +3 1374 6342 1372 +3 4627 598 6386 +3 1945 475 4366 +3 2759 7058 4396 +3 598 2408 4628 +3 597 4629 2407 +3 7013 6257 4076 +3 597 4122 2408 +3 2408 598 4629 +3 4629 598 4627 +3 2407 3564 597 +3 3089 3177 4631 +3 803 2470 3868 +3 4637 599 278 +3 1148 2409 4818 +3 6332 6334 3182 +3 4818 650 1148 +3 1370 2686 2994 +3 4480 4479 4640 +3 2685 2 2152 +3 4796 600 4640 +3 4640 600 601 +3 601 600 4641 +3 6322 6323 2632 +3 3291 3279 4641 +3 6321 5178 2334 +3 6927 6318 740 +3 6314 6316 6333 +3 4641 1548 601 +3 3127 3156 4642 +3 6313 6312 3681 +3 1002 602 4647 +3 632 604 4653 +3 4653 604 487 +3 4474 3347 4655 +3 4608 605 4661 +3 605 3638 2410 +3 1353 6304 3951 +3 5758 949 3459 +3 6295 6298 5911 +3 4661 720 4608 +3 3229 606 303 +3 303 4662 3229 +3 4599 2619 7464 +3 4662 720 4694 +3 4307 607 4663 +3 6250 3996 3345 +3 731 608 4663 +3 4663 608 7177 +3 949 3803 323 +3 3168 3153 4664 +3 4664 731 4663 +3 3973 3972 4666 +3 414 6291 4927 +3 6286 6288 4554 +3 448 6283 3704 +3 5748 609 4667 +3 4667 609 2411 +3 298 611 4667 +3 4667 611 5748 +3 5987 1674 4671 +3 7376 1313 4675 +3 3165 958 3210 +3 3583 613 4677 +3 5211 3135 6350 +3 3210 958 4849 +3 1936 4678 7370 +3 4678 4677 4679 +3 1410 2397 5893 +3 2681 4532 712 +3 31 5600 4681 +3 4110 3674 4684 +3 7190 618 4684 +3 618 2294 2413 +3 4686 617 2294 +3 617 3726 2235 +3 1723 3220 5289 +3 4697 3012 5533 +3 3760 3759 358 +3 5555 7369 6272 +3 3760 988 3027 +3 3229 4689 619 +3 625 619 4689 +3 991 6890 709 +3 379 4692 2165 +3 625 624 4692 +3 4692 624 4428 +3 2440 716 624 +3 624 625 4689 +3 1718 2181 5244 +3 4695 937 1166 +3 4696 4695 4698 +3 3220 1723 5042 +3 4695 630 4698 +3 4698 630 1370 +3 1287 631 4699 +3 2001 7392 4699 +3 4815 1471 6507 +3 1337 6263 1195 +3 604 632 4465 +3 252 7453 2675 +3 604 4465 2390 +3 4408 3046 4706 +3 4706 4700 4707 +3 4034 6614 6259 +3 4710 1175 4033 +3 1175 6012 4712 +3 3653 3652 4715 +3 3431 3430 4716 +3 4718 4639 758 +3 4511 636 4719 +3 636 6671 1669 +3 6175 994 4942 +3 4942 994 4941 +3 1968 2046 3616 +3 6130 640 4721 +3 4721 640 1951 +3 6248 6249 7117 +3 2787 3323 4432 +3 2110 4724 1491 +3 4724 2110 641 +3 4418 4417 641 +3 6243 6244 6948 +3 1586 5535 1741 +3 641 2110 4725 +3 2046 997 3616 +3 645 725 4049 +3 5461 6357 6237 +3 725 645 4896 +3 262 7077 199 +3 3575 3404 725 +3 997 4487 677 +3 649 4734 3205 +3 4734 649 1318 +3 4735 3036 493 +3 1067 653 4737 +3 4737 653 655 +3 654 655 653 +3 655 654 1952 +3 1074 1591 6996 +3 6226 6227 3494 +3 653 4741 654 +3 3798 3311 4744 +3 1319 6224 5503 +3 5545 1004 3614 +3 4747 89 5120 +3 6217 6218 1313 +3 3471 4747 49 +3 4747 4752 89 +3 4748 2348 2423 +3 5876 2451 6860 +3 5160 2327 920 +3 2451 5876 1915 +3 623 4325 6893 +3 6212 6213 2124 +3 1004 6271 5129 +3 1267 661 6812 +3 6812 661 3583 +3 4769 3084 1196 +3 6763 6004 5991 +3 2721 663 4771 +3 4771 663 2334 +3 4501 1074 6996 +3 6093 5281 3314 +3 1591 1074 5952 +3 668 673 4773 +3 1869 1423 4346 +3 4773 673 63 +3 1079 3441 334 +3 673 668 2425 +3 4745 4744 4776 +3 1012 4955 4467 +3 956 4779 3558 +3 4263 3513 4781 +3 4957 1012 2611 +3 6378 1025 3588 +3 2209 680 4783 +3 4783 680 2340 +3 4926 1458 332 +3 6491 3567 4785 +3 3227 3512 4790 +3 4558 4556 4791 +3 4002 4000 4792 +3 684 683 4792 +3 2426 6991 1644 +3 682 683 684 +3 2662 926 1874 +3 682 4500 2426 +3 3588 1025 1969 +3 1303 6207 5879 +3 1034 5037 4928 +3 684 3225 682 +3 7176 686 374 +3 4198 4257 4798 +3 687 1029 2007 +3 1009 7030 6205 +3 6201 6202 2985 +3 7136 7130 7279 +3 1192 4800 1029 +3 688 4801 689 +3 688 3949 2430 +3 5037 1034 3124 +3 689 3948 520 +3 4381 3380 136 +3 690 4704 2841 +3 5070 4805 2733 +3 1296 6198 6735 +3 4805 5070 4679 +3 4810 1228 1812 +3 6735 6198 6194 +3 1228 817 4813 +3 6187 6188 1017 +3 3028 335 693 +3 692 4815 693 +3 5940 5942 6833 +3 1064 6184 2805 +3 692 3477 778 +3 693 4815 3028 +3 425 7324 2428 +3 693 3162 692 +3 6787 6180 1792 +3 5055 698 4816 +3 4816 698 5266 +3 2468 1037 291 +3 7387 3560 2684 +3 1770 650 4818 +3 3731 4054 4823 +3 1934 694 3218 +3 2216 1697 3912 +3 3912 701 2726 +3 4087 3441 3586 +3 4826 4828 912 +3 1042 3552 573 +3 2098 5110 4806 +3 1864 3150 3122 +3 2432 4829 705 +3 2049 5559 7426 +3 3552 1042 1092 +3 3552 7374 573 +3 1538 3670 4832 +3 4835 4313 801 +3 1538 165 4835 +3 6175 2708 518 +3 1391 1162 164 +3 4839 7349 376 +3 3568 4839 376 +3 4839 3568 4836 +3 4376 7088 5943 +3 3357 4290 4842 +3 883 710 4842 +3 1011 1014 1943 +3 1682 710 5194 +3 883 1451 4843 +3 711 3936 360 +3 3751 711 4844 +3 4846 4457 537 +3 4846 4845 4847 +3 1307 4848 5086 +3 715 4849 958 +3 4849 3391 2868 +3 5908 1615 4851 +3 4851 2437 5147 +3 4358 716 4856 +3 5257 719 4856 +3 4856 719 4358 +3 4858 720 4661 +3 721 4858 2410 +3 4858 721 931 +3 3861 3860 4860 +3 4304 4497 4862 +3 4862 4860 4863 +3 78 4083 3365 +3 1055 4019 877 +3 2693 6169 5704 +3 3262 5674 4864 +3 7522 5056 5515 +3 2442 4864 78 +3 1061 3541 3539 +3 4362 4361 5702 +3 5847 806 2077 +3 1061 1508 5622 +3 1082 5030 3963 +3 7051 1168 4873 +3 2181 1718 6235 +3 6161 6163 928 +3 4874 17 6094 +3 5459 1086 3428 +3 4471 4024 4877 +3 3311 3040 4878 +3 4102 4779 4879 +3 4878 4877 4879 +3 3044 1089 5464 +3 729 2813 730 +3 729 730 2899 +3 730 732 2899 +3 3428 1086 3113 +3 1092 3423 3949 +3 1089 3503 6583 +3 4872 735 4888 +3 735 3175 2448 +3 738 737 4888 +3 4888 737 4872 +3 4889 738 1336 +3 1739 144 6246 +3 4890 738 4888 +3 4384 497 4893 +3 3126 2307 5276 +3 741 2450 742 +3 742 1888 741 +3 1888 742 743 +3 743 2278 3597 +3 80 6860 2451 +3 5178 80 4897 +3 1367 124 4771 +3 6154 6155 7199 +3 80 742 4897 +3 4235 4394 4900 +3 3492 4018 4901 +3 4901 4900 4902 +3 4265 4903 5102 +3 6360 7244 6153 +3 6735 6194 6149 +3 4905 2235 2160 +3 3423 1092 1562 +3 4904 4903 4905 +3 1103 3410 3408 +3 1103 4458 3037 +3 6266 1236 4908 +3 1927 1350 2789 +3 13 6183 6145 +3 5987 2051 4910 +3 7041 1105 3392 +3 4913 745 4912 +3 6140 6141 786 +3 4912 745 763 +3 4913 4912 2452 +3 837 825 6137 +3 1167 2174 5861 +3 2490 177 242 +3 2174 1167 5508 +3 6131 6133 556 +3 4925 753 4923 +3 4923 753 4389 +3 3392 1105 5495 +3 6125 6126 6687 +3 754 4925 2111 +3 4923 755 5126 +3 2578 2663 2249 +3 3851 4848 4927 +3 5480 1574 2701 +3 4452 3598 4929 +3 2929 2161 4930 +3 2699 757 5328 +3 5328 757 4930 +3 6789 7007 1045 +3 6119 6120 2179 +3 3180 511 2006 +3 760 759 4933 +3 4933 2454 4931 +3 83 2453 4934 +3 4936 3097 2433 +3 4891 762 4936 +3 4936 762 766 +3 4912 763 4937 +3 4938 764 4937 +3 764 2452 4912 +3 3398 4938 553 +3 4937 766 762 +3 762 4938 4937 +3 2858 1102 5386 +3 1170 6015 1901 +3 3375 1118 3374 +3 5448 768 767 +3 767 768 2614 +3 3374 1118 5720 +3 3544 3312 4940 +3 5004 4491 6114 +3 4941 4940 4942 +3 1283 6111 3514 +3 2460 4943 5101 +3 1154 6902 2878 +3 6018 6636 2709 +3 6106 6107 5561 +3 5386 1102 1796 +3 3794 2872 6103 +3 4943 2460 3294 +3 6902 1154 6729 +3 5690 776 4946 +3 4946 776 986 +3 777 2462 4948 +3 5136 1278 2956 +3 779 4948 986 +3 4948 779 2367 +3 6401 780 4289 +3 4734 781 4951 +3 4951 781 4732 +3 6098 6099 929 +3 1682 1155 3357 +3 4951 784 4734 +3 7013 4460 4155 +3 4951 780 4952 +3 669 2929 757 +3 4957 1903 1704 +3 4957 4955 1012 +3 3249 3250 4959 +3 2644 785 4959 +3 785 2466 6999 +3 786 6141 6097 +3 1394 5559 217 +3 1246 789 4960 +3 4960 789 5709 +3 2840 6204 6090 +3 916 6087 5176 +3 3272 3961 4963 +3 3367 4152 4965 +3 4963 4962 4965 +3 1106 5179 5177 +3 3773 3777 4966 +3 4969 790 2092 +3 4175 5146 6842 +3 4970 795 3648 +3 1871 4971 700 +3 796 5671 2365 +3 3357 1155 4665 +3 1924 803 7203 +3 3332 3390 1895 +3 506 4973 2222 +3 4044 3823 4975 +3 2959 2444 4274 +3 4977 3941 136 +3 3396 4978 4977 +3 1177 3952 6739 +3 2470 803 3792 +3 4137 1997 3901 +3 3762 2779 6970 +3 5179 1106 3136 +3 805 4980 1413 +3 4980 805 3327 +3 1413 2945 805 +3 3759 3863 4981 +3 4981 1413 6417 +3 1265 6082 5306 +3 3030 5770 305 +3 806 5847 1259 +3 1091 6079 247 +3 4983 4986 3118 +3 4983 233 810 +3 6075 6077 3981 +3 1190 882 6567 +3 810 4986 4983 +3 1247 6071 4743 +3 4986 810 4916 +3 4610 4015 4987 +3 882 1190 2597 +3 5158 6254 1334 +3 811 4989 2498 +3 4989 811 2379 +3 393 813 4989 +3 813 1483 2498 +3 4546 4544 4990 +3 1243 6060 2348 +3 2967 3127 4994 +3 4992 4990 4994 +3 6312 3507 4998 +3 5001 3177 3305 +3 987 814 5001 +3 5001 814 5690 +3 987 1189 5002 +3 4813 817 2922 +3 5006 2479 2637 +3 4270 1196 3084 +3 1196 2946 4769 +3 3984 819 5008 +3 819 87 2481 +3 2481 5008 819 +3 5185 1201 3081 +3 6057 6058 1459 +3 5008 2481 7092 +3 3774 2481 5279 +3 87 5279 2481 +3 820 1070 5009 +3 729 4541 5011 +3 5011 820 5009 +3 5009 6539 5011 +3 3081 1201 6867 +3 2485 6817 160 +3 5917 5012 7476 +3 1300 1205 5183 +3 920 2327 5013 +3 4301 3266 5026 +3 5020 5019 5026 +3 5035 5033 1082 +3 823 4916 5036 +3 823 4584 4766 +3 823 5036 5041 +3 5041 4584 823 +3 4789 3984 5045 +3 499 826 5045 +3 5183 1205 1583 +3 4669 826 5050 +3 4459 1207 3058 +3 6046 6047 4113 +3 5051 827 3339 +3 5051 6462 149 +3 1732 265 1625 +3 3578 1442 5053 +3 1207 3057 352 +3 2187 5054 6533 +3 3206 830 5058 +3 2489 5058 830 +3 5058 832 3206 +3 3359 5062 2035 +3 5063 832 5058 +3 255 2384 4412 +3 4553 1195 5035 +3 5074 834 5341 +3 3283 3239 5075 +3 6782 1209 210 +3 5080 835 5077 +3 5077 5074 5080 +3 5836 5837 5082 +3 4876 4789 5083 +3 5084 2385 34 +3 1195 4342 3264 +3 2560 2432 5088 +3 3173 3495 4985 +3 2412 5233 4187 +3 1238 2138 782 +3 5090 4985 2594 +3 1209 3037 209 +3 6031 7057 7209 +3 5096 4945 4204 +3 1849 842 5096 +3 5096 842 2483 +3 845 843 5097 +3 845 5097 842 +3 6000 846 5155 +3 846 4092 5155 +3 3412 1259 810 +3 848 774 5101 +3 3832 1363 1110 +3 4073 3051 5104 +3 3073 6387 6030 +3 848 2498 5104 +3 2546 1251 3036 +3 2498 848 5105 +3 5105 848 5101 +3 5105 2497 2054 +3 3036 1251 3784 +3 1490 2216 6569 +3 6026 6028 1280 +3 2216 1490 3709 +3 1234 6023 5094 +3 5107 3836 5108 +3 2012 5843 888 +3 1259 5036 4916 +3 5109 2012 1532 +3 3752 6452 6014 +3 3574 850 5111 +3 850 3575 2499 +3 3152 125 1797 +3 5111 854 3574 +3 528 851 5112 +3 5112 854 2096 +3 2499 853 3054 +3 3054 5114 2499 +3 5114 854 5111 +3 3069 3053 5118 +3 2755 857 5119 +3 2933 1269 1944 +3 1227 2637 2479 +3 5120 5123 2190 +3 5120 857 5123 +3 1437 1285 3615 +3 859 2672 6242 +3 859 6459 5126 +3 6001 6002 1329 +3 858 5127 1324 +3 5127 858 2111 +3 5127 2111 6459 +3 3615 1285 1467 +3 5127 859 6242 +3 3655 1295 2961 +3 5233 2412 2487 +3 3429 6264 5130 +3 861 5131 1188 +3 5131 861 3468 +3 1188 3022 861 +3 865 862 5132 +3 5132 862 5128 +3 1295 2927 3076 +3 4421 1314 1321 +3 862 865 3073 +3 5133 4618 4322 +3 1072 867 5133 +3 5133 867 5132 +3 6976 5950 7484 +3 3495 3498 2860 +3 873 5151 6492 +3 1321 2953 4421 +3 3665 5155 4559 +3 3665 873 5155 +3 5164 5163 5167 +3 2108 1316 2910 +3 3523 2928 5169 +3 2370 874 5169 +3 5169 874 1122 +3 4549 6234 5993 +3 1316 2225 3327 +3 2346 3280 3505 +3 1222 6391 6019 +3 875 4647 1122 +3 5746 4652 5170 +3 4652 875 5170 +3 1318 2693 4734 +3 878 5172 621 +3 5172 878 4811 +3 4586 4585 5173 +3 5174 5173 5175 +3 3136 2928 5179 +3 5118 5117 5182 +3 1300 5183 786 +3 3173 4043 5184 +3 4845 322 5186 +3 2016 5189 4036 +3 196 7469 7399 +3 1125 4036 5190 +3 2208 879 161 +3 710 883 4843 +3 4843 5194 710 +3 2011 885 1717 +3 5196 885 2011 +3 2501 4353 5196 +3 1485 6559 2652 +3 4709 1233 1907 +3 4362 2502 5202 +3 2502 1801 2587 +3 5237 485 5067 +3 5208 5836 5082 +3 2693 1318 1289 +3 1157 888 5209 +3 888 6656 5210 +3 4920 5015 7377 +3 1627 4051 7521 +3 4286 892 5212 +3 892 3694 2503 +3 5212 2503 5213 +3 3077 1526 6573 +3 5212 90 4286 +3 2503 2198 5213 +3 1199 2198 19 +3 4448 4944 5217 +3 2463 894 5218 +3 5223 893 5220 +3 5220 893 6113 +3 6574 2641 975 +3 5220 894 5223 +3 4969 4968 5224 +3 6554 804 3718 +3 3718 5225 6554 +3 5025 4968 5481 +3 7364 6437 7427 +3 793 1360 5983 +3 5227 5226 5228 +3 2891 7019 1699 +3 5020 4215 5230 +3 5232 897 7325 +3 2412 6758 7043 +3 5233 897 4187 +3 899 3378 135 +3 3378 899 3506 +3 4530 5981 5980 +3 7019 3445 1699 +3 1326 5360 5958 +3 1300 4941 994 +3 3316 900 941 +3 7395 1328 5369 +3 900 3316 1383 +3 5369 1328 6022 +3 4102 4101 5239 +3 368 902 704 +3 5241 3589 2215 +3 906 1681 4463 +3 5970 5971 5584 +3 5240 5239 5241 +3 1343 5384 6390 +3 5245 907 1716 +3 2229 5968 1902 +3 1343 1796 1102 +3 2508 2938 5462 +3 5625 1365 5391 +3 5391 1365 1974 +3 1371 5648 502 +3 4949 275 812 +3 914 910 4281 +3 5648 1371 4777 +3 910 4348 5450 +3 2689 4532 4708 +3 1206 929 6099 +3 3312 1422 5407 +3 1422 5406 6137 +3 2508 4302 914 +3 4941 1300 4344 +3 5250 4518 3304 +3 5250 917 4518 +3 1204 5963 488 +3 919 918 5251 +3 5251 918 3992 +3 2509 2606 5251 +3 2606 2509 5353 +3 1203 5958 3569 +3 1724 920 5013 +3 2468 4967 4381 +3 1010 1426 5456 +3 5456 1426 5454 +3 5255 926 1226 +3 927 5256 7509 +3 927 3268 2513 +3 7509 5256 5258 +3 931 721 5257 +3 5257 4856 931 +3 5257 935 5092 +3 5258 933 2113 +3 5258 935 7509 +3 7276 1428 5458 +3 936 3569 2529 +3 5262 1179 5921 +3 2759 941 3765 +3 4132 4919 5273 +3 5458 1428 2268 +3 4028 1919 942 +3 1919 4306 942 +3 1668 3360 5277 +3 663 6516 1473 +3 1105 5540 539 +3 4833 946 5282 +3 5283 5284 3867 +3 5283 946 5284 +3 3599 4788 727 +3 7386 3148 2740 +3 5474 380 2186 +3 1435 5497 5496 +3 1501 5609 5776 +3 4328 6412 5954 +3 1039 2740 3148 +3 4841 6311 1132 +3 948 5832 1136 +3 3800 3190 5291 +3 5292 5291 5293 +3 4675 4676 5295 +3 4233 4809 5297 +3 5299 5297 5300 +3 5301 985 7138 +3 1437 3615 504 +3 5740 1453 2292 +3 460 5303 2417 +3 979 951 5304 +3 6004 4220 603 +3 7151 804 6554 +3 351 951 1695 +3 979 953 5306 +3 7402 1760 1212 +3 2292 1453 1481 +3 5306 953 6615 +3 1968 5308 3805 +3 569 954 5319 +3 515 5941 463 +3 7402 2778 1760 +3 5319 954 2088 +3 3531 3475 5310 +3 5874 961 5310 +3 1453 1114 2932 +3 5313 957 3358 +3 1481 146 2281 +3 5313 3053 957 +3 3188 4847 5315 +3 2146 3557 2347 +3 1191 5933 6065 +3 2146 569 5319 +3 5313 961 5321 +3 7355 962 5322 +3 962 2918 3743 +3 1187 5931 2297 +3 2848 964 5323 +3 5323 964 1842 +3 5324 565 4449 +3 5494 5532 2523 +3 3892 3358 5326 +3 5328 965 5329 +3 5329 965 5326 +3 5329 5326 4496 +3 2977 3657 5332 +3 3928 1223 5332 +3 967 966 5333 +3 1482 2558 2127 +3 5333 966 4574 +3 6001 967 5333 +3 5334 1273 7269 +3 5185 5184 5337 +3 1307 4849 715 +3 3491 3490 5339 +3 4975 4973 5340 +3 5339 5337 5340 +3 4477 968 5345 +3 1482 1896 1036 +3 5345 969 4477 +3 3917 3915 5347 +3 969 1364 5347 +3 1185 2614 768 +3 4138 3169 5348 +3 5348 3169 1364 +3 5348 969 5345 +3 3259 3260 5349 +3 5350 1388 4298 +3 5351 4243 2298 +3 4833 6769 1178 +3 971 5354 473 +3 5354 971 5351 +3 1392 5266 5355 +3 549 973 2253 +3 3806 4775 5359 +3 1993 2981 4814 +3 5261 974 5361 +3 974 5260 2529 +3 4803 1484 2065 +3 5361 5360 1326 +3 975 5359 977 +3 977 5361 975 +3 5361 977 5261 +3 4865 3645 5363 +3 4893 2593 5365 +3 5365 5363 5366 +3 4967 2468 1985 +3 1432 5915 2416 +3 1272 6558 5372 +3 1272 929 5373 +3 5374 1099 3445 +3 2285 5149 6846 +3 4849 1307 3391 +3 3579 3580 5377 +3 1901 6015 3579 +3 4005 4119 1346 +3 5912 5913 4581 +3 3580 3392 5378 +3 3692 1321 4418 +3 5908 628 3722 +3 1410 7386 1557 +3 953 979 5304 +3 953 5304 2516 +3 4615 980 590 +3 1493 2105 4595 +3 1354 982 6307 +3 435 2798 1384 +3 3901 1997 2163 +3 5901 5902 799 +3 4064 3477 5382 +3 7200 474 3647 +3 5622 3541 1061 +3 4238 3856 5386 +3 3166 5192 5390 +3 2766 1357 1511 +3 2613 2764 5017 +3 527 1508 5626 +3 1974 1975 5391 +3 5394 1974 6799 +3 6019 1019 1222 +3 986 776 779 +3 776 5395 779 +3 814 987 5002 +3 814 5002 2475 +3 5398 5395 5399 +3 5625 3342 4228 +3 5400 1552 989 +3 5896 5897 3215 +3 5494 5856 5873 +3 989 1552 1211 +3 736 4182 7148 +3 5400 989 2581 +3 1510 5622 527 +3 990 984 4305 +3 990 4388 2535 +3 5889 5890 6469 +3 3517 3285 1576 +3 6133 1514 5635 +3 5635 1514 5634 +3 5886 5860 6661 +3 1516 5091 4866 +3 1275 6729 2885 +3 3629 3615 1467 +3 3614 3187 5402 +3 5091 1516 2316 +3 4500 4499 5404 +3 2954 3957 5405 +3 3278 3312 5407 +3 2538 6553 2305 +3 3368 4291 5410 +3 5873 5803 5494 +3 3799 3798 5411 +3 835 992 5413 +3 5413 992 5066 +3 3960 3800 5415 +3 5268 3493 5417 +3 5871 1174 6247 +3 5416 5415 5417 +3 5419 4795 5420 +3 4795 5419 5422 +3 2911 2119 5423 +3 1532 1157 2323 +3 4659 4658 5435 +3 2736 5868 3903 +3 4619 3886 5428 +3 6394 6273 3162 +3 4051 513 3297 +3 5429 6567 635 +3 4140 6771 5999 +3 2070 3703 1512 +3 996 4715 2541 +3 1157 1532 2012 +3 1126 4716 996 +3 2542 1539 1987 +3 662 1539 7497 +3 5864 5866 1537 +3 4418 1321 1314 +3 5949 1000 6262 +3 1000 1236 6262 +3 18 669 1685 +3 4499 3016 5438 +3 2967 2954 5439 +3 1795 1003 5441 +3 2752 5854 35 +3 5441 1003 1032 +3 7429 1550 5789 +3 1550 7057 7033 +3 3828 3023 5445 +3 5444 5441 5445 +3 5446 5263 2257 +3 7521 4051 96 +3 5734 1005 5446 +3 5446 1005 1008 +3 3029 2606 3325 +3 5447 5448 6843 +3 6247 4670 5871 +3 5873 2210 5803 +3 1006 5153 2081 +3 767 1007 2459 +3 2459 5448 767 +3 5447 1008 1005 +3 1005 5448 5447 +3 3970 3969 5452 +3 5452 5453 7322 +3 1159 5843 2012 +3 3989 4126 2469 +3 4310 4309 5457 +3 5838 5839 773 +3 2611 4954 4957 +3 5456 5454 5457 +3 1970 3732 5389 +3 5873 2610 2210 +3 3649 1013 218 +3 5828 5830 4484 +3 1553 7420 129 +3 2963 5826 678 +3 3428 3426 218 +3 3067 5460 4033 +3 717 1649 5460 +3 3067 1559 5460 +3 1554 66 818 +3 2273 5463 2275 +3 3703 2070 2206 +3 1089 3044 2895 +3 4141 4140 5465 +3 5465 2895 3044 +3 5187 3592 5468 +3 1015 5470 2615 +3 1015 2089 4690 +3 3131 1016 5471 +3 3219 5822 7333 +3 66 1554 5793 +3 5471 3436 5473 +3 2788 1450 5474 +3 6043 7191 5817 +3 4346 7032 5475 +3 4791 1325 4790 +3 4790 1325 2279 +3 124 1367 4769 +3 1222 1019 5482 +3 5482 3473 3846 +3 1020 5486 1604 +3 5486 1020 1952 +3 1424 5712 1130 +3 1023 1022 5488 +3 2545 3933 5489 +3 5489 1022 5490 +3 1022 1023 5490 +3 5296 5295 5493 +3 5496 5495 1435 +3 387 1024 503 +3 4525 2704 2947 +3 4153 4954 5506 +3 3816 3095 5510 +3 6309 5028 7387 +3 1027 1026 3909 +3 3909 5512 1027 +3 4278 1028 2549 +3 2549 1028 2620 +3 1560 1233 204 +3 2549 5512 4278 +3 5514 1214 3385 +3 5512 2548 5514 +3 3881 5300 5516 +3 3413 2992 5517 +3 4103 4105 5520 +3 1030 5522 2550 +3 1150 2600 1261 +3 5522 1030 5519 +3 5519 1213 5522 +3 5500 7023 180 +3 900 1031 941 +3 3840 1032 1003 +3 1003 5528 3840 +3 3942 3644 5530 +3 6350 2212 5211 +3 5538 5537 256 +3 1233 1560 1907 +3 5304 351 3897 +3 1036 2558 1482 +3 2599 5505 4772 +3 93 2556 5548 +3 1309 1563 1762 +3 1367 2450 747 +3 4172 3828 5550 +3 4054 4472 5551 +3 2312 1040 5554 +3 1040 1242 871 +3 1762 1563 1851 +3 5551 5550 5554 +3 1041 5557 5588 +3 1456 1411 4972 +3 7133 2229 7131 +3 4136 2065 1484 +3 2143 1043 5560 +3 1043 1276 1555 +3 418 3212 1489 +3 2223 1044 2561 +3 6100 2223 1276 +3 5564 1046 5565 +3 4 6938 229 +3 5190 5189 5565 +3 5881 2269 69 +3 2269 5881 541 +3 5433 6052 594 +3 5566 1048 3888 +3 324 5258 5256 +3 3888 3887 2562 +3 1049 1048 5566 +3 1411 4911 1336 +3 4337 3368 5567 +3 85 3002 702 +3 5567 1049 822 +3 5569 1049 5566 +3 5183 1583 5867 +3 5572 898 4205 +3 5867 1583 5866 +3 5574 2512 6872 +3 1053 2787 5574 +3 2787 1053 5575 +3 3692 1402 5577 +3 5142 5141 5578 +3 5439 5438 5581 +3 3522 3285 3517 +3 2856 5807 1778 +3 5801 5802 5948 +3 5580 5579 5581 +3 5582 5141 7262 +3 1587 1632 3818 +3 364 1054 5592 +3 95 5592 2568 +3 5592 5595 2211 +3 5132 867 865 +3 90 2504 5594 +3 5594 1068 1542 +3 95 2565 5595 +3 5059 1057 5595 +3 1057 1062 5650 +3 3160 6839 5798 +3 1632 1587 2135 +3 5596 5598 5679 +3 5596 1062 1057 +3 1057 5598 5596 +3 1063 5573 5601 +3 5573 1063 5603 +3 5603 1063 1843 +3 2572 5205 5272 +3 3169 3882 5605 +3 4519 4768 5157 +3 4481 3460 5608 +3 11 1065 5608 +3 1065 5609 1136 +3 5258 324 933 +3 5609 1066 5776 +3 4658 4907 5611 +3 5614 1542 6698 +3 4232 2700 769 +3 6490 6543 5794 +3 1068 865 867 +3 3872 3102 5616 +3 5618 2163 1997 +3 3940 3108 5618 +3 5303 5302 5621 +3 3541 5622 526 +3 1882 1350 1933 +3 5391 3342 5625 +3 507 527 5626 +3 477 5792 3844 +3 5009 1070 5628 +3 4526 4523 5631 +3 1514 1071 5195 +3 5634 5631 7358 +3 4416 4415 5636 +3 7033 5789 1550 +3 3440 3438 5638 +3 1073 5639 4949 +3 7462 1144 5788 +3 1073 1390 4758 +3 2179 6120 5782 +3 3143 424 1390 +3 6387 185 1390 +3 5778 5779 4964 +3 188 6122 5777 +3 4696 3049 5640 +3 5773 5774 4750 +3 2592 3129 1524 +3 138 1613 4788 +3 1916 5316 7520 +3 4788 1613 5932 +3 2029 2681 6609 +3 4078 5730 5643 +3 1233 4709 7498 +3 5585 7180 7181 +3 1076 536 3035 +3 1411 1456 4906 +3 5645 1075 5644 +3 5644 1075 2230 +3 4600 3300 5645 +3 5644 4777 5645 +3 1129 5768 1763 +3 536 1877 502 +3 4777 5644 5648 +3 6770 1077 5649 +3 3716 1965 2577 +3 2577 5658 3716 +3 4040 1456 6877 +3 6404 4533 4573 +3 1397 2654 6395 +3 1153 1462 4503 +3 1470 7251 1464 +3 4635 1080 5658 +3 5658 1080 1992 +3 1620 6880 7393 +3 5659 1081 5062 +3 6880 1620 1942 +3 2131 1626 1609 +3 5029 1494 5660 +3 5755 5758 3459 +3 1609 1626 70 +3 20 1641 1600 +3 5665 5664 5667 +3 2852 1879 5670 +3 4866 1084 5670 +3 5670 1084 1937 +3 1085 1937 1084 +3 7049 1085 1543 +3 4020 2696 1939 +3 1600 1641 1598 +3 6801 6803 860 +3 1462 3516 139 +3 1939 2696 447 +3 2639 2439 2474 +3 1645 2604 7286 +3 1653 6262 1236 +3 6262 1653 5198 +3 4954 2611 5506 +3 6713 1665 1549 +3 3901 2163 3563 +3 1113 6556 2968 +3 5680 808 915 +3 2945 4564 5685 +3 5682 5681 5685 +3 2968 6461 1113 +3 1096 1094 5400 +3 1237 1096 5686 +3 3437 1097 478 +3 478 5691 3437 +3 1237 1098 5691 +3 5691 1098 884 +3 4274 2389 3509 +3 3754 5697 4210 +3 5753 670 6975 +3 2986 5669 5699 +3 3184 3639 5702 +3 5702 1101 2582 +3 1101 4335 4765 +3 4440 2616 7224 +3 5376 2582 1101 +3 6399 7223 5750 +3 2582 5376 4840 +3 789 5412 5709 +3 3411 5665 5711 +3 5749 5748 611 +3 5714 5713 5716 +3 5676 5717 1018 +3 5862 1109 5718 +3 5743 5745 122 +3 5718 1109 2094 +3 6024 1469 2801 +3 5177 3374 5720 +3 4976 3468 5722 +3 5725 5723 494 +3 4075 4074 5726 +3 3404 3458 5728 +3 4865 4869 5729 +3 5728 5726 5729 +3 1665 3264 6714 +3 5796 2213 5732 +3 1990 6888 7036 +3 5829 6635 5742 +3 1512 3185 2070 +3 3907 3908 5736 +3 4429 5519 5737 +3 2810 1112 1867 +3 1867 5738 2810 +3 3043 5805 5739 +3 4006 1115 5741 +3 6914 4562 289 +3 5740 1116 5741 +3 1116 5739 1117 +3 1869 5938 2514 +3 1117 5741 1116 +3 1116 5740 2292 +3 5741 1117 4006 +3 5177 5742 1106 +3 2492 2782 5044 +3 5044 6150 5371 +3 2536 5371 6150 +3 6707 1670 1545 +3 344 5743 3859 +3 3132 1121 7470 +3 122 5745 2195 +3 5170 1122 874 +3 874 5746 5170 +3 5745 5743 5746 +3 2586 5749 5498 +3 1112 2810 1871 +3 3013 3014 4895 +3 3256 1104 3294 +3 2730 6448 5736 +3 4036 1125 5755 +3 2473 6295 5733 +3 949 5758 1816 +3 1126 996 2541 +3 5759 998 1126 +3 5758 5755 5759 +3 1128 1127 5764 +3 1545 1670 6706 +3 6395 1128 5764 +3 2654 1397 1705 +3 5252 5202 2502 +3 5766 1129 4536 +3 5768 1129 5961 +3 5769 1129 5766 +3 1244 1130 5712 +3 1130 2589 1424 +3 3185 1512 6964 +3 204 7498 5770 +3 5496 1133 5771 +3 5771 1133 5607 +3 1135 5771 6822 +3 5771 1135 5496 +3 5580 3975 5773 +3 3610 5223 5775 +3 5774 5773 5775 +3 1673 6013 6362 +3 1573 1577 5777 +3 392 1138 5779 +3 4537 3005 5780 +3 5779 5778 5780 +3 178 51 248 +3 2957 3538 5786 +3 4371 1141 5788 +3 5140 5788 1141 +3 1144 5786 1145 +3 1145 5788 1144 +3 5788 1145 4371 +3 3020 1146 998 +3 998 5791 3020 +3 5791 1147 477 +3 3844 4947 477 +3 5726 5728 3107 +3 5792 1147 3198 +3 65 66 5793 +3 5793 1147 5791 +3 494 5723 5287 +3 2435 6821 5720 +3 6024 7079 4635 +3 5794 2409 1148 +3 2584 1567 5732 +3 4805 2431 2733 +3 2733 2431 765 +3 4258 4257 5801 +3 4173 3604 5802 +3 6250 3345 6738 +3 3710 3023 5806 +3 5802 5801 5806 +3 6196 4591 1485 +3 1851 7221 7223 +3 6013 1673 6014 +3 1151 1150 5810 +3 2601 1167 5861 +3 4656 3767 3114 +3 2185 2601 5813 +3 5861 1150 5813 +3 1150 1151 5813 +3 6577 1678 314 +3 4643 4642 5817 +3 6574 1678 2046 +3 6534 1679 4270 +3 1153 1522 5825 +3 72 6327 5717 +3 2963 1152 5826 +3 5826 1152 5688 +3 5825 1152 2963 +3 1679 5246 1196 +3 1957 7402 1212 +3 3366 3367 5833 +3 5830 5828 2650 +3 5713 5714 4352 +3 2983 4871 2090 +3 2604 6802 1585 +3 6525 1682 5879 +3 4129 4953 1275 +3 1504 1505 5838 +3 245 1007 773 +3 5254 922 5841 +3 5841 922 6741 +3 5839 5838 5841 +3 3630 1156 5842 +3 3518 6489 5711 +3 1212 7255 7378 +3 5879 3588 6525 +3 888 1157 2012 +3 1163 2375 5845 +3 5843 1159 5845 +3 1159 5842 1163 +3 1163 5845 1159 +3 5251 2606 5846 +3 2606 3029 5846 +3 5263 1164 5849 +3 18 1685 7464 +3 5849 1495 5263 +3 1495 5467 5850 +3 5419 1165 5851 +3 2522 5718 2094 +3 5848 2539 5851 +3 5852 5848 5851 +3 7082 2609 5853 +3 5853 105 2804 +3 5126 755 5855 +3 2523 5856 5494 +3 2163 4260 4098 +3 2269 5057 6584 +3 1819 5043 5860 +3 7464 1685 2699 +3 1168 5864 2343 +3 5866 5864 5867 +3 3871 3903 5868 +3 2474 6196 5152 +3 4333 5662 6518 +3 3641 3526 5870 +3 7150 1541 1721 +3 3321 1124 2627 +3 936 3778 5880 +3 2186 5288 5474 +3 5288 2186 6647 +3 5883 1171 5887 +3 5887 1171 6590 +3 4987 5307 5889 +3 4464 4462 5890 +3 5890 5889 5891 +3 5735 3745 5897 +3 5897 5896 5898 +3 1101 5702 3639 +3 1172 5899 2612 +3 5899 1172 5065 +3 5697 3754 2386 +3 2612 4226 1172 +3 5268 5292 5902 +3 5902 5901 5905 +3 4851 5147 628 +3 2839 5696 5362 +3 3436 5471 5909 +3 1699 3445 5693 +3 2581 3707 1238 +3 5681 5682 5392 +3 2927 4522 5912 +3 4415 5226 5913 +3 5357 3440 5914 +3 5913 5912 5914 +3 1175 5915 5916 +3 1059 4041 2628 +3 5915 1175 4710 +3 5275 890 5677 +3 4306 7278 5676 +3 5007 5917 7476 +3 5917 231 7053 +3 1685 669 757 +3 5284 1178 5920 +3 5920 1178 1570 +3 6371 1693 6369 +3 5672 4518 917 +3 1570 4898 5920 +3 1084 4866 5091 +3 1182 5921 2461 +3 5921 1182 1185 +3 1184 1183 5923 +3 5925 1184 5923 +3 5923 1185 1182 +3 5664 5665 4068 +3 6813 972 3702 +3 1182 5925 5923 +3 1693 1820 384 +3 2677 1434 5929 +3 4386 1186 5930 +3 1186 4387 2624 +3 5930 1187 4386 +3 4013 4934 5931 +3 5433 3479 6052 +3 6366 1695 5540 +3 5931 1187 1613 +3 5932 4978 727 +3 5677 6712 5275 +3 5930 5932 1613 +3 1191 1188 5131 +3 5002 1189 5933 +3 5933 1191 6300 +3 4381 5935 3380 +3 5937 2466 785 +3 5937 1246 4960 +3 2429 224 5939 +3 1246 1248 5939 +3 3520 5901 5941 +3 7220 5661 2050 +3 5293 4392 5945 +3 5945 5944 463 +3 5947 5946 5963 +3 1695 951 539 +3 5951 1197 5947 +3 5947 1197 1681 +3 2212 5892 1060 +3 4012 4065 6364 +3 1198 432 5951 +3 4012 1733 726 +3 1494 5029 2747 +3 6501 1739 6159 +3 5880 1202 5957 +3 5957 1202 222 +3 5957 1203 5880 +3 5958 1203 6048 +3 5959 1203 5957 +3 2579 2628 5962 +3 5962 1204 488 +3 5946 5093 5963 +3 5963 1204 4811 +3 6159 1739 6210 +3 6632 4568 5656 +3 621 5172 5964 +3 5964 1204 5962 +3 5965 5033 659 +3 1206 5965 3612 +3 5965 1206 1274 +3 1541 462 1088 +3 1741 2672 6240 +3 2143 1211 1274 +3 466 1750 6176 +3 6435 1591 7 +3 5502 5506 5968 +3 5522 1213 1900 +3 2953 882 1436 +3 5971 1214 551 +3 5971 5970 5973 +3 3465 3466 5974 +3 3424 4530 5980 +3 6176 1750 451 +3 5983 4733 793 +3 4767 5954 5986 +3 1218 1217 5988 +3 1218 5988 6045 +3 5990 4057 1222 +3 3335 3623 5993 +3 5376 5427 4840 +3 3822 4962 5995 +3 950 3307 5998 +3 5333 1223 6001 +3 4089 4874 6002 +3 470 4357 2374 +3 470 6003 472 +3 6002 6001 6003 +3 3204 1250 6138 +3 1226 926 1249 +3 1249 5254 1226 +3 1570 2635 1230 +3 1230 1227 1570 +3 6009 1229 1812 +3 4813 6009 1812 +3 6009 2637 1230 +3 97 2635 794 +3 6518 4037 4333 +3 5076 3435 6014 +3 6199 1783 1631 +3 1783 2656 3157 +3 1234 4286 1231 +3 4332 4331 6023 +3 1234 1232 6023 +3 6051 6470 2570 +3 6023 1232 7475 +3 1232 1234 1231 +3 2805 5640 3049 +3 1231 6025 1232 +3 350 1235 3482 +3 4908 1236 6029 +3 6029 1236 1000 +3 6028 6026 6029 +3 6020 862 6030 +3 4055 5656 6031 +3 4440 4857 4649 +3 6036 1677 6762 +3 1255 2640 1238 +3 2138 1238 3707 +3 1098 1237 5686 +3 5686 6037 1098 +3 6040 6675 6236 +3 1385 1429 6041 +3 1853 6685 1710 +3 596 6042 7454 +3 1385 1387 6042 +3 6619 6852 5638 +3 1789 6180 2552 +3 1240 1357 2766 +3 6045 3510 1218 +3 6045 2633 7436 +3 5655 4113 6047 +3 6047 6046 7336 +3 1241 6050 4754 +3 1241 3713 3690 +3 6180 1789 1792 +3 1040 2312 6055 +3 1242 6055 6455 +3 6055 1242 1040 +3 3721 3922 6057 +3 3547 3239 6059 +3 6058 6057 2971 +3 3406 5119 6060 +3 6060 1243 6061 +3 5631 5634 2011 +3 5629 1412 1766 +3 5556 5557 6061 +3 6061 5267 6060 +3 43 6062 1245 +3 1351 1245 6062 +3 1351 3171 6066 +3 1247 4309 6068 +3 1247 2644 6071 +3 1248 1246 5937 +3 5937 6072 1248 +3 2644 1247 6072 +3 6072 1247 6068 +3 1248 6072 6068 +3 1249 6073 1250 +3 4871 2983 2093 +3 1250 6073 6209 +3 1591 5952 6736 +3 1792 6182 4741 +3 4801 6074 690 +3 1304 1305 6074 +3 282 1254 3437 +3 282 3437 2240 +3 2640 1255 413 +3 6077 6075 6078 +3 4613 1256 6080 +3 1256 137 2647 +3 1265 1257 6080 +3 6080 1257 4613 +3 485 3427 5627 +3 5497 4419 5306 +3 1265 1260 6082 +3 6082 1260 3348 +3 5827 5607 3348 +3 5424 889 703 +3 1260 1265 6080 +3 7215 5695 4917 +3 1260 6080 2647 +3 5629 3427 1412 +3 5197 3194 6089 +3 87 819 6090 +3 1266 1271 6092 +3 1266 4852 4582 +3 4090 3567 6092 +3 1271 17 6092 +3 17 1271 6094 +3 4349 4345 6097 +3 526 1510 4228 +3 929 1272 6098 +3 6098 1272 5372 +3 8 6564 5620 +3 1274 1206 2143 +3 1206 6099 2143 +3 6182 1792 1789 +3 3940 1047 3108 +3 1043 6100 1276 +3 6099 6098 6100 +3 6101 4783 6667 +3 6101 7267 2956 +3 2956 2084 6101 +3 2648 2084 1279 +3 5121 1279 2084 +3 1279 2245 2648 +3 1102 6136 1343 +3 4819 3839 6106 +3 4126 4125 6107 +3 3542 4310 6108 +3 1072 6698 2575 +3 6107 6106 6108 +3 1796 3050 4238 +3 1281 3927 6112 +3 1281 1283 3235 +3 2685 5611 2 +3 1065 11 7128 +3 5682 3252 6111 +3 6111 1283 2171 +3 3348 6083 5827 +3 6754 1282 6112 +3 6112 1283 1281 +3 6113 1284 5220 +3 6088 6426 4066 +3 6113 2114 6981 +3 6114 439 4243 +3 6114 2114 439 +3 6116 1585 6802 +3 5860 5886 6119 +3 5783 5782 6120 +3 5776 5777 6122 +3 6120 6119 6122 +3 6125 3980 247 +3 3536 4208 6126 +3 3952 3953 6128 +3 6126 6125 4799 +3 4902 3485 6129 +3 5635 4409 6133 +3 6133 6131 6135 +3 6136 5384 1343 +3 6137 5407 1422 +3 825 2890 6139 +3 5183 5867 6140 +3 6095 6097 6141 +3 4872 6142 7051 +3 6141 6140 6142 +3 5487 5486 6145 +3 542 4302 1547 +3 5039 4766 1547 +3 1956 3913 2831 +3 4707 3973 6149 +3 3725 4407 6151 +3 2525 2456 6426 +3 6155 6154 6157 +3 813 393 5956 +3 1063 5601 2015 +3 2728 1286 6160 +3 6161 1438 6457 +3 6054 3644 6167 +3 6163 6161 6167 +3 3273 1288 6169 +3 2693 1289 6169 +3 4958 6588 5600 +3 1289 6782 210 +3 3300 1290 6170 +3 1290 3408 6170 +3 6170 1380 3300 +3 518 1291 4437 +3 4437 6174 518 +3 4942 4397 6175 +3 466 6176 3981 +3 451 6174 6176 +3 3809 3810 6177 +3 3982 567 6178 +3 2655 1001 6178 +3 4239 2655 1292 +3 6180 4238 723 +3 4741 3673 1792 +3 6144 6145 6183 +3 1789 6183 6182 +3 5641 5640 6184 +3 6846 1805 1899 +3 394 2651 6186 +3 3994 6185 2805 +3 3144 5940 6832 +3 4070 4198 6188 +3 4631 4946 6190 +3 6188 6187 6190 +3 6151 6149 6194 +3 609 39 6195 +3 1297 1296 6195 +3 6193 6194 6198 +3 1297 6195 2656 +3 1783 6199 2656 +3 3260 4416 6202 +3 6202 6201 6203 +3 6089 6090 6204 +3 783 1210 435 +3 2565 3363 5059 +3 3346 2331 7508 +3 4876 5019 6205 +3 4566 5881 5694 +3 1298 6206 1299 +3 6206 1298 5193 +3 7243 4635 6982 +3 1303 1299 6206 +3 1299 5194 1298 +3 1303 1302 6207 +3 6207 1302 5928 +3 1302 1303 6208 +3 6208 1303 6206 +3 1305 1304 6209 +3 6209 1304 1250 +3 1875 1305 6209 +3 783 435 7163 +3 2843 5587 1156 +3 1805 1891 2314 +3 4704 1875 1310 +3 6162 1812 1229 +3 1306 1310 2112 +3 6213 6212 6216 +3 6819 1311 1594 +3 1311 4071 2327 +3 3797 1602 4570 +3 1812 1228 4813 +3 6217 6219 421 +3 6647 3714 256 +3 6335 4249 824 +3 6220 98 5525 +3 6221 5525 98 +3 6442 2032 6221 +3 6223 1319 5503 +3 2544 2534 7211 +3 445 5205 6224 +3 1319 2055 6224 +3 1319 6225 5290 +3 6225 1319 6223 +3 1320 7511 7517 +3 6222 6171 3038 +3 3115 4317 6227 +3 5579 5580 4750 +3 6227 6226 6229 +3 4001 6124 6232 +3 3854 6779 5578 +3 834 1322 2668 +3 6067 7042 1894 +3 5995 5993 6234 +3 1741 3092 6239 +3 2753 1586 6240 +3 1741 6240 1586 +3 2669 1324 6242 +3 6242 1324 5127 +3 1053 5574 2250 +3 6335 1818 6334 +3 6239 2672 1741 +3 6239 6242 2672 +3 6244 6243 6245 +3 5716 3524 5099 +3 1048 1820 6370 +3 1327 3207 3533 +3 2673 4505 1327 +3 3654 3915 6248 +3 3698 3699 6249 +3 6249 6248 6251 +3 1041 6252 4277 +3 1049 5567 372 +3 6252 1340 459 +3 1820 1693 365 +3 1331 6254 5231 +3 6254 1331 1334 +3 6256 1333 6255 +3 6255 1333 5753 +3 4807 3080 1333 +3 6255 1334 6256 +3 6256 1334 1331 +3 5362 1515 2839 +3 4713 3918 6260 +3 99 1335 2710 +3 6470 3284 648 +3 1043 2143 6099 +3 1341 1337 6261 +3 6261 1337 1846 +3 6263 4342 1195 +3 1341 2679 6263 +3 6253 1340 6269 +3 6269 1340 6252 +3 2679 1341 6269 +3 4570 1602 3906 +3 1341 6261 2678 +3 5267 6061 5557 +3 2678 6253 6269 +3 6272 3397 1885 +3 1345 2576 6274 +3 2681 1976 6274 +3 1826 6376 4450 +3 5550 5551 5216 +3 1610 3696 4999 +3 1347 976 2234 +3 3778 1348 6278 +3 6280 1349 6278 +3 6549 3939 7441 +3 6278 1349 3778 +3 2559 3065 1439 +3 6636 1253 7318 +3 3171 1351 6280 +3 6280 1351 6062 +3 6278 1347 6280 +3 4042 5090 6281 +3 3241 3704 6283 +3 1174 2570 5863 +3 6285 1352 3011 +3 6281 6285 2168 +3 3546 3411 6286 +3 5076 5075 6288 +3 6288 6286 6290 +3 4929 4927 6291 +3 5077 4784 6292 +3 5735 5733 6295 +3 3623 3622 6298 +3 4233 6237 6299 +3 5540 7041 1698 +3 6298 6295 6299 +3 1353 6307 2266 +3 3479 6976 7484 +3 6307 1353 6303 +3 6307 6303 7202 +3 6308 1359 2683 +3 2684 1700 5003 +3 1700 2684 5893 +3 2684 6309 7387 +3 1359 6309 5003 +3 3663 2596 6313 +3 3531 4046 6314 +3 5357 5358 6316 +3 3809 3782 6317 +3 6316 6314 6317 +3 256 3714 5538 +3 6319 5697 5694 +3 6322 6292 770 +3 2632 1360 1322 +3 715 1361 6324 +3 6324 6323 414 +3 6028 1362 6325 +3 1362 5611 2685 +3 6325 2147 6028 +3 6376 1826 6378 +3 2602 5568 7305 +3 7221 1851 1563 +3 1370 2994 4698 +3 5532 1567 6977 +3 1368 6330 1369 +3 461 2686 6330 +3 6331 1369 6330 +3 1762 1851 2122 +3 1369 4597 1368 +3 1014 1011 2602 +3 1392 1395 6331 +3 6330 1370 6331 +3 4164 3266 3182 +3 593 6335 401 +3 6335 6334 724 +3 6695 5528 1003 +3 803 3868 5298 +3 5526 5098 4580 +3 7372 5070 7368 +3 1853 1073 4949 +3 1760 2778 2988 +3 1073 1853 6387 +3 3284 6470 1802 +3 6342 4296 116 +3 1372 2213 1374 +3 1373 6343 1375 +3 5387 1860 5384 +3 6342 1374 6343 +3 5384 1860 6390 +3 1877 1076 4488 +3 6343 1374 6340 +3 6340 1375 6343 +3 1375 2946 1373 +3 1801 2502 5996 +3 1030 5520 4105 +3 6348 7304 1822 +3 1376 1913 6349 +3 4538 6351 563 +3 6351 1376 2527 +3 4130 4131 6352 +3 1076 1877 536 +3 1733 6353 4806 +3 4501 6171 3719 +3 5421 6495 5516 +3 3234 5157 4768 +3 5299 5271 6356 +3 6234 6237 6357 +3 5826 4528 6358 +3 4636 3516 6359 +3 6526 1730 1751 +3 6362 3308 1673 +3 6362 6359 678 +3 1695 6366 5543 +3 4134 4133 6367 +3 1698 3935 6368 +3 6367 6366 6368 +3 5410 5411 6369 +3 6370 4248 821 +3 4745 4827 6371 +3 375 1693 6371 +3 6168 2690 100 +3 6168 1379 2692 +3 1027 2549 2620 +3 2684 3560 5893 +3 64 1377 6374 +3 1379 6374 1377 +3 6374 1378 64 +3 1896 35 3926 +3 100 2690 6375 +3 4450 4449 1826 +3 3588 6207 6378 +3 6377 6376 6378 +3 2329 6379 6381 +3 6379 1380 6170 +3 649 1031 900 +3 6381 1383 2329 +3 1384 644 3746 +3 1318 649 6381 +3 5907 1384 2798 +3 2065 4645 547 +3 6499 4573 6383 +3 5968 5506 2611 +3 5450 5244 2904 +3 5228 3259 6384 +3 4298 1389 6384 +3 1387 1385 6385 +3 1828 2865 6813 +3 6385 1385 6041 +3 610 6854 5501 +3 6386 1387 6385 +3 6385 1389 6386 +3 5495 5496 1135 +3 6387 1390 1073 +3 5406 4596 6388 +3 1395 1392 6392 +3 6392 1392 5355 +3 1022 3930 610 +3 6392 6390 1860 +3 1393 6388 1220 +3 13 6145 5486 +3 1395 6392 1393 +3 1396 6393 1400 +3 1396 4105 2698 +3 1400 3907 1396 +3 5764 1397 6395 +3 6395 1400 7102 +3 35 1896 1482 +3 1659 1655 308 +3 2920 1917 6449 +3 6393 236 2207 +3 5953 5799 6397 +3 6405 3117 5107 +3 3624 1403 543 +3 1403 4030 540 +3 510 1404 6407 +3 6407 1404 2702 +3 5953 5954 6412 +3 6413 6208 4183 +3 3729 5994 4082 +3 1405 6413 4142 +3 308 1655 4673 +3 1406 6415 1409 +3 6415 1406 6377 +3 6416 1409 6415 +3 1409 4509 1406 +3 5048 3632 5393 +3 299 6416 2374 +3 6415 1405 6416 +3 444 1659 1887 +3 6417 1413 4980 +3 362 4980 2064 +3 1414 6418 1415 +3 6418 1414 1944 +3 408 6420 4541 +3 1415 2044 1414 +3 1917 6448 6450 +3 408 1417 6420 +3 6422 6421 6424 +3 6430 3113 1086 +3 5388 2540 7146 +3 6431 6430 6432 +3 295 1418 3635 +3 3635 6433 295 +3 1419 6433 2286 +3 6433 1419 1425 +3 4983 1421 6434 +3 1421 3676 2706 +3 1959 6471 530 +3 1959 6468 6467 +3 5209 5210 6436 +3 6434 1425 6436 +3 6436 1425 1419 +3 4306 5676 1018 +3 4898 2617 7341 +3 4802 1962 6500 +3 2707 6438 787 +3 6500 1962 7252 +3 5476 2813 6539 +3 6438 6915 908 +3 6041 1429 522 +3 903 898 3212 +3 522 6439 6041 +3 3076 5227 6440 +3 3946 4478 6441 +3 6440 6439 6441 +3 1433 6153 6949 +3 2942 1431 6443 +3 1431 6360 1433 +3 1432 6443 1431 +3 6443 1432 2416 +3 5916 5915 6444 +3 1432 1433 6444 +3 1015 5481 4648 +3 6444 1433 6949 +3 1434 2677 6445 +3 101 6446 2711 +3 6723 2275 3044 +3 1013 5459 218 +3 5308 1968 3616 +3 5737 5736 6448 +3 3442 2920 6449 +3 3667 3611 6450 +3 6450 6449 1917 +3 6013 6014 6452 +3 4637 4636 6453 +3 6452 6451 6453 +3 6455 6055 2642 +3 6455 1439 1242 +3 4819 4823 6456 +3 6456 1439 3065 +3 4602 2268 1428 +3 1438 1038 2559 +3 6457 1439 6455 +3 5800 3660 5809 +3 1968 2641 6574 +3 1440 5809 3660 +3 2739 2307 1427 +3 5051 1442 6462 +3 1440 6462 6460 +3 3588 1969 6525 +3 1447 2715 6465 +3 4490 1443 6466 +3 3561 2715 6466 +3 1887 1659 308 +3 674 1694 2311 +3 6466 1608 4490 +3 4843 1451 6467 +3 1426 6039 190 +3 342 879 2208 +3 530 3391 1959 +3 1963 3152 2393 +3 6365 3582 4325 +3 6467 6471 1959 +3 3689 6472 337 +3 7427 3139 7364 +3 2952 2836 4147 +3 6474 1454 6218 +3 3537 4737 6476 +3 3550 1455 3549 +3 273 6477 3550 +3 3937 1457 187 +3 187 6480 3937 +3 5452 5919 2519 +3 6480 6477 273 +3 5451 1769 2133 +3 5442 127 3281 +3 3407 3478 6484 +3 5350 5349 6486 +3 5534 3820 6488 +3 6203 5711 6489 +3 2389 4274 6102 +3 6488 6486 6489 +3 4785 1458 6491 +3 5151 264 6492 +3 5539 6493 4926 +3 6492 6491 6493 +3 2668 7086 834 +3 5481 2615 5022 +3 6354 88 2948 +3 2311 1694 5276 +3 106 7508 4023 +3 3283 3309 6496 +3 4886 1461 6496 +3 1008 2081 4512 +3 1459 6497 1460 +3 6497 1459 6058 +3 651 1969 6528 +3 6498 1460 6497 +3 1460 5738 1459 +3 5441 5444 1795 +3 4971 1460 6498 +3 6497 1461 6498 +3 2802 5581 5438 +3 1539 4382 2303 +3 6159 5822 6501 +3 1977 6543 6541 +3 1464 7251 3506 +3 1464 1465 2772 +3 1465 1058 7185 +3 2720 3028 6507 +3 2720 3543 2659 +3 1471 1468 6507 +3 6177 6451 6508 +3 2541 1816 5758 +3 3438 3782 6509 +3 6509 6508 6510 +3 6515 1474 6516 +3 6516 1474 6514 +3 6514 1473 6516 +3 909 3775 910 +3 6000 5539 5066 +3 3330 4992 6519 +3 3566 3565 6522 +3 4643 4128 6524 +3 6522 6519 6524 +3 1155 1682 6525 +3 1325 4791 6527 +3 5324 5325 6528 +3 792 1623 6567 +3 642 651 6528 +3 4767 6243 6529 +3 3656 7486 5428 +3 5713 5632 3524 +3 6532 1475 3362 +3 6532 1476 6531 +3 6531 6533 6532 +3 6531 1477 6533 +3 1679 6534 1107 +3 4058 3476 6535 +3 3794 5052 2659 +3 3695 4331 6536 +3 6535 6534 6536 +3 4761 7087 6540 +3 5795 5794 6543 +3 6541 6544 1977 +3 2596 6545 6312 +3 1165 5420 4297 +3 4461 1523 6551 +3 4863 2305 6553 +3 5767 2495 6553 +3 447 2010 381 +3 7518 2700 5872 +3 2011 5195 5196 +3 2723 1832 1480 +3 5526 6344 2192 +3 1480 1478 3397 +3 1480 3398 1478 +3 5195 2011 5634 +3 6557 3302 746 +3 5415 5416 6721 +3 5189 2016 4100 +3 2016 3331 2037 +3 7337 6557 1832 +3 5063 2035 832 +3 4510 749 4756 +3 6403 4502 6560 +3 6559 6558 6560 +3 5830 3822 6561 +3 6357 6356 6563 +3 6562 6561 6563 +3 5621 5620 6564 +3 142 4721 6566 +3 6886 6369 5411 +3 882 2953 635 +3 3699 5795 6568 +3 2726 1487 6569 +3 6569 1487 1572 +3 1572 1490 6569 +3 2035 5062 126 +3 2758 6052 2590 +3 2748 1492 6570 +3 1492 1571 2446 +3 2446 6570 1492 +3 5659 1494 6760 +3 5467 1495 6572 +3 5408 3570 443 +3 6572 1495 5849 +3 5731 6573 5072 +3 1326 5958 314 +3 6576 4487 997 +3 1678 6577 6576 +3 1497 6582 4759 +3 5387 6137 5406 +3 6583 5464 1089 +3 6582 6578 6583 +3 948 1501 6590 +3 7311 7264 5405 +3 1503 6590 1171 +3 6590 1503 1507 +3 1946 2505 2603 +3 1505 1504 6591 +3 6592 1505 6591 +3 6591 2729 1507 +3 1503 6592 6591 +3 4100 4099 6596 +3 2132 1808 2040 +3 3252 3100 6597 +3 3566 3235 6598 +3 4773 2973 6599 +3 6598 6597 6599 +3 2663 6897 2280 +3 3692 6602 4251 +3 6602 6601 6603 +3 1552 249 1274 +3 2538 2630 5767 +3 5767 6553 2538 +3 2902 2838 7343 +3 1465 1464 6502 +3 6502 6605 1465 +3 1509 6607 983 +3 1509 3203 4312 +3 1911 2783 6521 +3 983 4543 1509 +3 5395 5398 1985 +3 292 4781 6608 +3 1698 3579 6015 +3 6611 3163 691 +3 6610 6611 6613 +3 6260 6259 6614 +3 6614 6613 6616 +3 997 2046 1678 +3 6618 2619 6977 +3 984 5390 4299 +3 3478 4603 6620 +3 5005 4489 6623 +3 6622 6620 6623 +3 2858 5386 5031 +3 3058 2924 6624 +3 1181 6625 6624 +3 2284 6625 1517 +3 53 2308 2646 +3 1427 2307 3902 +3 6273 7295 6156 +3 6625 2284 2665 +3 6627 1517 6625 +3 2063 6578 6807 +3 6578 2063 6583 +3 6025 2958 6628 +3 3059 2969 6629 +3 3745 3748 6631 +3 6629 6628 6631 +3 3470 3493 6633 +3 5905 5742 6635 +3 6634 6633 6635 +3 1841 5380 2516 +3 4146 6823 5378 +3 3351 5416 6638 +3 2676 7461 7460 +3 3326 3324 6639 +3 6640 3470 2242 +3 6639 6638 6640 +3 3881 3875 6646 +3 5273 5271 6648 +3 6646 6645 6648 +3 1866 2144 7206 +3 4157 5282 6650 +3 6858 6458 2688 +3 4768 4519 2398 +3 1518 6651 574 +3 1518 6172 4768 +3 1519 2731 1520 +3 1519 4184 2731 +3 1520 3534 1519 +3 1522 1520 6655 +3 1524 6655 1520 +3 6655 1524 3129 +3 1524 2762 2592 +3 2362 2077 806 +3 1525 2322 567 +3 3460 1528 6658 +3 6658 1528 5925 +3 2121 1876 1556 +3 102 6658 2735 +3 6658 102 11 +3 5870 1529 6659 +3 6659 1529 5868 +3 6659 1531 5870 +3 2923 1530 6662 +3 4001 3705 5703 +3 6662 1531 300 +3 4456 6485 6663 +3 6663 1531 6659 +3 7244 3602 4460 +3 2077 2102 5847 +3 3547 2079 6684 +3 6684 2079 6683 +3 1328 258 6053 +3 5363 5365 2593 +3 5796 6600 6670 +3 6515 6340 6674 +3 4520 7180 7068 +3 1326 975 5361 +3 4807 6256 5110 +3 1535 7094 6675 +3 1535 2743 6678 +3 4807 2098 5687 +3 2743 1535 6679 +3 6679 1535 6675 +3 6333 6316 5358 +3 1536 6679 6675 +3 6679 1536 6752 +3 165 1538 6681 +3 6681 1538 4832 +3 5402 5664 6682 +3 3546 3547 6684 +3 6683 6682 6684 +3 5083 5084 6686 +3 283 1540 6686 +3 6691 5590 6689 +3 6689 5590 4300 +3 6689 1540 6691 +3 6693 1985 2468 +3 5444 777 4329 +3 4329 6694 1795 +3 971 2113 4517 +3 6936 6486 5349 +3 5528 6695 291 +3 6694 6693 6695 +3 969 5347 6294 +3 4322 6135 6696 +3 5896 2958 6699 +3 6698 6696 6699 +3 4194 3609 5509 +3 6551 6550 6705 +3 1372 6707 5732 +3 1670 6707 1372 +3 6707 1545 4995 +3 6703 6705 6709 +3 5337 5339 6688 +3 1545 6706 6709 +3 601 1548 6711 +3 6548 6547 6712 +3 1549 6405 6713 +3 4342 5556 6714 +3 6714 1549 1665 +3 1556 2033 7519 +3 5373 3612 279 +3 1665 6713 6715 +3 4181 4184 6717 +3 3084 6718 3034 +3 3694 3695 6720 +3 641 2907 4724 +3 7269 1780 5334 +3 1551 3742 4313 +3 3579 1698 7041 +3 1626 2131 6869 +3 1223 3928 472 +3 3821 4351 6725 +3 6869 2131 6873 +3 1616 1308 6159 +3 1711 3507 6143 +3 2745 2139 6727 +3 3507 1711 4426 +3 1819 3472 2190 +3 5560 1555 6728 +3 1555 3298 2745 +3 6727 2138 6728 +3 2138 1558 6728 +3 3255 2135 1631 +3 5396 2703 5388 +3 6728 1558 5560 +3 5605 7275 6730 +3 4475 4474 6731 +3 6397 6398 6733 +3 7004 1556 1876 +3 6733 6731 6734 +3 6739 3332 1177 +3 3432 1559 1013 +3 6739 6737 6740 +3 965 5328 4930 +3 2648 2245 246 +3 193 1562 2209 +3 1631 2135 6947 +3 6742 6741 922 +3 5891 5798 6745 +3 5325 2279 642 +3 3849 4464 6746 +3 6746 6745 6748 +3 2469 5454 3989 +3 6146 2172 6989 +3 6751 1564 6924 +3 964 2848 1870 +3 1929 1533 2743 +3 576 5874 2021 +3 2518 5848 3784 +3 6750 6752 1536 +3 3174 3103 6753 +3 4638 4890 6755 +3 6996 5315 5314 +3 961 5874 5321 +3 6755 6753 6756 +3 4435 1565 6759 +3 1565 2747 5029 +3 6989 2172 2201 +3 6760 6572 6546 +3 6579 1907 1560 +3 1569 6760 2747 +3 6760 1569 6572 +3 4249 2176 824 +3 1565 4435 3253 +3 2194 2282 6762 +3 648 6974 6270 +3 4157 5302 6768 +3 6769 2635 1178 +3 1487 1571 1492 +3 1492 6770 1487 +3 2088 5641 6184 +3 6770 1572 1487 +3 4808 5733 6772 +3 5898 6131 6775 +3 6838 5308 3616 +3 6774 6772 6775 +3 1577 1573 6776 +3 6776 1573 2383 +3 1578 1577 6776 +3 5990 5783 6777 +3 4247 2176 1108 +3 3746 3505 2204 +3 6989 2201 7028 +3 7028 2201 7312 +3 6778 3854 1855 +3 5577 5578 6779 +3 2516 171 1841 +3 5510 6601 6780 +3 6779 6778 6780 +3 2161 5778 4964 +3 6737 6079 6783 +3 395 1580 6784 +3 3052 3088 6785 +3 2738 6784 3433 +3 1479 5621 5302 +3 5323 4913 6786 +3 1581 6786 4913 +3 1581 6788 2751 +3 6904 3340 4098 +3 6791 1582 6788 +3 5297 5299 5461 +3 6788 1582 1867 +3 3302 3721 1582 +3 2209 410 193 +3 6791 6788 1581 +3 2344 1584 560 +3 6219 5672 6796 +3 6472 6474 6798 +3 6581 5493 5295 +3 917 5394 6799 +3 251 6796 6799 +3 860 1645 6801 +3 2445 1586 6805 +3 1946 7148 6758 +3 6805 2753 6804 +3 6805 103 2442 +3 2127 6806 1482 +3 103 2752 6806 +3 410 2209 580 +3 5291 5292 4786 +3 6807 4420 2754 +3 5154 5527 3585 +3 6807 1588 2063 +3 6808 2754 1589 +3 2757 1588 6808 +3 6808 1588 6807 +3 895 2214 7056 +3 6808 1589 2750 +3 6811 5234 1995 +3 2214 7055 7059 +3 5553 356 7524 +3 2215 906 5241 +3 3902 2307 1110 +3 6814 1593 1592 +3 1593 5186 1592 +3 6649 1594 6818 +3 4646 3646 697 +3 2925 3536 6819 +3 6831 1601 1595 +3 3275 3274 6820 +3 5078 4476 4573 +3 3340 3457 3562 +3 6821 6634 5829 +3 6822 2592 2762 +3 6822 1596 1135 +3 5379 5378 6823 +3 906 2215 7059 +3 6823 1596 4583 +3 3672 5484 4583 +3 6824 1596 6822 +3 2763 1598 6825 +3 6825 1598 6826 +3 6826 1597 3853 +3 3853 6825 6826 +3 6826 1598 1641 +3 4250 4252 6827 +3 5454 2469 5457 +3 4223 4222 6828 +3 4588 3449 6829 +3 2766 6372 6829 +3 2761 3660 6831 +3 1996 1601 6831 +3 6765 6764 6835 +3 5307 5308 6838 +3 5799 5798 6839 +3 6838 6835 6839 +3 6845 4650 6847 +3 4014 3553 6848 +3 6848 4650 6845 +3 6290 6201 6849 +3 6510 3435 6851 +3 3967 574 5282 +3 5636 5638 6852 +3 6851 6849 6852 +3 6853 610 3360 +3 7380 2221 1600 +3 3231 2986 6855 +3 6854 6853 6855 +3 3174 3175 6856 +3 6859 1168 2343 +3 2221 7093 20 +3 1805 6846 5149 +3 7127 3593 4632 +3 2564 5280 7155 +3 6859 2343 2342 +3 5330 6010 6862 +3 2794 1342 809 +3 794 1606 6862 +3 6864 1605 4280 +3 4580 2118 4117 +3 6864 1604 5487 +3 4028 1987 662 +3 6866 1605 6864 +3 4280 1604 6864 +3 6769 6768 6866 +3 6864 1606 6866 +3 1201 5185 6688 +3 6870 6869 6873 +3 2229 7132 5969 +3 3472 1819 2179 +3 1612 6874 1018 +3 6874 1612 1671 +3 6876 4702 6915 +3 681 2398 441 +3 4851 1615 6877 +3 6402 1616 6878 +3 1616 6158 123 +3 50 6878 1942 +3 1620 7225 5571 +3 7158 1680 685 +3 2241 7157 7160 +3 1619 1671 5558 +3 156 939 4899 +3 7429 2246 1550 +3 7104 2737 3921 +3 5985 7508 106 +3 4195 1621 6887 +3 6887 7112 2352 +3 2352 7112 6587 +3 1021 6648 5271 +3 4079 4810 6889 +3 5330 6144 6891 +3 6890 6889 6891 +3 5710 3522 2488 +3 6881 1664 6893 +3 297 1885 1478 +3 3830 3829 6895 +3 4285 2119 6900 +3 6562 4919 6905 +3 5615 5828 6907 +3 3836 5107 6910 +3 1478 1885 3397 +3 7209 2246 7212 +3 6915 1622 2936 +3 3481 5245 6916 +3 6916 1622 6912 +3 5217 6627 6918 +3 2924 4586 6919 +3 6258 6908 6925 +3 6921 6920 6925 +3 6318 6927 6612 +3 3329 4210 6928 +3 6927 6926 6928 +3 5900 6921 6929 +3 1625 6931 1732 +3 6931 1625 2030 +3 6932 6931 6933 +3 5894 1742 6934 +3 7169 1895 3390 +3 1742 2060 6934 +3 6596 1628 6937 +3 6937 1628 6595 +3 6937 1629 6596 +3 6938 5564 5565 +3 5068 4476 5078 +3 229 1629 6939 +3 5730 4078 6939 +3 6939 2975 229 +3 6939 1629 6937 +3 6521 2553 3002 +3 3002 2553 6744 +3 1840 3958 1630 +3 6765 4487 6942 +3 1840 6593 6942 +3 3818 6945 1587 +3 2251 7277 4264 +3 7277 2251 7276 +3 6946 1632 2135 +3 5734 5446 5262 +3 2529 5260 936 +3 6199 1631 6947 +3 1587 6945 2776 +3 2777 1634 7034 +3 7034 1664 2777 +3 5188 6951 5750 +3 1636 1635 6951 +3 6951 1635 6399 +3 2263 3356 828 +3 1635 1636 2777 +3 2777 1636 1634 +3 935 5257 721 +3 5606 1637 6953 +3 1637 4335 6580 +3 6953 6660 4762 +3 6953 1638 5606 +3 3400 3395 5385 +3 4514 4515 6955 +3 237 6956 492 +3 4974 3815 6943 +3 4314 6308 6961 +3 3356 2263 2068 +3 2027 257 135 +3 6960 6958 6961 +3 3241 4168 6962 +3 3187 3185 6964 +3 5534 5667 6966 +3 6964 6962 6966 +3 6967 1640 6970 +3 6970 1640 4979 +3 5202 5252 2326 +3 2264 7357 1843 +3 4402 3483 6971 +3 1748 1643 6972 +3 6972 1643 5753 +3 1706 4202 6975 +3 5201 708 985 +3 6974 6972 6975 +3 7357 2264 7356 +3 2268 7375 7029 +3 3655 3654 6984 +3 4521 4522 6985 +3 6985 6984 6986 +3 5612 6669 6987 +3 352 1644 6991 +3 4585 3402 6992 +3 5232 4314 6995 +3 1646 2820 7282 +3 3159 3158 6997 +3 1646 6084 6997 +3 6084 1646 7001 +3 2244 4376 6792 +3 7001 1646 7282 +3 7375 2268 7446 +3 1647 3611 2781 +3 3761 4804 3277 +3 3297 2885 6729 +3 908 2507 1541 +3 2087 7314 608 +3 1648 3443 1647 +3 5239 5240 3558 +3 4069 3528 7003 +3 1031 3205 3765 +3 7003 1648 2999 +3 7005 1648 1647 +3 5523 4761 7008 +3 1649 1785 1651 +3 6067 3971 5235 +3 1895 1177 3332 +3 1903 3366 6994 +3 812 6685 4949 +3 5153 2276 2081 +3 2081 2276 3045 +3 2281 5797 2226 +3 1658 1656 7020 +3 1656 1309 7023 +3 1309 1762 180 +3 7021 7020 7023 +3 5818 1657 7024 +3 1656 1658 2599 +3 5370 6944 7026 +3 6917 6155 7027 +3 6987 6989 7028 +3 1964 6811 1995 +3 1662 7031 2785 +3 7031 1662 7029 +3 7029 1663 7031 +3 7031 1663 2030 +3 897 5232 3189 +3 5789 7033 147 +3 5797 2281 146 +3 3947 7034 1634 +3 2694 7033 7057 +3 5654 3947 1666 +3 1169 7035 5229 +3 1060 1140 1561 +3 6980 6979 7036 +3 5226 5227 4581 +3 7419 7397 2372 +3 1553 2300 7432 +3 1667 4234 1669 +3 1667 1669 7040 +3 7157 2301 284 +3 3395 3400 1332 +3 7040 1669 6671 +3 3366 1903 5583 +3 1657 7044 7024 +3 7044 29 30 +3 30 7024 7044 +3 3950 6909 6523 +3 7046 1671 1612 +3 1935 3049 4696 +3 2587 664 3006 +3 7046 1672 5288 +3 1672 7047 5474 +3 7047 1672 2094 +3 2301 7429 284 +3 7048 4910 2051 +3 7048 1676 4910 +3 71 2303 4382 +3 1085 7049 1937 +3 1675 7049 1674 +3 7049 1675 1937 +3 1675 1676 7050 +3 1676 7048 2789 +3 2791 2194 1754 +3 1677 1754 2194 +3 2791 6230 2399 +3 2792 4187 897 +3 3299 3200 7055 +3 7056 4095 895 +3 1681 7059 6228 +3 7059 1681 906 +3 7059 7056 2214 +3 2303 7497 1539 +3 2406 2371 7061 +3 2371 2406 2555 +3 894 1284 2302 +3 1516 5706 495 +3 7063 2052 181 +3 5091 2316 5754 +3 5414 5594 2504 +3 2755 1960 5123 +3 5123 1960 637 +3 2323 7240 1532 +3 5252 3006 4039 +3 4904 1688 7067 +3 1688 3168 2796 +3 109 7067 2796 +3 7067 1689 4904 +3 107 5907 2798 +3 6678 5236 7069 +3 107 2797 7069 +3 4798 6610 7070 +3 4080 6187 7071 +3 7058 7431 5547 +3 6259 3056 7072 +3 5670 1879 5787 +3 7427 1639 3139 +3 7071 7070 7072 +3 6154 4515 7076 +3 119 2323 5926 +3 4635 5658 5761 +3 7079 1080 4635 +3 4892 4649 7426 +3 5270 2324 5571 +3 233 6434 6436 +3 2324 5834 1620 +3 68 2801 7078 +3 7377 5130 6264 +3 5393 3632 5352 +3 5003 1700 7080 +3 7080 1700 1702 +3 1701 2683 7080 +3 5823 6960 7081 +3 2610 5027 2210 +3 1701 2804 7081 +3 2804 1701 7082 +3 7082 1701 7080 +3 3499 2236 1320 +3 2345 1703 7083 +3 2590 1132 6311 +3 6994 2650 1047 +3 4032 4031 7090 +3 2699 4599 7464 +3 7093 7090 7094 +3 3074 3080 7097 +3 355 1705 7098 +3 722 2712 7005 +3 15 4081 5197 +3 7098 7097 7099 +3 7105 3844 3845 +3 4202 1706 7106 +3 885 1035 2543 +3 7106 1706 4108 +3 4106 4107 7107 +3 2660 5193 161 +3 6379 2329 1380 +3 5192 2670 4299 +3 2876 3683 2438 +3 2329 1383 6380 +3 2154 2345 7083 +3 1610 2421 513 +3 2295 1709 7114 +3 4061 5565 5189 +3 7114 1709 70 +3 2350 6147 7458 +3 2269 6584 7123 +3 5609 7125 1066 +3 7125 5609 1065 +3 411 75 7126 +3 102 2732 7128 +3 7126 7125 7128 +3 4467 7131 1012 +3 5969 5968 2229 +3 3632 3444 5814 +3 3003 3379 7133 +3 2873 3926 5187 +3 6147 2350 6210 +3 2229 7133 7132 +3 546 1714 7134 +3 6616 4567 7135 +3 4714 4713 7137 +3 7135 7134 7137 +3 6908 6909 7142 +3 319 756 872 +3 6930 6929 7144 +3 2299 733 5222 +3 2507 1716 462 +3 4344 4345 7152 +3 1719 7154 1721 +3 2314 6400 1899 +3 1719 3544 2806 +3 7152 1720 7154 +3 1592 6766 5437 +3 7154 1720 7150 +3 7150 1721 7154 +3 1721 4598 1719 +3 5823 7160 6017 +3 7160 7158 2241 +3 7124 5337 5184 +3 4655 4653 7161 +3 5986 6734 7162 +3 3046 6245 7164 +3 5106 733 2645 +3 7162 7161 7164 +3 491 6833 7165 +3 7165 4373 491 +3 5942 1277 7165 +3 4373 7165 21 +3 5027 2610 5181 +3 1724 5013 2807 +3 1728 7169 82 +3 3390 4388 7169 +3 2263 2351 5418 +3 82 7168 1728 +3 5829 5742 5177 +3 217 1527 4924 +3 1941 3557 7170 +3 5225 5422 7171 +3 1941 5763 7171 +3 5632 3651 3524 +3 6980 1732 7172 +3 7172 1732 6932 +3 1830 5610 7172 +3 113 1912 6579 +3 7172 5610 6980 +3 1737 686 7176 +3 6407 2702 1737 +3 7176 1738 6407 +3 7177 4284 4307 +3 115 2351 104 +3 7066 1527 7525 +3 7180 7177 7181 +3 1740 7183 6345 +3 7183 1740 1752 +3 1253 1221 7318 +3 7318 1221 2836 +3 2077 2362 4616 +3 4616 2362 2105 +3 7498 5298 305 +3 3222 4112 2914 +3 7185 1906 7469 +3 6345 7183 7188 +3 702 2421 1610 +3 629 603 7318 +3 6504 4005 4136 +3 5790 3448 7189 +3 6212 5817 7191 +3 3631 489 6275 +3 3156 5579 7193 +3 7192 7191 7193 +3 5766 1746 7194 +3 5173 5174 3617 +3 2360 7195 442 +3 5172 4811 1204 +3 6566 6564 7196 +3 7194 7196 8 +3 7346 1838 6653 +3 3049 1935 3486 +3 1747 4514 2815 +3 1944 3030 2933 +3 1749 3214 1747 +3 3068 541 4566 +3 7155 1697 3077 +3 2607 1730 1729 +3 1752 7184 7183 +3 1752 2144 7184 +3 3110 1753 7207 +3 7207 1753 1866 +3 7207 7206 7208 +3 4060 7387 2487 +3 5017 3114 2613 +3 1680 1677 7212 +3 2441 2883 7450 +3 7210 7209 7212 +3 4022 4221 7216 +3 7215 7213 7216 +3 874 2370 5745 +3 1755 7217 4587 +3 7217 1755 7271 +3 1757 1756 74 +3 1757 74 1781 +3 2478 4169 5515 +3 6483 5661 7220 +3 544 2032 7113 +3 1759 7220 2050 +3 7220 1759 1940 +3 3126 1430 3832 +3 6348 5750 7223 +3 4719 4718 7226 +3 6538 6537 7230 +3 7015 5721 3145 +3 5163 5164 6969 +3 6756 6229 7231 +3 7230 7226 7231 +3 5063 1763 7232 +3 7232 1763 5768 +3 1190 2734 1427 +3 7332 5165 3172 +3 7232 1767 3359 +3 5449 4765 5336 +3 4209 6828 5162 +3 3821 5660 7233 +3 1767 4176 7233 +3 2266 1764 7234 +3 7234 1764 2175 +3 1767 7234 2175 +3 1767 7232 5768 +3 1752 1768 7235 +3 1768 1749 1747 +3 2554 7236 173 +3 173 179 7238 +3 2784 2941 763 +3 7013 6153 7244 +3 1273 1771 7245 +3 7245 1771 1774 +3 7263 1772 7246 +3 1630 4446 617 +3 1047 2650 5828 +3 6458 5715 3601 +3 7247 7249 108 +3 4880 6088 5157 +3 1830 1773 7249 +3 1773 438 2823 +3 7249 7247 3812 +3 7252 6501 3219 +3 5662 2377 5642 +3 7054 7052 7253 +3 3665 4540 4557 +3 6930 5612 7254 +3 2764 7270 5017 +3 7118 5014 7257 +3 5018 5751 7258 +3 7258 7257 7259 +3 7246 1774 1771 +3 1771 7263 7246 +3 7261 7260 7263 +3 1776 1772 3489 +3 7250 7252 1962 +3 2197 7408 5150 +3 5466 2694 1666 +3 3854 5578 5141 +3 7245 1778 7268 +3 1778 5807 2817 +3 7268 1782 7245 +3 1666 2694 5654 +3 7269 1782 6761 +3 1781 7271 1757 +3 7271 1781 7217 +3 7268 7271 1755 +3 5298 2661 7203 +3 1784 3920 3918 +3 2860 5140 3495 +3 2818 1791 1784 +3 3683 694 1500 +3 2863 4093 761 +3 1651 1785 7273 +3 2819 1786 7273 +3 7512 3893 7141 +3 7273 1786 1787 +3 1786 7274 26 +3 7273 1787 7016 +3 7274 2243 26 +3 26 2233 1787 +3 1786 1791 7274 +3 7274 1791 2818 +3 1955 559 1171 +3 5458 7021 7276 +3 4264 4262 2251 +3 56 2047 2069 +3 5673 5676 7278 +3 1793 7282 2822 +3 7282 1793 7001 +3 7019 5888 2653 +3 7466 369 1323 +3 1897 1794 7284 +3 7284 2820 2675 +3 27 2820 1646 +3 30 7285 1800 +3 2768 7286 2604 +3 7286 1800 2106 +3 1154 1441 6215 +3 7285 7287 2106 +3 3877 3876 7288 +3 128 1803 7289 +3 7289 1803 253 +3 244 6820 6673 +3 7292 7289 253 +3 6797 5061 7280 +3 7293 3527 2824 +3 2824 1806 7293 +3 1806 1811 1807 +3 1807 7293 1806 +3 4197 4838 6034 +3 7293 1807 4652 +3 7155 3077 2258 +3 5619 3929 5087 +3 2825 4470 1809 +3 1809 1811 7295 +3 7295 1811 1806 +3 906 4463 368 +3 1806 5382 7295 +3 7297 2792 3189 +3 7297 7296 2133 +3 5278 153 3119 +3 1056 7368 3934 +3 7300 1817 6189 +3 3921 5604 7104 +3 1815 7300 2827 +3 1815 6906 1817 +3 1817 7300 1815 +3 6744 2768 4129 +3 1924 6652 3254 +3 6784 2738 6785 +3 859 5126 32 +3 2772 196 214 +3 1822 192 6345 +3 1822 7304 1823 +3 7519 4143 5546 +3 1526 3077 1697 +3 2674 6164 353 +3 1823 7304 7442 +3 1823 3214 192 +3 3030 1944 1414 +3 7306 1999 150 +3 6529 6530 7307 +3 6748 6412 7308 +3 2939 3848 7309 +3 1921 943 2722 +3 7308 7307 7309 +3 109 2796 1825 +3 4207 1824 7310 +3 1825 7310 109 +3 6882 4993 2331 +3 2270 5182 5117 +3 854 5112 5364 +3 7310 1825 2353 +3 1989 7312 2201 +3 5381 5380 1841 +3 3121 3386 2563 +3 5244 542 1718 +3 1829 1827 6328 +3 2323 1157 5926 +3 2955 2671 2835 +3 3383 6556 2153 +3 76 2812 2602 +3 2738 6783 1091 +3 1827 1829 171 +3 2181 6401 2904 +3 7316 7315 7317 +3 1773 1830 7323 +3 1830 7172 2811 +3 6801 7287 7326 +3 7329 7328 7330 +3 5499 1449 4562 +3 7120 6410 7331 +3 293 7334 312 +3 7335 6271 1004 +3 4129 2421 6744 +3 5640 2805 6184 +3 541 5057 2269 +3 1832 2723 141 +3 141 7334 7337 +3 2853 2290 6164 +3 1834 1833 7338 +3 848 5104 3797 +3 1833 1619 2793 +3 2542 1987 7339 +3 3026 1268 5253 +3 7339 1834 7340 +3 5515 1991 7202 +3 1835 2406 7061 +3 7340 2837 7339 +3 7340 1834 7338 +3 2406 1835 3469 +3 469 3631 2739 +3 1836 7342 1882 +3 7342 1836 262 +3 7343 2365 1 +3 1837 7343 7345 +3 7343 1837 4292 +3 7345 2839 1837 +3 7345 2838 257 +3 890 5275 2528 +3 7347 7346 5168 +3 164 4996 1391 +3 1839 2396 7349 +3 4839 1839 7349 +3 6398 6764 7350 +3 3674 4475 7351 +3 2494 7109 1850 +3 6593 1840 7352 +3 7352 1840 1630 +3 7351 7350 7352 +3 3091 225 4025 +3 7354 1841 1829 +3 2314 5976 3751 +3 5322 1842 964 +3 964 7355 5322 +3 6710 7356 1051 +3 5234 4817 7359 +3 7357 7356 7359 +3 1844 7360 1845 +3 1844 690 2841 +3 4189 3244 1054 +3 1848 1845 7360 +3 1845 4372 1844 +3 3963 7361 1082 +3 1848 1846 7361 +3 7361 1846 1337 +3 1306 1847 7362 +3 1846 1848 7360 +3 7360 7362 1846 +3 842 1849 845 +3 1293 6931 2030 +3 3603 1575 5393 +3 5097 7363 842 +3 2566 3991 2427 +3 6517 1904 1526 +3 1850 7363 2494 +3 7363 1850 1857 +3 5582 5587 7365 +3 3452 4197 5472 +3 7371 1855 7365 +3 7365 1855 3854 +3 3625 1856 1855 +3 7365 1857 7371 +3 7371 1857 1850 +3 488 5963 5093 +3 5752 1961 1828 +3 2290 4383 353 +3 2805 6185 1064 +3 2630 2538 3792 +3 7029 5458 2268 +3 664 2831 4651 +3 5919 3954 1654 +3 7379 6264 3124 +3 7017 1858 7381 +3 7381 1858 7167 +3 7381 2844 2020 +3 2020 1859 7381 +3 7381 1859 7017 +3 2687 5563 7437 +3 5894 2020 1862 +3 1862 7382 5894 +3 7065 1862 2020 +3 7382 1862 2058 +3 658 2184 4433 +3 254 1865 7383 +3 6686 5084 2177 +3 4037 3134 2045 +3 7388 1863 7384 +3 7384 1863 6302 +3 6332 4300 1863 +3 7384 1865 7388 +3 5705 5082 3659 +3 7238 6956 7391 +3 6830 2737 7104 +3 5426 4894 5705 +3 6880 6810 7393 +3 5046 1914 7393 +3 6660 3306 4017 +3 3659 5426 5705 +3 5369 6157 7395 +3 5149 2447 1805 +3 2881 1978 7395 +3 1980 2014 7396 +3 7184 1866 7398 +3 7324 627 7275 +3 2447 1891 1805 +3 3346 1891 2447 +3 7398 1866 1753 +3 1939 447 7303 +3 7467 1263 7399 +3 5642 4192 7401 +3 6788 1867 1112 +3 1112 7403 2751 +3 7405 7354 2832 +3 1871 1868 7406 +3 7405 1870 7406 +3 7406 1870 7403 +3 7403 1871 7406 +3 5144 5150 7408 +3 7073 7175 7411 +3 5139 1872 7412 +3 7412 1872 6253 +3 4554 6288 5075 +3 4283 1104 6096 +3 5080 5341 833 +3 7412 2851 5139 +3 5255 1873 7413 +3 7413 1873 6592 +3 2227 110 1874 +3 3724 3722 6993 +3 3363 2893 4673 +3 7413 1874 5255 +3 1310 1875 7414 +3 1526 1904 6573 +3 1875 6209 2662 +3 7414 1874 110 +3 5858 5352 5814 +3 6329 4106 7415 +3 1878 7417 1756 +3 7417 1878 2515 +3 7366 7324 7130 +3 7419 7398 1753 +3 7189 7188 7420 +3 5018 5144 7422 +3 7175 7389 7424 +3 7423 7422 7424 +3 6580 3638 605 +3 7045 7157 284 +3 129 2300 1553 +3 7432 7430 284 +3 1872 5689 1340 +3 3307 7006 7433 +3 2015 3779 1063 +3 5673 5168 7434 +3 6795 3121 4341 +3 2795 1879 2852 +3 4804 934 3343 +3 2184 2920 3591 +3 7050 1882 7439 +3 5316 1916 2049 +3 7439 1882 7342 +3 110 2227 2851 +3 2852 2854 2795 +3 126 832 2035 +3 2852 1886 7439 +3 7439 1886 7050 +3 2455 5695 2595 +3 5672 6143 7440 +3 7440 4518 5672 +3 6720 6718 7445 +3 7444 1889 7445 +3 7445 1889 61 +3 7373 7375 7446 +3 1893 1890 7446 +3 2963 1153 5825 +3 5054 2187 1033 +3 1893 1892 7447 +3 1153 2963 7228 +3 7447 1892 3600 +3 1715 1639 5215 +3 6810 6809 7448 +3 3578 6460 6462 +3 3916 2829 800 +3 7508 1891 3346 +3 3400 5371 1332 +3 2427 6861 2566 +3 5604 1914 5046 +3 7121 7123 7451 +3 7449 7448 7451 +3 7416 5807 7452 +3 6127 2449 2778 +3 7452 1898 7416 +3 99 2675 7453 +3 2857 7453 252 +3 2857 1898 7452 +3 2449 4708 2778 +3 7452 7455 2857 +3 2856 1982 7455 +3 7261 5334 7456 +3 7459 740 3595 +3 250 2491 7459 +3 2676 7460 2872 +3 2117 3280 3727 +3 513 2885 3297 +3 2676 1899 7461 +3 7461 1899 6400 +3 7461 1901 7460 +3 5140 7462 5788 +3 2227 559 1955 +3 7462 1905 1144 +3 3688 2957 7463 +3 7463 1905 3258 +3 3421 3258 7465 +3 7465 1905 7462 +3 2368 6976 7468 +3 7467 3962 7468 +3 7469 196 7185 +3 2493 7159 4067 +3 6636 6018 1253 +3 7467 7469 2814 +3 3242 2477 3815 +3 7007 2247 3902 +3 5751 7330 7474 +3 7120 7118 7477 +3 7474 7472 7477 +3 7478 231 5917 +3 5150 7259 7479 +3 6146 6989 7481 +3 2049 7426 5316 +3 5039 3904 4986 +3 7480 7479 7481 +3 7144 7142 7482 +3 6666 6669 7483 +3 1909 2461 7485 +3 1910 1909 7485 +3 5030 5033 249 +3 1910 3656 1972 +3 2487 7043 4060 +3 5850 5428 7486 +3 3656 1910 7486 +3 7486 1910 7485 +3 7329 7423 7488 +3 3856 3855 7490 +3 6129 6139 7491 +3 6349 1913 259 +3 259 7492 6349 +3 7491 7490 7492 +3 1810 5991 6004 +3 5019 5020 1009 +3 7495 1920 127 +3 1699 474 2891 +3 7496 1920 2303 +3 1919 7497 7278 +3 7092 436 2741 +3 5050 3991 2566 +3 7497 1920 7495 +3 7499 7167 1858 +3 1922 7502 2866 +3 1922 7499 1923 +3 1691 3175 735 +3 6618 6977 2584 +3 1923 7502 1922 +3 2373 6882 6879 +3 7502 1923 911 +3 1928 1925 1933 +3 1933 1925 6642 +3 1928 1926 7504 +3 627 7324 425 +3 1180 7257 5014 +3 1926 1928 7505 +3 7332 6621 4339 +3 6654 1930 7283 +3 7283 1930 5344 +3 1852 4067 7159 +3 7438 6233 7197 +3 316 1931 7197 +3 7197 1931 2028 +3 5044 1932 6150 +3 6150 2095 7078 +3 199 6233 262 +3 1836 1933 6642 +3 7077 6642 1925 +3 847 2807 2486 +3 4722 6225 6606 +3 1936 5485 6606 +3 3902 2247 2597 +3 3554 2427 2380 +3 2380 1449 1696 +3 163 7500 1158 +3 1113 2280 2646 +3 2646 2280 53 +3 5485 1936 6282 +3 5906 5320 5073 +3 7053 2742 5012 +3 1084 6008 1085 +3 1940 1759 6008 +3 2671 2697 1743 +3 820 5011 2401 +3 5754 6008 5091 +3 5763 1941 6922 +3 6922 1941 7170 +3 7466 6701 6871 +3 1743 2835 2671 +3 2840 6090 819 +3 1286 5167 6837 +3 6871 6922 6837 +3 6700 3159 6842 +3 495 7166 6641 +3 1942 5834 50 +3 5927 1943 771 +3 1943 6514 1474 +3 2480 4793 388 +3 3833 3831 2004 +3 2987 3869 5425 +3 5124 281 2272 +3 4928 3783 1034 +3 2680 3055 5455 +3 2475 6300 5398 +3 596 4422 6042 +3 4928 5124 4422 +3 2701 2514 5938 +3 7319 2925 4272 +3 7321 6250 6738 +3 5290 4722 4035 +3 7377 7379 3883 +3 7400 4160 4159 +3 4159 3883 7400 +3 4145 4144 1949 +3 4224 1947 3807 +3 5618 5616 3940 +3 1599 1590 734 +3 1947 3105 1949 +3 4820 4216 4211 +3 3781 1948 3807 +3 3807 1948 5701 +3 3807 1949 3781 +3 7435 1950 3937 +3 4427 4999 4998 +3 5215 6437 2075 +3 4998 327 4427 +3 7313 1951 640 +3 1952 7298 2422 +3 7298 1952 1020 +3 7428 4447 6165 +3 7313 7435 7298 +3 5900 7052 7241 +3 2095 2870 7147 +3 2869 1953 7147 +3 7017 7317 7145 +3 6653 6641 7014 +3 7014 7145 6935 +3 6774 3530 6726 +3 4990 4992 3462 +3 6423 3422 5893 +3 4809 4808 6571 +3 5517 5516 6495 +3 6571 6726 6495 +3 6464 5139 2851 +3 1955 5883 2871 +3 6758 2505 1946 +3 1958 6464 6214 +3 217 377 7525 +3 6464 1958 5139 +3 7525 377 4201 +3 3479 1132 6052 +3 3202 1810 5781 +3 5820 5884 6181 +3 7229 5423 2934 +3 2308 940 6134 +3 637 5043 1819 +3 1960 6341 1958 +3 1958 6214 1960 +3 5893 3560 1410 +3 7420 1553 1355 +3 2835 7305 2689 +3 1992 1967 5647 +3 2467 5472 4197 +3 6940 3116 1575 +3 5389 1971 2879 +3 52 1970 5389 +3 6244 3995 5203 +3 5174 6530 5103 +3 6918 6919 5060 +3 5103 5203 5060 +3 1975 1974 2880 +3 6767 6296 959 +3 2880 1974 5394 +3 940 2308 53 +3 6958 6920 4935 +3 7296 6995 4915 +3 7241 7182 4824 +3 4915 4935 4824 +3 2671 2318 6897 +3 2397 5508 6423 +3 1975 4691 7400 +3 3740 4720 6093 +3 2880 4691 1975 +3 7076 7306 4740 +3 3679 615 652 +3 615 3679 7457 +3 6882 3179 6879 +3 5918 2528 5320 +3 7396 1978 4654 +3 4740 1979 4654 +3 4626 4680 6268 +3 1979 4772 1980 +3 1980 4654 1979 +3 4654 1980 7396 +3 7455 1982 4531 +3 4531 1982 1687 +3 5710 2456 2525 +3 101 2710 4451 +3 1983 4390 1986 +3 4390 1983 7101 +3 1984 4390 2882 +3 4390 1984 4531 +3 4531 1986 4390 +3 1986 7100 1983 +3 4294 1058 5285 +3 6275 5480 2311 +3 1988 2814 4287 +3 4983 6434 233 +3 4382 1988 4287 +3 2814 1988 3962 +3 7331 7333 4056 +3 2064 1417 362 +3 6146 5014 3890 +3 4056 4186 3890 +3 335 2659 5052 +3 7064 1990 3841 +3 4327 6898 3741 +3 1990 6979 2884 +3 3841 1994 2799 +3 5275 2926 5320 +3 52 2577 1965 +3 7249 3812 2884 +3 6547 5679 2926 +3 1994 3812 117 +3 3812 1994 3841 +3 3396 4977 3380 +3 6897 2318 2280 +3 1964 1995 7038 +3 7038 6800 5518 +3 6800 5831 1998 +3 5683 5340 4973 +3 2398 681 6651 +3 1998 5518 6800 +3 5518 1998 5277 +3 5404 5405 7264 +3 4971 2810 1460 +3 2847 468 1929 +3 4720 7127 6093 +3 6992 6991 7503 +3 3202 2887 4443 +3 5991 3202 4443 +3 2939 5175 7493 +3 7503 7264 7493 +3 7223 7221 7471 +3 7442 1999 1823 +3 132 7025 2599 +3 7442 7471 7421 +3 3282 3220 7418 +3 6271 6272 7369 +3 7143 6132 5547 +3 2070 3185 7348 +3 7369 7418 7348 +3 5025 5224 4968 +3 3000 2007 7302 +3 7392 2001 7294 +3 5431 2004 7272 +3 2004 5425 2886 +3 2618 6949 2916 +3 7294 2006 7272 +3 7272 2006 7302 +3 6463 6549 307 +3 7302 2007 5431 +3 5431 7272 7302 +3 1499 3055 2931 +3 7242 6913 6103 +3 2428 7324 7366 +3 2794 3545 5602 +3 6391 1253 6018 +3 5623 3048 2116 +3 1037 2333 291 +3 3032 3057 7237 +3 4838 3452 6816 +3 3635 2013 7222 +3 7222 2013 382 +3 5724 5056 5997 +3 7222 7237 119 +3 7218 2031 2719 +3 4651 3913 7224 +3 7396 2014 7205 +3 2031 2846 7205 +3 2122 6399 1635 +3 5071 2015 7174 +3 1864 3179 366 +3 7174 2015 5601 +3 7174 2017 2261 +3 1817 3015 7140 +3 2017 2888 7140 +3 7086 812 5552 +3 4672 6431 6432 +3 4962 4963 479 +3 2644 4959 2482 +3 2888 2017 7122 +3 7122 2017 7174 +3 7122 2018 290 +3 2602 1011 5568 +3 2611 1012 1902 +3 6118 4803 6064 +3 7116 2019 7113 +3 292 4225 3571 +3 7113 2019 4755 +3 6816 3450 4838 +3 2019 5834 2324 +3 2019 7116 7091 +3 5469 5577 1402 +3 7065 2020 2844 +3 7501 6944 7060 +3 7062 7065 7060 +3 5230 5229 7035 +3 6204 6205 7030 +3 7192 5774 6952 +3 5468 6216 6950 +3 6952 7011 6950 +3 4093 4009 3240 +3 1140 1060 5892 +3 315 6923 2727 +3 776 5690 5399 +3 1977 576 6840 +3 6896 6923 6840 +3 6832 6833 6815 +3 1431 2942 6724 +3 2025 2023 6708 +3 6708 2023 3827 +3 2024 6708 2892 +3 6708 2024 6747 +3 6747 2025 6708 +3 7333 5822 6665 +3 924 2026 6657 +3 7498 204 1233 +3 6657 2026 2874 +3 3280 2346 6858 +3 6665 6702 6657 +3 7283 2028 1931 +3 1931 6654 7283 +3 6954 6917 6617 +3 3501 2029 6609 +3 2576 2254 6609 +3 1849 4944 4448 +3 6124 4001 5703 +3 6589 5835 5531 +3 7031 2030 6575 +3 2461 208 1182 +3 6575 2030 1625 +3 6555 2031 7205 +3 6586 6555 4375 +3 5023 3996 1463 +3 6513 2874 2026 +3 7116 2032 2034 +3 2829 3916 4016 +3 6702 6402 6506 +3 2034 924 6506 +3 2034 2032 6442 +3 7028 7312 6429 +3 4940 4941 3195 +3 6406 434 325 +3 6220 5356 6347 +3 2036 98 6347 +3 6339 6513 2026 +3 2705 4029 3150 +3 1486 484 425 +3 6339 2036 152 +3 6843 5448 2459 +3 5032 1551 2164 +3 876 6429 6338 +3 6338 2036 6347 +3 5718 5717 6327 +3 7434 6935 6277 +3 6310 6327 6277 +3 7250 7260 6246 +3 6158 6159 6210 +3 7458 6809 2350 +3 6147 6210 1739 +3 398 2037 2923 +3 766 2457 6732 +3 2923 6109 398 +3 1694 1430 3126 +3 6622 3039 6105 +3 6485 6484 6056 +3 2415 2454 3180 +3 6105 6109 6056 +3 2889 1799 3363 +3 5370 5369 6022 +3 7443 7062 6011 +3 6022 6053 6011 +3 2038 7008 5966 +3 5882 7054 28 +3 757 2699 1685 +3 2311 3631 6275 +3 3422 7473 4956 +3 2039 5882 5966 +3 3193 6637 4117 +3 5882 2039 2040 +3 5819 3176 131 +3 5882 2040 7054 +3 4927 2424 414 +3 1343 6390 5652 +3 755 2125 3592 +3 947 1726 2769 +3 2041 5812 2043 +3 4735 4267 5812 +3 991 2042 5812 +3 2042 5859 2043 +3 2043 5812 2042 +3 2525 3285 5710 +3 2043 4736 2041 +3 1331 5231 705 +3 5108 423 2156 +3 5602 4797 1993 +3 3983 1911 3607 +3 2931 4421 1499 +3 4508 3771 3191 +3 2265 7353 3729 +3 1879 2047 5787 +3 1516 5785 5706 +3 6905 4919 4132 +3 56 2071 5765 +3 1659 444 3140 +3 5785 5787 5765 +3 7504 7101 5727 +3 5627 5270 485 +3 5041 4914 4634 +3 7328 6722 5719 +3 5727 5756 5719 +3 7326 7323 5700 +3 6933 7373 5698 +3 2452 4774 6557 +3 2789 4909 1927 +3 4671 2050 5678 +3 5678 2050 5661 +3 2078 3447 6832 +3 5678 2074 4671 +3 5671 2074 1 +3 1742 5894 7382 +3 1599 4562 6914 +3 2053 5647 1967 +3 7382 2058 5593 +3 4909 1434 2711 +3 5593 2058 5666 +3 366 3179 3183 +3 5593 2059 7382 +3 5593 2053 2059 +3 4903 4904 5102 +3 2066 6302 5590 +3 1751 1730 1727 +3 4900 4901 3739 +3 5562 3771 6794 +3 2066 1111 5562 +3 5549 3072 169 +3 2066 5549 169 +3 5549 2066 5590 +3 5475 7032 3717 +3 2067 6681 5513 +3 5477 3393 2164 +3 5284 5920 3867 +3 2067 718 5477 +3 2467 2067 5513 +3 5513 5434 2467 +3 6505 7410 5994 +3 4760 4756 5375 +3 115 5375 465 +3 2071 5327 2866 +3 7027 7026 5318 +3 5327 5344 5318 +3 2072 5294 2076 +3 5294 2072 6604 +3 2076 6605 2072 +3 2076 7367 5285 +3 5274 2074 5678 +3 2900 2076 5294 +3 5294 5274 2900 +3 5571 6117 5270 +3 4723 5179 2928 +3 490 5248 4377 +3 1560 113 6579 +3 5869 2151 5248 +3 2078 5247 2080 +3 5247 2078 6815 +3 3737 2080 5247 +3 2080 4907 2078 +3 1726 947 6697 +3 6994 3940 3102 +3 3050 2042 991 +3 274 5136 1455 +3 4889 1381 737 +3 5121 2084 2956 +3 7255 1212 1770 +3 3559 2688 3601 +3 5153 5121 1278 +3 4877 4878 2218 +3 5180 5546 4143 +3 2771 2569 736 +3 5242 2087 5069 +3 2087 731 5095 +3 5069 5095 14 +3 4816 2088 954 +3 954 5055 4816 +3 6608 4225 292 +3 6094 1270 4874 +3 3928 3658 4357 +3 4639 4234 4972 +3 6095 4889 4911 +3 4906 1456 4040 +3 4906 4911 1411 +3 6142 4872 737 +3 4439 2089 4883 +3 1585 6902 1275 +3 3202 5991 1810 +3 4883 2093 4439 +3 2090 4871 4185 +3 2093 481 4871 +3 5462 3118 2508 +3 33 2330 2093 +3 4616 2102 2077 +3 840 3288 2083 +3 4049 5729 4869 +3 3509 2389 6505 +3 33 2093 4883 +3 4581 3076 2927 +3 4860 4862 341 +3 7100 7265 1194 +3 7472 5756 4825 +3 6500 6410 4802 +3 4825 4870 4802 +3 1778 1779 2856 +3 4205 898 5804 +3 6310 7315 4794 +3 7047 2094 1109 +3 1109 4778 7047 +3 111 1932 4729 +3 2097 4729 2905 +3 4729 2097 4794 +3 4729 4794 3790 +3 7064 7063 4728 +3 7443 2906 4693 +3 5166 2587 1801 +3 6200 4280 460 +3 798 1568 206 +3 4432 7018 6005 +3 2887 930 2555 +3 2099 4687 2906 +3 6049 864 866 +3 4687 2099 4728 +3 4674 6586 265 +3 4674 2100 2719 +3 6053 7218 4644 +3 3183 2447 366 +3 4644 2100 2099 +3 2105 2101 5142 +3 5142 4595 2105 +3 721 3584 935 +3 2101 2105 44 +3 4616 2105 1493 +3 242 443 2490 +3 1751 1727 2790 +3 4594 5681 5392 +3 4594 3033 5113 +3 4578 2225 1316 +3 4578 4550 858 +3 4578 2109 3328 +3 1993 4797 2981 +3 4550 2111 858 +3 4550 4578 1316 +3 4491 2114 6114 +3 2116 4483 2159 +3 4491 4517 4483 +3 5657 6094 1271 +3 7277 7276 4469 +3 5500 2123 4469 +3 6900 2119 2911 +3 4425 2120 4455 +3 4455 2120 2773 +3 1762 2122 4425 +3 4455 2123 4425 +3 5113 3033 157 +3 3925 2124 4413 +3 2124 6213 2912 +3 5535 1586 2445 +3 4413 2126 3925 +3 1282 4393 157 +3 6505 2389 7410 +3 4393 2126 753 +3 4389 2126 4413 +3 2127 2558 4380 +3 1770 6326 7255 +3 4845 4846 1488 +3 2433 3104 4936 +3 6096 2845 4283 +3 4213 4727 4359 +3 4359 4374 4380 +3 7483 7482 4355 +3 5342 7397 4319 +3 4343 4355 4319 +3 7487 7488 4316 +3 6617 6654 4282 +3 4843 311 1298 +3 7389 7391 4269 +3 12 4316 4269 +3 4401 1876 2121 +3 5959 5064 4214 +3 2128 4214 5064 +3 3777 2931 2680 +3 4559 471 1729 +3 2129 4180 2130 +3 4180 2129 6577 +3 4161 2130 4180 +3 2130 3958 2129 +3 3104 2433 3466 +3 4180 4214 2128 +3 2128 4161 4180 +3 469 1623 4882 +3 7182 2132 4150 +3 2132 1143 4135 +3 2443 2512 6005 +3 2133 4135 5451 +3 4135 2133 4150 +3 1890 7447 4118 +3 4118 2134 1890 +3 2742 7053 4918 +3 3213 5396 7146 +3 5700 5698 4116 +3 2134 2915 4116 +3 2134 4118 4112 +3 2434 1865 6680 +3 4112 2915 2134 +3 2914 5176 3222 +3 5200 5197 4081 +3 2628 2579 1059 +3 7030 7035 4004 +3 4041 4081 4004 +3 4109 4268 4003 +3 2940 6380 2192 +3 3373 2136 320 +3 320 3999 3373 +3 5088 77 3664 +3 4145 3008 3990 +3 3999 4003 3990 +3 7011 5218 3932 +3 5854 5187 3926 +3 3932 3979 3926 +3 7411 7408 3923 +3 4343 7208 3900 +3 2639 2335 455 +3 7480 6666 3891 +3 3900 3923 3891 +3 2443 5617 6872 +3 6727 2139 2145 +3 6856 2140 3838 +3 2140 6859 2342 +3 3837 2142 3838 +3 3727 5976 2573 +3 3838 2142 6856 +3 4250 3221 2142 +3 3838 2145 3837 +3 3837 2145 2139 +3 4982 5055 3834 +3 3784 5852 3036 +3 4894 5426 2492 +3 1638 4762 5707 +3 6846 2676 4630 +3 569 2146 3763 +3 3763 2146 2347 +3 3763 3784 1251 +3 6328 2147 3750 +3 3750 2147 6325 +3 3505 3280 2117 +3 2152 3750 2685 +3 2149 2148 3743 +3 4076 4159 7514 +3 3737 2149 3743 +3 3108 5615 4260 +3 3690 4225 3590 +3 5247 2151 2149 +3 2800 3802 1210 +3 7514 2916 4163 +3 3737 3743 2918 +3 3853 2154 7083 +3 4826 4827 4745 +3 6662 2158 2923 +3 2923 2158 6109 +3 153 521 2189 +3 2393 3606 775 +3 765 7149 3934 +3 2159 419 2116 +3 2942 7016 5653 +3 2942 1652 6724 +3 2943 1803 128 +3 3978 2354 2960 +3 551 5584 5971 +3 2165 2976 379 +3 2895 5999 3504 +3 6649 4272 2925 +3 2166 3938 142 +3 871 6456 4823 +3 2167 4156 4142 +3 3011 4167 1502 +3 3011 2168 6285 +3 711 360 1170 +3 1611 3015 6870 +3 3015 2170 7140 +3 978 7242 5379 +3 811 5105 2054 +3 153 4633 5259 +3 3033 2171 1282 +3 3339 827 3043 +3 161 5193 2208 +3 2173 3598 167 +3 5861 2174 4504 +3 6872 2512 2443 +3 704 5240 368 +3 4753 3709 2981 +3 209 3054 3273 +3 3072 2177 34 +3 34 2177 5084 +3 3242 1391 2180 +3 3203 2182 281 +3 2663 6461 612 +3 5158 1561 1140 +3 378 6556 2646 +3 366 3150 1864 +3 7220 3281 6483 +3 3586 1208 5599 +3 57 5261 2990 +3 3535 1477 2970 +3 2189 3119 153 +3 759 3106 4933 +3 3106 2185 5813 +3 3267 2188 558 +3 5680 2191 3130 +3 3130 2191 2702 +3 37 838 4752 +3 2666 5511 2271 +3 2192 1382 2940 +3 5473 3131 5471 +3 38 206 1568 +3 2194 6762 1677 +3 2741 1449 2380 +3 2195 3132 122 +3 6196 2474 2439 +3 1578 6776 504 +3 5372 6558 3141 +3 1963 3434 7129 +3 5213 2198 3143 +3 39 186 6195 +3 1976 712 5568 +3 5409 6265 2455 +3 5409 2252 6265 +3 471 4092 7139 +3 3281 127 7496 +3 2696 6086 614 +3 2639 2474 2770 +3 2203 347 348 +3 347 2203 3861 +3 1497 5680 3130 +3 1497 2580 6582 +3 2207 236 1399 +3 1568 3480 182 +3 3375 1544 227 +3 4200 426 2220 +3 4432 2574 7018 +3 6668 7242 6103 +3 2220 211 4200 +3 2208 6468 342 +3 4662 2414 3229 +3 4812 6571 4808 +3 7378 1957 1212 +3 6679 6752 1929 +3 2419 6 2159 +3 5592 2211 364 +3 2573 7508 5985 +3 7378 7255 1452 +3 1710 3675 5000 +3 5732 2213 1372 +3 1907 4067 2746 +3 1568 182 38 +3 3842 4875 306 +3 5110 4829 4806 +3 1743 3066 2812 +3 5281 6692 3314 +3 1489 1301 3197 +3 6569 2216 2726 +3 4048 1745 2578 +3 207 2217 675 +3 3054 2219 3273 +3 3304 464 2826 +3 3974 5143 2431 +3 2222 216 506 +3 2222 3292 215 +3 7459 2491 7456 +3 7255 4216 1452 +3 3102 3940 5616 +3 2223 1239 1044 +3 579 3319 219 +3 43 220 6062 +3 3328 2225 4578 +3 2524 3436 5524 +3 4568 6632 5895 +3 3669 2287 552 +3 7039 3172 5165 +3 3749 511 5810 +3 5482 223 3349 +3 5644 2230 3362 +3 3362 2230 1476 +3 4255 2231 3373 +3 4108 2232 1127 +3 369 4001 5317 +3 4119 2234 1346 +3 2234 976 3697 +3 4161 232 59 +3 891 3412 5210 +3 2621 3304 2826 +3 7320 1690 3983 +3 2430 6138 1304 +3 687 2007 5081 +3 1580 3433 6784 +3 5619 2883 6165 +3 4323 239 3433 +3 5548 243 67 +3 5691 2240 3437 +3 2240 6075 282 +3 3370 1240 2612 +3 6373 1991 1765 +3 634 2243 4714 +3 246 6741 410 +3 1991 4169 1765 +3 248 5782 178 +3 5135 886 6426 +3 683 1644 4052 +3 3472 248 0 +3 3148 7043 4244 +3 1961 4468 1971 +3 467 2248 4356 +3 4665 6527 4791 +3 2248 4453 396 +3 6896 2021 2253 +3 2253 5358 549 +3 6609 2254 3501 +3 4960 5709 788 +3 1595 54 6831 +3 57 269 5261 +3 3621 270 58 +3 2622 5083 4789 +3 5599 4087 3586 +3 1613 138 5931 +3 1455 3550 274 +3 272 4782 4539 +3 4539 3555 272 +3 3508 2267 3986 +3 1458 4926 6493 +3 3126 5276 1694 +3 1262 2337 4339 +3 7437 4579 6965 +3 3583 4677 4749 +3 7267 6101 4782 +3 3583 2271 6812 +3 6608 4780 130 +3 2272 525 5124 +3 2273 2275 5970 +3 741 285 7444 +3 5570 290 3613 +3 2607 3870 1730 +3 2283 7122 290 +3 1548 3680 3338 +3 3245 4468 1961 +3 5842 2284 3630 +3 7222 2286 3635 +3 3635 2286 6433 +3 4040 6876 4906 +3 3648 2287 4970 +3 4607 2288 585 +3 2288 3678 304 +3 864 6282 7372 +3 2289 3712 2291 +3 3715 2291 3712 +3 2932 1481 1453 +3 1453 5740 1114 +3 3794 6103 6913 +3 3661 2980 1972 +3 1972 2980 5269 +3 956 4776 4779 +3 668 4773 4593 +3 2294 618 4686 +3 3304 4518 3042 +3 3396 4976 3063 +3 5178 4897 4771 +3 2277 317 4193 +3 1189 6065 5933 +3 3372 3845 340 +3 5747 3811 3744 +3 2563 3386 5061 +3 5853 2804 7082 +3 3787 2304 3789 +3 2305 3792 2538 +3 2334 1473 1908 +3 2595 2845 5409 +3 329 2306 40 +3 2306 3811 330 +3 4401 5383 310 +3 7456 2491 3813 +3 5383 2309 310 +3 4029 2720 5171 +3 3602 2892 3827 +3 6795 2980 3121 +3 6055 2312 3840 +3 6320 1712 3453 +3 5488 5501 5531 +3 6218 2313 6474 +3 7083 2315 3853 +3 4726 3859 345 +3 4563 2317 3864 +3 2548 3909 357 +3 3912 2726 2216 +3 3912 7155 5280 +3 3936 3762 4979 +3 3936 3559 3762 +3 6480 2319 3937 +3 4212 7008 4761 +3 6461 3870 612 +3 3937 2319 7435 +3 818 3943 5007 +3 2158 300 6056 +3 4246 2321 4717 +3 4863 6553 1734 +3 7437 5563 2388 +3 5715 3762 3601 +3 5951 878 1198 +3 4151 5196 4353 +3 3878 1115 4006 +3 5490 1023 3974 +3 3306 2405 4017 +3 2569 4303 5599 +3 5375 4756 2520 +3 390 2326 4039 +3 4039 2326 5252 +3 7004 1918 1556 +3 843 7111 5097 +3 5628 7227 2534 +3 5013 2327 4071 +3 2327 1594 1311 +3 4078 4219 2975 +3 1127 2328 4108 +3 4108 2328 7106 +3 67 399 5548 +3 7270 2537 5978 +3 4559 4092 471 +3 733 5106 471 +3 4360 1045 557 +3 1473 2334 663 +3 523 2336 4139 +3 2812 3066 1908 +3 2339 566 406 +3 2339 3344 4154 +3 2340 562 397 +3 5649 1572 6770 +3 413 6078 2640 +3 3682 3376 6394 +3 6355 6899 945 +3 3684 4776 4744 +3 4171 3420 4273 +3 3865 7130 7136 +3 655 2422 1193 +3 3399 6411 4751 +3 7368 1056 866 +3 4163 6949 6153 +3 6887 2352 4195 +3 4195 2352 4493 +3 5599 2746 4087 +3 4195 4493 4492 +3 4267 4735 4079 +3 7310 2353 4207 +3 4207 2353 2395 +3 2092 2355 4969 +3 430 2356 4217 +3 4217 433 430 +3 439 2357 4243 +3 2357 4242 440 +3 442 23 2360 +3 3373 2361 4255 +3 2230 1075 2940 +3 780 4732 2008 +3 452 6499 6383 +3 3697 6375 4276 +3 230 4277 459 +3 4049 4869 645 +3 1041 4277 5267 +3 6808 1215 2757 +3 86 2365 4292 +3 4292 2365 7343 +3 4663 7177 4307 +3 2507 462 1541 +3 6876 4040 4702 +3 3853 2315 6825 +3 4948 2367 4329 +3 4329 2367 6694 +3 2368 7468 2369 +3 2369 4347 2368 +3 7061 2371 4347 +3 2374 4357 299 +3 970 4358 5354 +3 5845 2375 4370 +3 4370 2375 4368 +3 3369 1141 4371 +3 1217 4373 5988 +3 2110 1491 47 +3 490 482 2984 +3 1551 5032 6336 +3 7136 5504 3865 +3 5408 2378 4378 +3 4722 5485 3218 +3 4732 2382 266 +3 640 6130 1950 +3 5663 7226 4718 +3 2003 2790 5589 +3 5978 7385 7270 +3 1437 504 1579 +3 4412 5071 255 +3 1738 510 6407 +3 7322 4360 5040 +3 4430 5944 3320 +3 2387 4437 519 +3 4437 2387 6174 +3 3652 3803 1816 +3 5112 4458 528 +3 4326 3473 1019 +3 1412 3427 1424 +3 3317 7137 4713 +3 40 2390 4465 +3 2416 1651 6443 +3 2390 4700 604 +3 5211 356 5819 +3 2391 4467 4955 +3 6591 1504 2392 +3 2392 4482 4703 +3 4207 2395 4492 +3 4700 4706 487 +3 4492 2395 4195 +3 7494 543 4493 +3 7349 2396 4504 +3 3310 3772 6115 +3 2827 7300 1814 +3 441 5620 681 +3 2006 2415 3180 +3 3212 3009 1489 +3 4695 4696 5640 +3 1546 1995 4867 +3 3465 2400 554 +3 2423 7303 381 +3 7084 1966 7074 +3 7379 2551 3342 +3 7211 2534 7227 +3 560 6793 2344 +3 6420 36 1416 +3 4541 2401 5011 +3 5101 774 2460 +3 571 2402 4563 +3 1744 5922 5762 +3 3147 2526 4574 +3 2403 4592 575 +3 4592 2403 1081 +3 2404 4606 581 +3 2404 4605 582 +3 4017 2405 4609 +3 4609 2405 4608 +3 1868 4615 2849 +3 7061 7340 1835 +3 1388 4627 6386 +3 4627 2407 4629 +3 2408 4629 597 +3 2054 6250 7321 +3 625 4692 5982 +3 2410 4661 605 +3 4661 2410 4858 +3 42 607 643 +3 4663 607 4664 +3 1296 609 6195 +3 4667 2411 4666 +3 938 1704 3102 +3 5420 4682 3228 +3 4753 4797 1452 +3 6273 6394 3211 +3 3229 2414 4689 +3 5181 319 5027 +3 4689 2414 624 +3 4228 2551 5047 +3 1704 1903 6994 +3 4931 2415 2001 +3 2001 2415 7294 +3 1649 2416 4710 +3 4710 2416 5915 +3 2413 4685 4684 +3 2417 1951 460 +3 2363 5814 3985 +3 4725 2110 1493 +3 3090 725 4896 +3 1856 1707 3819 +3 3934 7149 3929 +3 2422 655 1952 +3 37 4752 4747 +3 7303 657 4752 +3 666 2425 668 +3 2425 4775 673 +3 2758 594 6052 +3 1718 6132 7143 +3 2426 683 682 +3 683 2426 1644 +3 3992 1738 7176 +3 1192 2429 4800 +3 2430 4801 688 +3 4801 2430 6074 +3 1221 3629 1467 +3 4007 2431 4805 +3 5006 2637 4813 +3 937 4816 5266 +3 6309 1359 5028 +3 5088 2432 77 +3 6265 6305 2995 +3 705 77 2432 +3 7383 4832 1804 +3 2258 2564 7155 +3 4832 2434 6681 +3 4406 4619 4683 +3 1488 4846 1544 +3 7115 943 6587 +3 2784 3889 2941 +3 6882 2373 4993 +3 3253 3998 4406 +3 6877 2437 4851 +3 7000 2493 4836 +3 4976 3396 3706 +3 4333 5066 992 +3 716 2440 4856 +3 4837 5022 5078 +3 6805 2442 2445 +3 3365 2445 78 +3 3600 5533 3012 +3 2102 4616 47 +3 6570 2446 1270 +3 2448 4888 735 +3 4888 2448 4890 +3 497 4896 4893 +3 742 2450 4897 +3 4677 4678 4749 +3 4912 4937 764 +3 4504 2600 5861 +3 2125 4923 4389 +3 6581 5295 4676 +3 2001 2453 4931 +3 3106 2454 4933 +3 4934 760 83 +3 763 2457 4937 +3 1315 2603 2505 +3 1183 767 2614 +3 6470 1087 1802 +3 773 5839 245 +3 2479 6857 5617 +3 4943 1463 3996 +3 7485 2461 1179 +3 1179 2461 5921 +3 7043 3148 4060 +3 4948 4329 777 +3 780 6401 4952 +3 4732 780 4951 +3 4952 784 4951 +3 4672 6432 3446 +3 648 4576 2570 +3 788 2466 4960 +3 4960 2466 5937 +3 5684 3570 4424 +3 6792 4376 7085 +3 5929 796 86 +3 3628 6038 6957 +3 7428 6165 92 +3 4202 6270 6974 +3 3018 2998 2623 +3 934 4804 3761 +3 3509 3345 2959 +3 1654 3515 4346 +3 7087 960 1268 +3 92 6763 1797 +3 6897 2663 2578 +3 648 2570 6470 +3 5933 2475 5002 +3 2475 5399 814 +3 7080 2683 5003 +3 2922 5006 4813 +3 6857 2479 5006 +3 3943 2480 5007 +3 1208 3586 1079 +3 5007 2480 7478 +3 819 3984 2840 +3 5628 2485 5009 +3 5009 2485 6539 +3 2486 5013 4071 +3 5013 2486 2807 +3 1674 5987 4910 +3 5846 919 5251 +3 5233 2487 5028 +3 5028 2487 7387 +3 4914 5041 5036 +3 3339 2226 5051 +3 830 194 2489 +3 4899 2566 156 +3 5058 2489 5063 +3 1079 3586 3441 +3 7425 1090 3236 +3 6116 2878 6902 +3 5837 3659 5082 +3 7236 2554 7206 +3 2836 2952 629 +3 5088 3265 3122 +3 3122 2560 5088 +3 7111 2494 5097 +3 5097 2494 7363 +3 5101 2497 5105 +3 4072 3681 3696 +3 2499 5111 850 +3 5111 2499 5114 +3 4352 2500 5128 +3 3468 2625 5131 +3 5128 2500 5132 +3 1122 5170 875 +3 298 4667 4666 +3 1468 5171 6507 +3 60 3723 1142 +3 5195 5634 1514 +3 1324 3025 2109 +3 5195 2501 5196 +3 4151 885 5196 +3 2503 5212 892 +3 3143 2504 5213 +3 1444 2248 467 +3 4187 2505 2412 +3 900 6381 649 +3 5245 1716 2507 +3 4624 3723 242 +3 2508 914 2938 +3 4727 5918 5906 +3 2075 7178 6901 +3 914 4348 910 +3 3992 2509 5251 +3 2496 1087 3384 +3 4820 4753 1452 +3 4433 3591 2921 +3 2513 5256 927 +3 4630 2872 1607 +3 5256 2513 324 +3 939 836 4669 +3 3591 7470 1121 +3 5221 5940 6284 +3 2410 3584 721 +3 941 5526 3316 +3 663 2721 6516 +3 351 5304 951 +3 2516 5380 953 +3 3358 961 5313 +3 5949 5435 4658 +3 5507 3730 4633 +3 2347 2518 3763 +3 2148 5322 3743 +3 5856 2523 5329 +3 5329 2523 5328 +3 4574 2526 5333 +3 7269 1624 1780 +3 4478 5345 968 +3 487 7161 4653 +3 5345 4478 7291 +3 1122 4647 880 +3 212 1821 2657 +3 2529 5361 974 +3 6016 4326 6019 +3 3587 1511 2420 +3 5361 2529 5360 +3 5935 4381 4967 +3 6817 2544 1534 +3 2554 4739 7208 +3 769 4354 5159 +3 5249 4887 6903 +3 6603 2309 91 +3 1104 4283 3096 +3 2535 5390 984 +3 5400 5686 1096 +3 2535 984 990 +3 2443 2617 2479 +3 3964 4050 2749 +3 972 5818 1690 +3 2112 2678 1847 +3 5851 2539 5419 +3 6043 5817 4642 +3 5419 2539 5422 +3 91 995 6603 +3 5429 2532 792 +3 4672 3594 6431 +3 2541 5759 1126 +3 2081 5447 1006 +3 1717 2543 2273 +3 3144 3444 6284 +3 5463 2543 5465 +3 1016 5909 5471 +3 3096 3290 5597 +3 2821 3228 7010 +3 6874 942 4306 +3 3341 2054 7321 +3 5490 2545 5489 +3 3909 2548 5512 +3 4050 3964 1119 +3 5969 2550 5522 +3 2550 5520 1030 +3 331 1036 3979 +3 2558 93 2913 +3 3334 7301 5087 +3 2559 6457 1438 +3 5663 4718 4638 +3 2749 4414 3964 +3 5171 2560 3122 +3 2082 6453 4636 +3 2561 1276 2223 +3 2562 5566 3888 +3 5566 2562 5569 +3 1809 4470 5572 +3 2889 2565 5591 +3 1054 2568 5592 +3 3376 3682 5527 +3 867 2575 1068 +3 3965 1062 5596 +3 7357 2572 1843 +3 1843 2572 5603 +3 598 4628 7454 +3 6692 3388 4341 +3 5208 5573 5603 +3 3197 1684 5484 +3 3675 1710 816 +3 2575 1542 1068 +3 1542 2575 6698 +3 6274 2576 6609 +3 4626 6268 5721 +3 1371 1877 4489 +3 3362 5648 5644 +3 5553 2605 2345 +3 3594 2826 3618 +3 5062 1494 5659 +3 2722 943 6588 +3 1441 1966 6988 +3 3965 2579 1093 +3 3130 2580 1497 +3 5400 2581 5686 +3 5872 381 7518 +3 3764 4422 596 +3 898 3009 3212 +3 5686 2581 6037 +3 1315 3007 4194 +3 7450 2709 2441 +3 5907 5235 644 +3 4621 4622 3107 +3 2498 5105 811 +3 2345 2605 1703 +3 1115 2585 5741 +3 5741 2585 5740 +3 5749 2586 5748 +3 1127 2232 5764 +3 2502 2587 5252 +3 7194 2588 5766 +3 5766 2588 5769 +3 1245 1130 43 +3 7005 7099 722 +3 1758 3482 1235 +3 6192 5309 1814 +3 4364 204 5770 +3 5607 2592 5771 +3 2274 2501 1071 +3 113 5811 3343 +3 4752 838 1939 +3 5771 2592 6822 +3 1141 2594 5140 +3 7303 4752 1939 +3 5000 1100 1710 +3 7074 1158 7084 +3 998 5772 5791 +3 5791 5772 5793 +3 5143 765 2431 +3 1661 1658 1662 +3 2599 7025 1656 +3 2712 2999 1648 +3 1618 7523 307 +3 7219 2153 7512 +3 5813 2601 5861 +3 356 5211 1060 +3 5825 5827 1152 +3 1729 4577 4559 +3 1585 4953 2604 +3 2639 2691 2335 +3 5040 1363 1642 +3 590 6615 5380 +3 7513 3643 2998 +3 4370 4367 5845 +3 5845 4367 5843 +3 4610 4611 3776 +3 3114 889 6704 +3 3545 5589 7141 +3 2931 2950 4421 +3 6478 6373 4770 +3 1165 2608 5851 +3 5851 2608 5852 +3 143 105 7158 +3 1501 5887 6590 +3 1501 5886 5887 +3 2612 5899 3370 +3 5065 2613 5899 +3 6033 1469 6024 +3 5899 2613 3767 +3 4485 3846 639 +3 5007 7478 5917 +3 1178 5284 4833 +3 2614 5923 1183 +3 2624 5930 1186 +3 587 4608 720 +3 5930 2624 5932 +3 5131 2625 1191 +3 2625 5935 6300 +3 582 4605 219 +3 785 2644 6072 +3 6228 5947 1681 +3 5956 6160 813 +3 2249 2663 612 +3 222 2627 5957 +3 5957 2627 5959 +3 5962 2628 5964 +3 3145 3228 4682 +3 5005 4600 4777 +3 1211 1558 989 +3 1360 2632 5983 +3 4596 4597 1220 +3 5988 4373 21 +3 5988 2633 6045 +3 7467 7399 7469 +3 3595 7121 250 +3 6546 5849 1164 +3 4813 2637 6009 +3 6010 1229 97 +3 6719 4588 6372 +3 2968 1727 3870 +3 1231 5614 6025 +3 4026 7217 1137 +3 2964 5173 4585 +3 1238 2640 6037 +3 4582 5657 1271 +3 6439 2695 6041 +3 5396 4984 6034 +3 3840 2642 6055 +3 3685 6061 1243 +3 220 2643 6062 +3 6062 2643 6280 +3 6068 3464 1248 +3 7341 7018 3968 +3 1751 4340 6526 +3 6072 5937 785 +3 1249 926 6073 +3 6073 926 2662 +3 2647 6080 1256 +3 2647 6083 1260 +3 4582 1271 1266 +3 7460 6103 2872 +3 7203 2661 2771 +3 6850 6863 7198 +3 6114 4243 5004 +3 6186 2651 1286 +3 1286 2651 6160 +3 3152 1963 125 +3 88 2690 6168 +3 1158 7500 7084 +3 5050 6834 3991 +3 6179 2655 4239 +3 4239 6091 6179 +3 186 2656 6195 +3 2656 6199 1297 +3 6947 2658 6199 +3 6199 2658 1297 +3 5193 2660 6206 +3 6206 2660 6208 +3 6073 2662 6209 +3 2662 7414 1875 +3 2121 6594 2638 +3 6347 98 6220 +3 5523 5356 6220 +3 3524 3651 2436 +3 5511 2666 6223 +3 6223 2666 6225 +3 2632 1322 6322 +3 3642 2669 6239 +3 6239 2669 6242 +3 4853 2673 1327 +3 5073 5320 2926 +3 1041 2679 6252 +3 6409 3399 3405 +3 4534 5269 4547 +3 1639 2547 5835 +3 7284 2675 1897 +3 453 6771 3021 +3 6445 2677 1897 +3 7453 1335 99 +3 1847 6261 7362 +3 5478 856 7042 +3 4570 4571 3797 +3 2678 6269 1341 +3 6252 2679 6269 +3 6609 2681 6274 +3 1348 2682 6278 +3 2266 6304 1353 +3 2564 484 1486 +3 5003 2683 1359 +3 6309 2684 5003 +3 6312 6313 2596 +3 2685 6325 1362 +3 6325 2685 3750 +3 6330 1368 461 +3 2965 6343 1373 +3 6343 2965 6342 +3 3991 2741 2380 +3 1330 2532 2638 +3 6349 6352 1376 +3 1377 2692 1379 +3 6320 4330 318 +3 4330 6320 3453 +3 6375 1378 100 +3 1318 6381 6379 +3 1366 474 1699 +3 6270 656 4576 +3 6379 1289 1318 +3 6279 6193 1708 +3 900 1383 6381 +3 4350 7135 4567 +3 1384 7163 435 +3 6041 2695 6385 +3 5355 5264 6390 +3 6390 6392 5355 +3 2698 6393 1396 +3 6393 2698 236 +3 1652 6626 2024 +3 6377 5928 6415 +3 3276 1417 6418 +3 2706 6434 1421 +3 5180 4143 2993 +3 672 1880 615 +3 5617 2443 2479 +3 7121 3595 7123 +3 6949 2618 6444 +3 99 2710 6445 +3 572 2402 679 +3 1927 6446 7505 +3 4451 1926 101 +3 3858 6630 2310 +3 6054 578 6455 +3 6455 578 6457 +3 5305 4560 6552 +3 4665 4791 4556 +3 3898 1608 2715 +3 2715 1608 6466 +3 3632 6284 3444 +3 6466 1443 3561 +3 6058 2716 6497 +3 6148 4555 4547 +3 7497 1919 662 +3 3506 2717 6502 +3 6502 2717 6605 +3 5171 2720 6507 +3 6516 2721 6515 +3 3797 4571 774 +3 4764 1914 3921 +3 6757 6773 2667 +3 3397 5936 2723 +3 6977 4599 5532 +3 3626 5041 4634 +3 1270 6094 6570 +3 6570 6094 5657 +3 2729 6591 2392 +3 4701 4990 4544 +3 5109 6624 6625 +3 733 471 7139 +3 2697 2671 6897 +3 2638 4401 2121 +3 3620 2520 749 +3 5925 2735 6658 +3 7139 5222 733 +3 1710 1100 1853 +3 5868 2736 6659 +3 1330 4188 792 +3 6659 2736 6663 +3 6675 6040 1536 +3 2743 6679 1929 +3 2744 6706 3087 +3 6706 2744 6709 +3 6713 6403 6715 +3 4313 4288 1551 +3 7521 6215 4050 +3 2745 6728 1555 +3 6728 2745 6727 +3 7440 6143 6545 +3 2401 3025 820 +3 6545 1603 7440 +3 3109 2847 6752 +3 6760 6546 5659 +3 2563 5979 5343 +3 480 3164 1457 +3 7321 2265 3341 +3 2747 3253 1569 +3 1492 2748 6770 +3 4540 4577 6526 +3 5048 5221 6284 +3 6351 4538 397 +3 6197 3344 797 +3 2383 1579 6776 +3 3082 5374 2898 +3 7401 4494 4037 +3 2751 6788 1112 +3 5854 2752 6804 +3 1513 2160 2085 +3 1954 6383 4533 +3 1586 2753 6805 +3 554 1668 1998 +3 3593 7127 4720 +3 6807 2754 6808 +3 2770 1653 6266 +3 5116 6297 5586 +3 5204 2760 6814 +3 2619 1523 7464 +3 54 2761 6831 +3 6822 2762 6824 +3 1598 2763 6827 +3 20 1600 2221 +3 1240 2766 6829 +3 6829 6044 1240 +3 1973 588 6306 +3 6845 4170 852 +3 6411 3399 6409 +3 123 6878 1616 +3 7046 5558 1671 +3 6887 1621 4308 +3 4455 2773 6900 +3 6900 2773 6898 +3 6912 2979 6916 +3 6595 2774 6937 +3 6937 2774 6939 +3 4686 2775 1630 +3 1630 2775 7352 +3 2776 6945 7095 +3 2776 6947 1587 +3 5858 2363 6690 +3 2777 1854 1635 +3 1637 6580 3306 +3 3306 6953 1637 +3 6970 4979 3762 +3 2444 2959 5597 +3 6970 2779 2557 +3 1803 2943 1107 +3 5529 6358 4528 +3 7358 5631 4523 +3 3681 4072 1722 +3 1647 2781 7005 +3 7281 5562 6794 +3 7273 7016 1651 +3 4434 1007 1183 +3 2865 1657 5818 +3 6575 2785 7031 +3 2785 1661 1662 +3 4179 881 6222 +3 7040 5301 1667 +3 904 2786 1657 +3 191 1618 7507 +3 5474 5288 1672 +3 4778 2788 7047 +3 7047 2788 5474 +3 4909 2789 7048 +3 4751 6411 2991 +3 2789 7050 1676 +3 105 1680 7158 +3 3609 2792 7297 +3 4381 1037 2468 +3 2573 5976 2314 +3 4347 1683 2837 +3 3606 2406 3469 +3 7108 6985 4522 +3 1653 2770 6690 +3 2796 7067 1688 +3 6313 1722 1650 +3 1689 109 1948 +3 7441 307 6549 +3 2801 7079 6024 +3 3422 1702 1700 +3 7082 7080 1702 +3 4742 7089 2876 +3 7338 2793 7089 +3 3280 6858 2724 +3 6858 2346 3971 +3 2806 7154 1719 +3 7154 2806 7152 +3 7199 6955 4515 +3 6408 2919 5692 +3 4601 4932 5278 +3 2807 1728 1724 +3 1728 2807 7169 +3 7170 6185 699 +3 6932 2811 7172 +3 2811 7323 1830 +3 6767 1737 6296 +3 7398 198 7184 +3 4287 2814 1906 +3 1906 2814 7469 +3 1747 2815 1768 +3 2815 7235 1768 +3 74 1756 7417 +3 5754 1838 1940 +3 5768 7234 1767 +3 6670 6542 771 +3 7196 1746 4513 +3 1776 7246 1772 +3 29 2823 7285 +3 6857 2821 3646 +3 2817 7268 1778 +3 7268 2817 7271 +3 3918 2818 1784 +3 1785 2819 7273 +3 7282 2820 7284 +3 1794 2822 7284 +3 4506 4507 5122 +3 7284 2822 7282 +3 7285 2823 7287 +3 3933 613 661 +3 6121 3228 2821 +3 6273 2825 7295 +3 7295 2825 1809 +3 1576 2141 7507 +3 1815 2827 7153 +3 6834 7092 2741 +3 6478 1142 2155 +3 2919 6408 2174 +3 363 2155 7096 +3 2794 809 3545 +3 1522 2196 1520 +3 2908 3002 85 +3 7304 7471 7442 +3 3395 1332 2816 +3 2652 6560 4502 +3 109 2830 1948 +3 660 5404 4499 +3 2760 5436 4757 +3 1824 2830 7310 +3 6865 4498 4497 +3 6328 2832 1829 +3 1829 2832 7354 +3 3499 1703 6844 +3 7340 7338 1835 +3 7061 2837 7340 +3 2493 6579 1912 +3 7343 2838 7345 +3 5696 2839 7345 +3 4504 6408 7349 +3 2841 7360 1844 +3 7360 2841 7362 +3 5587 2843 1857 +3 7167 2844 7381 +3 4520 4284 7180 +3 7205 2846 7396 +3 2849 7406 1868 +3 7406 2849 7405 +3 2025 2022 4490 +3 6253 2850 7412 +3 7413 6592 559 +3 110 2850 7414 +3 5837 2808 380 +3 2852 7439 2854 +3 7342 2854 7439 +3 1603 3042 7440 +3 1703 3499 7083 +3 7440 3042 4518 +3 3600 2855 7447 +3 5807 2856 7452 +3 7452 2856 7455 +3 5576 287 2749 +3 7455 4531 2510 +3 2860 7462 5140 +3 1760 650 1770 +3 1770 1212 1760 +3 7462 2860 7465 +3 805 2859 2910 +3 1179 2861 7485 +3 7485 2861 7486 +3 4763 3662 915 +3 7495 7278 7497 +3 1371 4489 5005 +3 2866 7502 2071 +3 2866 7501 1922 +3 783 3720 131 +3 1933 7505 1928 +3 2069 7283 5344 +3 1513 4905 2160 +3 1618 7441 3634 +3 1949 3807 1947 +3 2869 2060 1742 +3 2060 2869 7147 +3 7147 2870 2060 +3 6589 614 6086 +3 6767 761 3240 +3 2871 6464 1955 +3 6464 2871 6214 +3 4186 2874 1989 +3 1989 2874 6513 +3 4939 7149 765 +3 1992 2877 1967 +3 5647 2052 3716 +3 3716 2052 1965 +3 3230 6942 4487 +3 4703 4481 2392 +3 5658 2577 5761 +3 2577 5389 2879 +3 2879 5761 2577 +3 5394 2533 2880 +3 2533 2621 6479 +3 2186 2808 3714 +3 3018 4882 2998 +3 7410 2514 5994 +3 1978 2881 4654 +3 2602 7305 76 +3 4654 2881 4740 +3 1102 2858 6136 +3 3125 2760 3038 +3 7101 2882 4390 +3 2882 4451 1984 +3 1906 4294 4287 +3 2884 3841 1990 +3 3841 2884 3812 +3 1267 1964 5518 +3 5518 1964 7038 +3 2886 7272 2004 +3 7272 2886 7294 +3 2014 5824 7205 +3 4796 4640 4479 +3 7205 5824 6555 +3 2664 1915 3079 +3 5601 2018 7122 +3 7122 7174 5601 +3 2283 2888 7122 +3 2034 7091 7116 +3 5059 5595 2565 +3 3827 2892 6708 +3 2892 6724 2024 +3 6442 924 2034 +3 5356 2894 6347 +3 6347 2894 6338 +3 5966 7006 2039 +3 1373 5246 174 +3 2555 3606 2393 +3 5882 2038 5966 +3 5630 6731 4474 +3 5812 2041 4735 +3 5812 4267 991 +3 3277 4510 3761 +3 3277 168 2044 +3 1489 2002 1301 +3 1993 2794 5602 +3 2044 2899 732 +3 5661 2900 5678 +3 5678 2900 5274 +3 5666 2901 5593 +3 6691 5549 5590 +3 2959 3345 5023 +3 6680 5434 5513 +3 6604 2902 5294 +3 1506 4404 568 +3 5294 2902 5274 +3 6815 2151 5247 +3 5443 2847 2335 +3 5065 3154 2764 +3 2905 4778 2097 +3 4693 2906 4687 +3 2906 4644 2099 +3 4757 4179 3038 +3 7426 5559 734 +3 5142 5469 4595 +3 4244 1039 3148 +3 916 163 1158 +3 7002 163 916 +3 2911 4455 6900 +3 2912 4413 2124 +3 947 2903 6719 +3 4413 2912 4389 +3 7157 6017 7160 +3 3677 816 3573 +3 4471 4472 4850 +3 2913 4380 2558 +3 4818 6326 1770 +3 4380 2913 4359 +3 6577 4214 4180 +3 4955 533 2391 +3 7428 125 7129 +3 2855 4118 7447 +3 4118 2914 4112 +3 6803 2915 4112 +3 2917 3838 2140 +3 3743 5322 962 +3 6121 2922 4297 +3 7219 5589 2790 +3 7290 3678 606 +3 6512 2930 4059 +3 3181 4730 3772 +3 5430 4700 2390 +3 6671 5934 3453 +3 1917 2920 2184 +3 2184 658 6448 +3 2921 7075 515 +3 7075 2921 1121 +3 5585 7068 7180 +3 2315 7083 3499 +3 1530 2037 3331 +3 422 3394 6465 +3 7366 6465 3394 +3 6624 2924 1181 +3 1181 2924 6919 +3 6685 3573 816 +3 3536 2925 6959 +3 4522 2927 7108 +3 5169 2928 2370 +3 6469 5890 4462 +3 4059 2930 4026 +3 2950 2931 3777 +3 4026 2930 4587 +3 5501 5488 610 +3 6166 2169 2932 +3 2933 2809 3027 +3 528 4456 1883 +3 4452 4453 1444 +3 2809 2933 3868 +3 122 7470 346 +3 3474 2934 3647 +3 3647 2934 5423 +3 6844 2236 3499 +3 6232 6124 3255 +3 585 1831 4607 +3 1831 2938 914 +3 3848 2939 7311 +3 7311 2939 7493 +3 2940 3031 2230 +3 3031 2940 1382 +3 367 6191 3978 +3 2457 2941 482 +3 6738 7353 7321 +3 457 2943 128 +3 128 2867 457 +3 3274 2944 6673 +3 5066 4333 2045 +3 6673 2944 7289 +3 4564 2945 2626 +3 2626 2945 1413 +3 14 5095 232 +3 4769 2946 124 +3 124 2946 1375 +3 2571 1033 2187 +3 3642 6239 1258 +3 2378 443 1137 +3 3985 5435 5198 +3 6139 2890 2858 +3 1430 5938 1869 +3 6115 3290 3310 +3 3668 963 3399 +3 3208 2951 1804 +3 2995 3333 3146 +3 1804 2951 3361 +3 128 2944 2867 +3 5023 5597 2959 +3 4421 2950 1314 +3 992 833 4333 +3 5439 2954 660 +3 660 2954 5405 +3 7463 2957 4822 +3 4822 2957 5786 +3 6628 2958 3215 +3 367 427 6065 +3 4442 4444 3944 +3 7108 2927 1295 +3 135 5343 2027 +3 3873 2962 6473 +3 3263 4705 4299 +3 1763 4536 1129 +3 120 959 4589 +3 7450 6016 2709 +3 2609 4956 6230 +3 5938 1430 1694 +3 4296 174 457 +3 5246 4271 174 +3 3361 2966 254 +3 254 2966 401 +3 2954 2967 4701 +3 3111 7344 4579 +3 2742 4918 134 +3 6736 669 7 +3 4701 2967 4994 +3 5784 4560 831 +3 4038 7336 4410 +3 6629 2969 7475 +3 2387 3981 6176 +3 7475 2969 4332 +3 7242 978 6913 +3 3804 2972 63 +3 2564 2258 484 +3 6599 2973 6081 +3 6081 2973 3419 +3 1521 6967 6971 +3 2161 6781 5778 +3 2690 88 6354 +3 3829 1486 2428 +3 2237 1214 714 +3 3484 2974 2976 +3 4188 1330 7513 +3 3484 2976 2165 +3 955 2976 3224 +3 517 4430 4237 +3 4124 289 4562 +3 5180 672 5546 +3 3657 2977 3633 +3 4605 3633 579 +3 13 5486 1952 +3 4374 2978 444 +3 837 2890 825 +3 5909 2979 6963 +3 1765 4770 6373 +3 6963 2979 6912 +3 552 137 1256 +3 1256 3669 552 +3 2941 2984 482 +3 482 6732 2457 +3 4426 7376 5296 +3 5669 2986 3231 +3 512 4423 2169 +3 2956 1278 5121 +3 3627 5636 4415 +3 3869 2987 928 +3 928 2987 1438 +3 4404 3998 4424 +3 4566 550 3068 +3 5174 5103 3617 +3 139 3267 4503 +3 6005 7018 7341 +3 7513 4882 4188 +3 2548 2992 714 +3 2956 7267 5136 +3 3181 3310 5695 +3 2531 3256 3294 +3 4562 1599 5499 +3 6085 5259 3993 +3 2994 2897 4698 +3 3742 5983 815 +3 535 4796 4479 +3 2996 6152 2441 +3 6152 2996 6763 +3 734 5559 1394 +3 6963 6912 1615 +3 6505 6738 3509 +3 5424 703 7385 +3 754 5113 157 +3 2947 5721 7015 +3 7239 4500 682 +3 4681 7115 7104 +3 1733 2999 6353 +3 4513 142 6566 +3 1920 7497 2303 +3 2007 3000 5081 +3 2875 7478 388 +3 2267 4021 389 +3 4205 5436 7186 +3 3379 3003 3425 +3 6353 2999 2712 +3 7015 4795 3336 +3 3425 3003 3653 +3 6540 3686 7433 +3 556 6133 4409 +3 886 5135 889 +3 5639 4758 4192 +3 278 3005 4537 +3 3990 3008 5 +3 4818 3010 6326 +3 6326 3010 4495 +3 416 1352 6231 +3 5715 6458 6067 +3 5692 2740 3024 +3 4583 6824 3672 +3 6847 3014 6581 +3 2281 4614 2292 +3 3181 3772 3310 +3 2659 335 3028 +3 294 2117 3727 +3 5438 3016 2802 +3 2802 3016 3976 +3 3461 3017 4524 +3 4405 4407 6883 +3 2520 3620 465 +3 3389 3019 4947 +3 4947 3019 200 +3 1146 3020 1399 +3 3021 2540 5388 +3 3762 5715 2779 +3 1161 3022 1188 +3 3570 454 4424 +3 153 5278 4633 +3 5445 3023 3919 +3 3581 6626 280 +3 3791 3027 2809 +3 5085 4364 5770 +3 1944 3276 6418 +3 3057 3032 352 +3 2545 4007 3910 +3 2171 3033 5392 +3 155 501 4219 +3 4486 2444 6115 +3 1251 2546 3834 +3 2546 3036 4735 +3 3410 3037 1209 +3 4394 4395 2896 +3 1209 6782 3410 +3 455 2439 2639 +3 2498 4989 813 +3 2189 4439 5021 +3 6595 3039 1788 +3 503 4391 981 +3 1579 2383 412 +3 4878 3040 2218 +3 2907 4417 2950 +3 2947 3336 4525 +3 3996 5023 3345 +3 157 4393 3186 +3 2535 4388 309 +3 4614 2226 159 +3 3145 5721 7010 +3 5814 5352 3632 +3 159 5739 4614 +3 2660 161 288 +3 2734 1623 469 +3 3140 5679 5598 +3 288 4183 2660 +3 3631 5276 2739 +3 467 166 167 +3 3598 1444 167 +3 2600 2396 1261 +3 3606 3469 7515 +3 7096 1764 982 +3 2081 3045 4512 +3 1164 3045 4592 +3 2624 4387 5865 +3 902 2714 4828 +3 2948 4881 3686 +3 2497 3996 6250 +3 4706 3046 487 +3 487 3046 7164 +3 6664 4016 3916 +3 4486 3047 1735 +3 2116 6981 4483 +3 3048 1284 6113 +3 5563 6762 2282 +3 2436 1134 5099 +3 3049 3994 2805 +3 5104 3051 3797 +3 1602 3051 3486 +3 1173 3052 6425 +3 1134 2436 626 +3 3545 809 5589 +3 6425 3052 6785 +3 5118 3053 3075 +3 3075 3053 5313 +3 2219 853 1660 +3 2379 3341 652 +3 454 568 4404 +3 7240 3057 1207 +3 2924 3058 2325 +3 2325 3058 3402 +3 2969 3059 3796 +3 3796 3059 3324 +3 3093 3060 7156 +3 2177 283 6686 +3 3898 5479 1608 +3 242 177 4624 +3 7009 4379 707 +3 3631 2311 5276 +3 5085 168 4364 +3 2540 3021 6771 +3 1119 1722 1627 +3 2586 4680 6007 +3 3146 2455 6265 +3 3044 5463 5465 +3 5856 3069 5873 +3 7093 3747 2797 +3 1391 3071 2180 +3 5818 7024 1911 +3 2177 5549 283 +3 2064 2225 36 +3 281 5037 3123 +3 4579 2244 3111 +3 6447 2232 170 +3 6447 3074 7097 +3 6065 1189 367 +3 2961 3076 1407 +3 629 7318 2836 +3 2376 5815 490 +3 1407 3076 6440 +3 5885 4801 690 +3 2135 3255 6946 +3 1357 3370 3767 +3 3388 6692 5281 +3 3729 4082 7457 +3 3167 2594 1141 +3 4525 3078 2704 +3 2990 2425 2183 +3 2990 2183 57 +3 4023 2331 4993 +3 3913 3325 7404 +3 7097 3080 5687 +3 6365 6552 3582 +3 4370 4368 44 +3 3420 3081 6867 +3 2645 2664 5106 +3 3082 1161 1099 +3 1161 3082 3022 +3 3702 4895 6978 +3 5246 2946 1196 +3 4363 1156 5587 +3 3031 1382 2970 +3 2944 3085 2867 +3 2867 3085 2744 +3 174 2965 1373 +3 6785 3088 5651 +3 5651 3088 4084 +3 3177 3089 3305 +3 6303 3091 4025 +3 6239 3092 1258 +3 5533 2062 4697 +3 1258 3092 1241 +3 4361 3184 5702 +3 3350 3093 25 +3 6504 4136 1484 +3 175 3149 3715 +3 1033 2571 1045 +3 3197 3672 418 +3 2433 3097 6337 +3 6824 4583 1596 +3 3098 5815 3808 +3 3690 3571 4225 +3 5815 3098 3099 +3 482 3099 6732 +3 716 4428 624 +3 6732 3099 3097 +3 5164 6481 6868 +3 1446 1578 5875 +3 6597 3100 4593 +3 666 3101 679 +3 3155 6002 3293 +3 5463 3044 2275 +3 3101 4561 572 +3 3940 6994 1047 +3 6460 5707 5809 +3 5449 5427 5376 +3 3221 3103 24 +3 4936 3104 4891 +3 1949 3105 5840 +3 5840 3105 4114 +3 2454 1151 3180 +3 4029 2705 3543 +3 5477 4288 165 +3 3137 3814 5884 +3 759 3111 6792 +3 3166 3113 7204 +3 7204 3113 6430 +3 3267 558 437 +3 521 4690 2089 +3 7415 1083 4961 +3 3103 3115 2394 +3 4352 1775 5713 +3 1559 3067 1013 +3 2394 3115 6227 +3 5154 5484 1684 +3 6901 6032 62 +3 1486 3829 1713 +3 2508 3118 3904 +3 3904 3118 4986 +3 2310 4023 4993 +3 5278 391 4601 +3 3768 3120 5021 +3 5021 3120 390 +3 960 4645 4136 +3 4435 5684 4424 +3 990 287 82 +3 4476 863 7409 +3 6363 5482 3349 +3 178 5782 6363 +3 3429 3123 6264 +3 2551 3124 1034 +3 1034 5047 2551 +3 4994 3127 2989 +3 2989 3127 4642 +3 3731 3128 4850 +3 2580 1404 1252 +3 6512 4059 4770 +3 3852 3137 1725 +3 2707 4349 6941 +3 2834 1016 182 +3 182 3480 2834 +3 7075 1121 183 +3 183 3520 7075 +3 2928 3136 2370 +3 2370 3136 267 +3 3138 7103 2136 +3 7103 3138 329 +3 1720 4345 4349 +3 6311 1579 412 +3 6943 808 3572 +3 5270 5627 4755 +3 2504 185 5414 +3 3073 5414 185 +3 3447 3144 6832 +3 756 319 1976 +3 380 1450 5837 +3 1013 3067 5459 +3 1330 6594 7513 +3 2073 7496 71 +3 4359 4727 2978 +3 5162 6717 4209 +3 3830 3147 844 +3 3147 4574 3151 +3 701 3416 2726 +3 3370 1357 1240 +3 2085 3153 1513 +3 7402 3893 6127 +3 4642 3156 6043 +3 6043 3156 7193 +3 2704 202 1783 +3 809 6427 3755 +3 4244 7043 4182 +3 5427 2991 6411 +3 4378 7417 3158 +3 1136 5832 5608 +3 3158 3159 4077 +3 4077 3159 6700 +3 3682 3162 693 +3 6700 6842 3814 +3 3902 1110 476 +3 2279 5325 691 +3 187 840 6477 +3 3164 3287 3288 +3 148 3166 4617 +3 4617 3166 5390 +3 6643 4660 4705 +3 3323 5575 5655 +3 1451 822 6471 +3 3153 3168 1513 +3 1513 3168 1688 +3 1364 969 5348 +3 1364 3169 5605 +3 2531 3294 2460 +3 2419 4517 933 +3 5180 1880 672 +3 4043 3173 4985 +3 6481 393 2993 +3 7430 3950 7045 +3 3103 3174 24 +3 7318 603 6636 +3 24 3174 6856 +3 2448 3175 4542 +3 2970 6531 3031 +3 4631 3177 5690 +3 5690 3177 5001 +3 4705 4660 4299 +3 5822 3219 6501 +3 3052 3178 3305 +3 4414 2749 287 +3 4232 6911 2700 +3 816 3677 793 +3 4730 3181 7215 +3 3639 3184 3584 +3 7509 3184 927 +3 999 7466 6070 +3 7348 3185 5129 +3 5402 3187 1498 +3 1498 3187 6964 +3 7517 1686 7231 +3 4847 3188 4457 +3 4457 3188 6551 +3 5916 3446 6012 +3 3272 3190 3289 +3 6089 3194 456 +3 456 1954 6089 +3 4197 718 2467 +3 6749 452 456 +3 1723 3199 2206 +3 4336 138 3599 +3 5094 6023 4331 +3 5693 7319 1366 +3 3916 1633 6664 +3 1627 1722 4072 +3 5312 5942 5221 +3 7055 3200 6228 +3 3200 5093 5946 +3 4016 6463 172 +3 5041 3626 4584 +3 2182 3203 1509 +3 1509 3711 2182 +3 3423 1562 193 +3 5408 4378 4077 +3 2166 194 830 +3 6594 2121 7519 +3 830 480 2166 +3 2335 2691 3303 +3 3287 3206 832 +3 832 126 3287 +3 4731 5072 4211 +3 5619 5087 7450 +3 7146 4321 5816 +3 2367 1985 6693 +3 6336 3540 4733 +3 5597 5023 3096 +3 5460 1649 4710 +3 6481 5164 2728 +3 1880 2379 652 +3 1650 1119 3964 +3 6494 4275 3243 +3 5430 2390 2202 +3 347 4320 3738 +3 3533 3207 341 +3 6621 4055 5624 +3 3887 3208 6511 +3 958 3165 1361 +3 708 5243 6038 +3 5023 1463 3096 +3 3210 3670 1538 +3 4136 4645 2065 +3 405 808 5680 +3 5680 1497 405 +3 200 3020 4947 +3 192 1822 1823 +3 4327 4325 3582 +3 2819 4323 2238 +3 3582 2653 4327 +3 192 3214 1749 +3 4072 4051 1627 +3 2117 6630 3858 +3 6473 2962 6645 +3 1544 3375 1488 +3 3914 5699 6716 +3 3714 6647 2186 +3 5485 6282 1934 +3 1072 5133 4322 +3 5470 4688 5068 +3 3218 4035 4722 +3 5289 3292 1723 +3 3115 3221 5668 +3 4200 211 3223 +3 1210 3802 435 +3 5403 3629 1221 +3 5555 6272 1885 +3 5056 2982 5997 +3 2664 2645 1915 +3 3219 6500 7252 +3 2165 4428 3484 +3 682 3225 7239 +3 7239 3225 3226 +3 3976 3226 2997 +3 2997 3226 3224 +3 3163 3227 2279 +3 2279 3227 4790 +3 2768 4953 4129 +3 2763 4317 5668 +3 87 1954 4533 +3 6600 5796 1567 +3 606 619 295 +3 328 2205 5980 +3 3231 6790 5669 +3 6790 328 1216 +3 2439 3109 791 +3 4112 3222 6803 +3 4303 2746 5599 +3 1281 3235 3566 +3 339 195 3842 +3 3446 1821 4672 +3 6059 3239 5191 +3 4168 3241 1502 +3 1502 3241 6283 +3 1014 2602 2812 +3 2568 3244 3576 +3 3576 3244 207 +3 1734 2495 6487 +3 697 7010 6268 +3 3964 4414 6643 +3 6924 1564 6750 +3 2366 707 4379 +3 3653 3246 3463 +3 3463 3246 531 +3 4324 3590 5137 +3 3250 3249 130 +3 130 3249 5137 +3 207 4780 3576 +3 4059 1142 6478 +3 4959 3250 2482 +3 2482 3250 675 +3 801 3165 4835 +3 603 1810 6004 +3 3251 3094 3668 +3 488 5093 203 +3 4440 7224 4857 +3 5408 454 3570 +3 203 3966 488 +3 3252 2364 4561 +3 2584 6707 4995 +3 7009 3480 1568 +3 206 4572 798 +3 339 306 752 +3 7463 3258 306 +3 7404 7256 7520 +3 6384 3259 4298 +3 4298 3259 5349 +3 4416 3260 5492 +3 5950 930 1339 +3 4659 3144 3447 +3 5674 3262 2893 +3 2893 3262 308 +3 675 6071 2482 +3 6879 3265 3664 +3 3664 3265 5088 +3 5026 3266 4548 +3 3116 6940 1884 +3 5201 1712 6320 +3 3945 2188 139 +3 2513 3268 3269 +3 6882 3183 3179 +3 7141 2418 3545 +3 464 3263 2670 +3 3120 3269 7173 +3 7173 3269 3268 +3 4136 4005 960 +3 3104 3270 829 +3 829 4891 3104 +3 2358 3271 4623 +3 4295 3272 2629 +3 2938 585 3676 +3 2629 3272 4963 +3 209 3037 2096 +3 210 6169 1289 +3 3085 3274 3275 +3 227 2435 1118 +3 2435 3275 6820 +3 2933 3027 1269 +3 1414 5085 3030 +3 4510 3277 732 +3 3312 3278 6315 +3 1939 838 4020 +3 6315 3278 4395 +3 4641 3279 3680 +3 5243 94 6396 +3 3279 213 2220 +3 2389 6102 1423 +3 3038 2760 4757 +3 3223 297 4200 +3 3223 3282 5555 +3 3220 3282 213 +3 646 6813 3702 +3 4743 5457 4309 +3 1938 4050 6215 +3 213 5289 3220 +3 4194 2495 5767 +3 2828 5287 5723 +3 3239 3283 5191 +3 5191 3283 6496 +3 2403 3286 126 +3 5508 1881 6423 +3 3206 3164 480 +3 3568 2157 7000 +3 3288 840 3164 +3 79 2083 2296 +3 5800 4762 620 +3 2296 3288 3286 +3 3263 1603 4705 +3 3279 3291 5289 +3 6803 3222 860 +3 5762 6865 4304 +3 3292 5289 215 +3 3199 3292 6104 +3 6104 3292 2222 +3 4360 7322 5453 +3 6978 2091 3702 +3 1463 3294 1104 +3 155 3295 3296 +3 3233 515 5944 +3 3047 7327 1735 +3 7327 3296 3717 +3 4032 3298 3133 +3 4169 2478 3754 +3 3133 3298 1555 +3 3299 4189 839 +3 5442 7347 127 +3 4346 3515 1869 +3 4189 3299 6039 +3 4743 6071 41 +3 41 5456 4743 +3 1290 3300 4600 +3 3721 3302 7012 +3 3302 6557 7337 +3 4486 3772 4399 +3 4017 5199 6660 +3 981 4391 4293 +3 6115 3772 4486 +3 5998 3307 1777 +3 1673 3308 3309 +3 6496 3309 3650 +3 3650 4886 6496 +3 6554 1323 7151 +3 3040 3311 671 +3 1422 3312 3544 +3 3040 3315 2218 +3 5301 7040 1712 +3 1 2902 7343 +3 2218 3315 4473 +3 4591 1564 3141 +3 4261 6751 1239 +3 1044 6040 6236 +3 1956 2831 5166 +3 22 3147 3830 +3 156 120 3662 +3 3668 6494 3251 +3 22 3318 276 +3 219 5972 582 +3 2863 761 6276 +3 4665 4556 4290 +3 1443 219 3319 +3 2524 5524 3724 +3 4430 3320 4237 +3 4237 3320 4240 +3 5895 3172 588 +3 4620 3629 5403 +3 7407 5633 1981 +3 6652 2771 7148 +3 5374 7019 2653 +3 638 5614 1231 +3 3931 6716 7037 +3 5156 3596 2742 +3 5314 3196 1593 +3 3060 3059 7156 +3 3877 3326 1200 +3 1200 3326 6639 +3 4980 3327 2064 +3 7042 6067 5235 +3 2064 3327 2225 +3 2493 7000 7159 +3 3329 3377 6512 +3 515 3233 2921 +3 3377 3329 6928 +3 3418 3330 6021 +3 1604 6200 1020 +3 6021 3330 6519 +3 231 94 7053 +3 847 3952 1177 +3 4284 4279 4177 +3 94 4918 7053 +3 3623 3335 25 +3 6965 1262 7437 +3 6711 1548 3337 +3 2341 3917 6382 +3 1916 4010 4201 +3 1215 3385 5973 +3 426 3338 3680 +3 5046 31 5604 +3 2615 5078 5022 +3 3000 7302 511 +3 3000 3749 3753 +3 7379 3342 6644 +3 4655 3347 3880 +3 3885 6460 3578 +3 7178 3217 223 +3 2664 2607 5106 +3 223 3846 7178 +3 3060 3350 3301 +3 5416 3351 6721 +3 2607 1729 5106 +3 6721 3351 3352 +3 3335 3352 25 +3 25 3352 3350 +3 3799 3353 671 +3 3315 3354 5049 +3 5049 3354 3511 +3 7022 5939 224 +3 224 5418 7022 +3 3753 3356 5081 +3 5081 3356 2068 +3 1682 3357 710 +3 3357 4842 710 +3 961 3358 6983 +3 2205 6853 3424 +3 3293 470 1224 +3 1358 593 2966 +3 502 1475 536 +3 4165 6222 881 +3 6680 7384 7281 +3 6994 3102 1704 +3 3366 5833 2650 +3 4152 3367 5583 +3 4291 3368 5960 +3 2524 6305 6287 +3 5462 3676 1421 +3 3369 6231 1352 +3 6879 6350 2373 +3 2595 3310 3290 +3 2162 3539 260 +3 2162 3371 1145 +3 3596 340 3198 +3 1083 3372 3532 +3 3587 6372 2766 +3 6375 6354 3026 +3 4709 5298 7498 +3 1285 1437 4841 +3 2764 3154 172 +3 7319 5693 6959 +3 2131 1609 6867 +3 3034 6534 4270 +3 2361 3999 5 +3 2435 5720 1118 +3 4265 4266 5760 +3 227 6703 4438 +3 1725 4406 3852 +3 1488 3375 3525 +3 7133 3379 3467 +3 3467 3379 4103 +3 3380 3706 3396 +3 2478 5515 5056 +3 804 3336 3718 +3 3706 3380 5935 +3 3019 3381 7102 +3 7102 3381 1128 +3 2328 1127 4196 +3 2251 4262 4602 +3 2496 3384 2236 +3 1235 3897 351 +3 1827 3387 1280 +3 1280 3387 350 +3 772 5801 4257 +3 3381 3389 4196 +3 847 1177 1895 +3 1895 7169 2807 +3 6511 84 2868 +3 6289 3581 228 +3 1105 7041 5540 +3 2164 4288 5477 +3 2361 5 4254 +3 1506 3137 3852 +3 6034 3393 718 +3 7366 3394 2428 +3 2428 3394 6895 +3 1885 3223 5555 +3 1885 297 3223 +3 3398 4774 764 +3 4774 3398 1480 +3 555 3401 403 +3 1002 7186 5437 +3 403 3261 555 +3 4459 1532 7240 +3 3686 7119 2948 +3 3724 3628 2524 +3 4724 3403 1491 +3 1491 3403 6422 +3 3675 3540 5000 +3 3458 3404 4884 +3 5119 3406 230 +3 6341 2755 230 +3 3478 3407 516 +3 3593 4720 7110 +3 6170 3408 3410 +3 3410 6782 6170 +3 7201 4458 1103 +3 5724 2386 3754 +3 1103 3407 7201 +3 5253 1346 4276 +3 1993 4814 1342 +3 232 4161 14 +3 6286 3411 4259 +3 4259 3411 5711 +3 707 2366 1716 +3 7380 6827 4252 +3 6396 2875 3001 +3 3307 4881 1777 +3 4881 3307 7433 +3 7200 5423 2119 +3 1557 7386 2740 +3 2992 3413 714 +3 3413 235 2237 +3 3505 2117 3858 +3 4523 3414 7358 +3 3530 3414 235 +3 235 354 3530 +3 4611 3418 3776 +3 2972 2973 63 +3 6081 3419 3565 +3 736 2569 5599 +3 3498 3420 5432 +3 60 1137 443 +3 5432 3420 4171 +3 1332 2536 1469 +3 4248 1108 2176 +3 3258 3421 752 +3 752 3421 458 +3 1386 1562 1092 +3 2205 3424 5980 +3 309 3426 148 +3 1086 4033 4712 +3 1086 5459 4033 +3 3001 6957 6396 +3 6790 3510 5669 +3 3429 4312 3203 +3 4312 3429 3793 +3 204 5811 1560 +3 3336 2947 7015 +3 3793 5130 5015 +3 4103 3430 2476 +3 3161 7195 2360 +3 6685 816 1710 +3 730 5476 2567 +3 1399 3431 1146 +3 1146 3431 4716 +3 1559 3432 239 +3 474 1366 5542 +3 717 1559 239 +3 1045 7007 557 +3 4127 3730 1160 +3 240 1614 6783 +3 240 3432 1614 +3 2116 243 5623 +3 243 5548 5623 +3 7168 7084 7500 +3 3234 3988 4880 +3 1738 918 3216 +3 6851 3435 5397 +3 289 7409 863 +3 1097 1254 3948 +3 4242 2997 4241 +3 3782 3438 4552 +3 5914 3440 3627 +3 3627 3440 5638 +3 2920 3442 7470 +3 7470 3442 346 +3 1647 3443 2591 +3 2591 3443 345 +3 3323 2574 4432 +3 2612 1240 6044 +3 5466 6951 5188 +3 4649 4892 1160 +3 4114 3449 4588 +3 1262 6965 2337 +3 1900 5969 5522 +3 581 3454 3455 +3 1714 121 7134 +3 121 3455 3456 +3 228 634 6289 +3 3455 5122 581 +3 4714 121 3456 +3 1973 6306 623 +3 584 3720 2310 +3 3562 3457 4884 +3 5728 3458 3107 +3 3107 3458 4621 +3 6361 7110 4720 +3 3459 4036 5755 +3 3386 3121 3661 +3 7374 1291 573 +3 5427 6411 4840 +3 131 584 3135 +3 4036 3459 2016 +3 5608 3460 11 +3 11 3460 6658 +3 3542 3461 2780 +3 5910 3464 3756 +3 2400 3465 5974 +3 4234 993 1669 +3 5974 4530 2400 +3 3270 3466 3261 +3 2295 5249 2756 +3 3245 2756 5249 +3 3293 6002 6003 +3 246 5839 6741 +3 2625 3468 3706 +3 3493 3470 201 +3 201 3470 6640 +3 3865 7366 7130 +3 1935 3906 1602 +3 4231 4229 3487 +3 4993 584 2310 +3 2179 5782 248 +3 248 3472 2179 +3 1819 2190 637 +3 3472 0 49 +3 3988 3234 2420 +3 3155 4356 2248 +3 2248 396 3155 +3 4264 3474 6173 +3 4837 6499 3192 +3 5310 3475 5874 +3 2021 6896 6840 +3 910 5450 909 +3 2727 6896 973 +3 253 7187 7288 +3 6957 3001 944 +3 4224 4226 3142 +3 778 4815 692 +3 6484 3478 385 +3 385 3478 6620 +3 7119 6540 1268 +3 3486 394 3994 +3 3432 3649 1614 +3 3482 6026 350 +3 6971 3483 1521 +3 1521 3483 4133 +3 7280 2115 6797 +3 7518 6006 2700 +3 3201 4241 2974 +3 5354 3201 970 +3 978 3585 6913 +3 4395 3485 2896 +3 5154 3585 5010 +3 2962 4075 4369 +3 4369 4075 4622 +3 5224 5918 5138 +3 881 6828 4222 +3 3343 3487 113 +3 3490 2261 2170 +3 4218 4219 501 +3 4010 7256 4009 +3 2384 3491 5683 +3 5683 3491 5339 +3 259 3488 7491 +3 433 4215 4548 +3 3488 3492 4901 +3 1650 6643 3663 +3 2355 4648 4968 +3 427 1099 1161 +3 7401 4365 4494 +3 6633 3493 6414 +3 6490 5794 2254 +3 4985 3495 2594 +3 6875 5309 3795 +3 2594 3495 5140 +3 584 2373 3135 +3 3081 3498 4859 +3 2091 3500 646 +3 646 3500 2756 +3 2353 643 1621 +3 841 4445 426 +3 2778 4708 2988 +3 271 260 4120 +3 271 4120 4121 +3 3786 3502 524 +3 82 287 4199 +3 524 3502 404 +3 1575 3603 423 +3 6583 3503 4759 +3 4759 3503 3551 +3 2717 3506 899 +3 6173 5533 508 +3 6422 748 1491 +3 4020 7364 3139 +3 899 73 2717 +3 4998 3507 327 +3 1711 6217 7376 +3 4493 2352 1921 +3 5646 3510 6045 +3 6045 7436 5646 +3 3353 3354 671 +3 5049 3511 3604 +3 904 2865 1828 +3 4790 3512 3497 +3 1518 4625 6697 +3 5871 4511 6267 +3 4781 3513 3576 +3 4190 4192 4758 +3 5591 3513 4263 +3 3516 205 139 +3 266 2008 4732 +3 2761 3519 149 +3 827 3519 3997 +3 3997 3519 2255 +3 267 2195 2370 +3 7075 3520 5941 +3 5563 3521 6762 +3 999 3705 369 +3 2373 6350 3135 +3 3746 7163 1384 +3 3757 268 3523 +3 2928 3523 4723 +3 3525 4723 268 +3 1118 3375 227 +3 1488 3525 268 +3 1633 3236 3666 +3 4894 3613 5705 +3 531 3526 3463 +3 2824 3527 3355 +3 4404 3852 3998 +3 7003 3528 4726 +3 4726 3528 3857 +3 3529 4297 2922 +3 4297 3529 1165 +3 4409 3530 556 +3 269 2262 2725 +3 270 3621 3548 +3 3475 3531 6333 +3 6333 3531 6314 +3 6382 2636 5219 +3 5243 6957 6038 +3 420 933 324 +3 4555 4632 5100 +3 6717 4184 1519 +3 1560 5811 113 +3 3886 6238 3656 +3 3533 341 4497 +3 6427 5649 1077 +3 437 2196 3267 +3 4178 4275 2991 +3 1519 3534 4209 +3 4209 3534 4223 +3 6813 646 5752 +3 2918 2 2080 +3 2149 3737 5247 +3 2148 3889 2784 +3 6819 3536 1317 +3 1317 3536 6126 +3 3556 3537 5311 +3 5311 3537 6476 +3 5786 3538 2162 +3 404 3539 524 +3 524 3539 3541 +3 4527 1508 1061 +3 1061 3538 4527 +3 2520 4756 749 +3 3017 3542 3415 +3 3415 3542 6108 +3 5221 5942 5940 +3 3544 2103 1422 +3 2103 3544 1719 +3 4590 3750 2152 +3 3411 3546 4068 +3 4068 3546 6684 +3 3239 3547 4554 +3 272 7267 4782 +3 1455 7267 272 +3 1827 2147 6328 +3 840 2083 274 +3 274 6477 840 +3 2187 1477 5455 +3 4155 5015 6257 +3 569 3763 1251 +3 4172 4173 3608 +3 3931 447 2696 +3 3504 3503 2895 +3 2146 5319 1064 +3 1386 1092 1042 +3 3500 3553 4014 +3 3555 563 3556 +3 4131 3556 2527 +3 563 4539 4538 +3 982 363 7096 +3 7170 3557 1064 +3 276 579 2977 +3 1443 5972 219 +3 6867 4273 3420 +3 4098 3562 3563 +3 3901 3563 5364 +3 5364 3563 3574 +3 597 3564 5207 +3 5207 3564 4166 +3 3418 3419 3776 +3 3566 2458 1281 +3 2458 3566 6522 +3 2595 5409 2455 +3 6092 3567 264 +3 5507 4932 4440 +3 2689 4708 2449 +3 4166 4167 5207 +3 2267 3004 7213 +3 1262 4339 2687 +3 3001 2875 277 +3 5952 6793 6781 +3 277 3333 3001 +3 3228 4297 5420 +3 6121 6857 5006 +3 3784 3763 2518 +3 4646 5498 1052 +3 4098 3563 2163 +3 5364 3574 854 +3 3404 3575 4884 +3 4884 3575 850 +3 5331 3967 6346 +3 3810 3577 2048 +3 4637 2048 599 +3 3719 2344 1617 +3 3005 599 3577 +3 6034 2703 5396 +3 4076 4163 7013 +3 545 2652 4502 +3 5852 3784 5848 +3 6015 3935 1698 +3 3579 5377 1901 +3 3392 3580 7041 +3 280 1652 5653 +3 6626 3581 577 +3 2520 465 5375 +3 661 4885 3933 +3 1918 6969 2033 +3 2551 4228 3342 +3 3123 3124 6264 +3 3091 2488 225 +3 2488 3091 4717 +3 1614 3649 6740 +3 2917 2342 1255 +3 3719 6171 6222 +3 1025 1826 565 +3 6816 4508 6773 +3 5055 4982 4736 +3 4999 4427 702 +3 3405 5166 1801 +3 6608 3590 4225 +3 3590 4324 3690 +3 2182 3711 750 +3 281 5124 5037 +3 2356 4162 2714 +3 890 3192 452 +3 3592 5541 755 +3 5789 3671 7429 +3 5731 6382 2338 +3 1254 282 519 +3 1254 519 3948 +3 3690 6050 1241 +3 2337 5165 4339 +3 284 3671 7432 +3 2742 134 318 +3 2855 6743 921 +3 2299 2278 2645 +3 286 1199 19 +3 286 2277 1199 +3 4814 2981 1490 +3 288 166 4183 +3 4336 6990 2337 +3 4788 3599 138 +3 4441 3602 3827 +3 3827 5116 4441 +3 423 3603 2156 +3 1617 5952 1074 +3 3512 3511 3497 +3 2636 6382 3917 +3 2636 3605 6730 +3 1414 2044 5085 +3 769 7436 4354 +3 2139 5844 3837 +3 5509 3609 1769 +3 1769 3609 7297 +3 5223 3610 893 +3 893 3610 439 +3 2781 3611 3667 +3 4922 6940 423 +3 4250 3837 5844 +3 3612 929 1206 +3 2259 2018 5573 +3 2142 3837 4250 +3 6189 2888 3843 +3 3187 3614 5129 +3 6574 2046 1968 +3 7204 3618 5192 +3 2466 3619 6999 +3 3487 1912 113 +3 1912 4836 2493 +3 5412 465 5709 +3 2670 3618 2826 +3 5022 4837 5025 +3 981 4293 4153 +3 5025 4837 5265 +3 2725 974 269 +3 6667 4783 2340 +3 5996 6409 1801 +3 2140 6856 3175 +3 3548 3621 571 +3 3093 3622 25 +3 4711 5816 4151 +3 4119 6504 6066 +3 5993 3623 4549 +3 1330 2638 6594 +3 4549 3623 6298 +3 782 6727 2145 +3 3625 7371 1850 +3 4945 2483 2843 +3 6727 782 2138 +3 3716 1992 5647 +3 2013 1418 5982 +3 5122 3455 1714 +3 6433 7290 295 +3 2410 3638 3584 +3 3639 4335 1101 +3 214 196 594 +3 3290 2845 2595 +3 3526 3641 3463 +3 2952 1339 5781 +3 3450 6816 6757 +3 3463 3641 3803 +3 2669 3642 3025 +3 3642 1070 820 +3 6311 6454 2590 +3 1992 3716 5658 +3 2289 310 2309 +3 5530 3644 3862 +3 386 3645 1445 +3 3157 2947 2704 +3 5529 4528 3648 +3 4201 2049 1916 +3 3648 795 5529 +3 3309 3083 1673 +3 4970 4886 795 +3 3803 3652 3463 +3 3246 3003 4746 +3 3425 3653 4715 +3 2872 3794 1607 +3 5521 7364 838 +3 3915 3654 6294 +3 1295 3655 7108 +3 1107 3476 1803 +3 7108 3655 6984 +3 5332 3657 3928 +3 299 2200 1409 +3 4144 5102 3781 +3 2200 3658 3770 +3 6831 3660 5800 +3 4830 3755 498 +3 4142 4156 1405 +3 3600 1892 508 +3 359 4979 1640 +3 2197 3891 3923 +3 3637 5206 3795 +3 445 5272 5205 +3 4557 873 3665 +3 2895 5465 4140 +3 1705 3908 2654 +3 3667 154 2781 +3 154 3667 355 +3 3668 3094 919 +3 963 3668 5846 +3 4336 3599 6990 +3 6511 3208 84 +3 407 4138 7291 +3 1777 3640 4853 +3 1758 6367 4133 +3 3146 6265 2995 +3 1538 3165 3210 +3 7315 3790 4794 +3 3790 111 4729 +3 1804 3361 7383 +3 3405 3399 963 +3 343 3672 6824 +3 5269 4534 1972 +3 5493 162 2057 +3 1792 3673 6787 +3 993 4719 636 +3 4684 3674 7190 +3 3718 3336 4795 +3 7190 3674 7351 +3 2706 3676 304 +3 1908 3066 1745 +3 5178 4771 2334 +3 304 7290 2706 +3 303 3064 4662 +3 2288 3064 303 +3 2527 6352 4131 +3 3676 5462 2938 +3 4589 3662 120 +3 2524 3628 6305 +3 1934 3218 5485 +3 6910 3685 2713 +3 7480 3891 2197 +3 2713 3685 1243 +3 305 2933 3030 +3 2957 3688 4527 +3 2458 6524 4128 +3 6472 3689 3691 +3 3691 538 6472 +3 306 3258 752 +3 4875 3691 3688 +3 7243 6982 3637 +3 1655 1659 3140 +3 4803 2065 6064 +3 2503 3694 61 +3 61 3694 6720 +3 4331 3695 5094 +3 3777 2907 2950 +3 3638 3639 3584 +3 2649 3900 3891 +3 1346 3697 4276 +3 1852 2746 4067 +3 4754 6050 7227 +3 4276 3026 5253 +3 4495 3698 4731 +3 5561 6107 4125 +3 4731 3698 6249 +3 5795 3699 1761 +3 3199 3700 2206 +3 1512 3703 4861 +3 4861 3703 326 +3 3704 5440 448 +3 5440 3704 326 +3 2908 2057 162 +3 214 1470 2772 +3 2462 3708 5238 +3 5238 3708 4070 +3 3023 3710 3919 +3 1876 4401 310 +3 310 2291 1876 +3 3095 2289 869 +3 2441 4220 2996 +3 3690 3713 3571 +3 3713 3365 6389 +3 4343 3900 2649 +3 5535 3365 3713 +3 313 2750 1589 +3 3715 3149 6123 +3 2291 3715 2293 +3 2141 2530 5424 +3 7408 7411 118 +3 635 2953 4251 +3 3296 501 155 +3 3926 3979 1896 +3 2680 2931 3055 +3 5854 3926 35 +3 2873 3932 3926 +3 1972 3656 6238 +3 3297 96 4051 +3 1114 2620 1028 +3 1028 2750 313 +3 4030 5065 1172 +3 319 5181 1345 +3 3721 6885 1582 +3 7011 3932 2873 +3 6885 3721 6057 +3 3771 4508 3452 +3 843 3725 6279 +3 4123 4759 3551 +3 6279 3725 6151 +3 999 5163 5903 +3 59 4446 2130 +3 4446 59 3726 +3 445 3728 5836 +3 5836 5272 445 +3 4468 3245 6903 +3 3146 4917 2455 +3 439 2114 893 +3 3336 804 4525 +3 4121 6231 271 +3 1160 3730 5507 +3 1744 5451 950 +3 623 6306 6365 +3 4125 3731 5561 +3 5561 3731 4823 +3 4365 4193 317 +3 402 2332 3337 +3 317 5222 4365 +3 6066 3171 4119 +3 5389 3732 1971 +3 2330 481 2093 +3 320 1566 4003 +3 3347 3734 3880 +3 3880 3734 3735 +3 329 3735 7103 +3 5818 972 2865 +3 5309 6033 3795 +3 4109 4110 4685 +3 2328 4196 7107 +3 7103 3735 3733 +3 3532 3372 5156 +3 976 3780 1378 +3 348 3548 3866 +3 3548 3738 1377 +3 2556 3824 5623 +3 6148 5269 6795 +3 4398 3990 4003 +3 4145 3990 4398 +3 3701 5575 1123 +3 5897 3745 3215 +3 3215 3745 6631 +3 2908 85 2057 +3 3622 3748 5911 +3 4230 3753 4047 +3 4230 4047 1839 +3 3461 3464 2780 +3 5 3999 3990 +3 3756 4800 2429 +3 7138 985 708 +3 3383 2153 7219 +3 3757 6766 322 +3 6766 3757 602 +3 2265 652 3341 +3 4587 3758 6761 +3 6761 3758 1624 +3 3863 3759 4334 +3 4334 3759 3860 +3 2136 2231 3138 +3 1269 988 4431 +3 2566 4899 5050 +3 7431 3765 5984 +3 5984 7143 7431 +3 3205 5984 3765 +3 2604 4953 2768 +3 443 242 60 +3 4105 5989 1030 +3 3269 3768 5637 +3 5637 3768 2090 +3 2404 3769 3633 +3 3657 3658 3928 +3 2200 3770 4507 +3 3815 4974 3242 +3 1208 4244 4182 +3 3773 3193 3403 +3 1160 4892 1590 +3 3193 3773 4966 +3 3507 6312 6545 +3 2609 1702 4956 +3 1349 2643 1202 +3 2262 3780 2725 +3 1970 52 117 +3 2725 3780 2682 +3 6509 3782 7394 +3 3589 5239 4101 +3 1973 4529 5895 +3 1628 4099 398 +3 4899 4669 5050 +3 5895 588 1973 +3 1034 3783 5047 +3 3541 3785 524 +3 524 3785 3786 +3 3618 6431 3594 +3 4366 3786 3764 +3 3764 3786 3783 +3 1881 7473 6423 +3 963 3029 1956 +3 3251 3788 3094 +3 918 3789 3216 +3 3216 3789 2304 +3 5918 5224 2528 +3 1714 4506 5122 +3 4109 4003 1566 +3 3405 963 1956 +3 3760 3791 2000 +3 5934 6035 4670 +3 3791 2470 2305 +3 3792 1924 2630 +3 3826 4312 3793 +3 4260 6904 4098 +3 397 5034 6351 +3 15 4004 4081 +3 7035 7030 1009 +3 1914 4764 7225 +3 3311 3798 671 +3 4558 3799 4997 +3 3679 2265 3729 +3 3589 4101 4095 +3 4089 4090 17 +3 4997 3799 5411 +3 3190 3800 3289 +3 1530 3112 6662 +3 3112 1530 323 +3 1816 4715 3652 +3 2877 68 1953 +3 5922 5998 1777 +3 3331 3459 949 +3 323 3331 949 +3 4015 3804 1176 +3 3805 2641 1968 +3 1981 5633 5997 +3 932 3806 5359 +3 3806 63 673 +3 63 3806 3804 +3 328 3231 2205 +3 6790 3808 1218 +3 4085 4086 1264 +3 3782 3809 7394 +3 7394 3809 6177 +3 4045 3810 751 +3 591 4227 1824 +3 952 3811 2306 +3 4868 4088 4080 +3 4676 6847 6581 +3 298 2202 330 +3 330 2086 298 +3 175 3816 3818 +3 6945 3818 3819 +3 6945 3819 1707 +3 3819 6076 1856 +3 2749 1938 5576 +3 6076 3819 3816 +3 4166 3820 802 +3 7353 2265 7321 +3 4551 7492 7490 +3 4351 3821 4176 +3 4176 3821 7233 +3 292 4318 4263 +3 4962 3822 5977 +3 5388 3450 3021 +3 2309 869 2289 +3 1967 870 2053 +3 4228 1510 5625 +3 6636 4220 2709 +3 326 913 5440 +3 172 1472 4016 +3 1284 3824 331 +3 3979 2302 331 +3 5125 3793 4155 +3 5317 1323 369 +3 2863 6276 4991 +3 5116 5145 6297 +3 5116 2023 5145 +3 6588 7425 2722 +3 1608 5479 2025 +3 2175 5955 4176 +3 3023 3828 3608 +3 3318 3830 6895 +3 3318 6895 3394 +3 3017 3831 4524 +3 4800 3833 1029 +3 3068 1090 541 +3 1029 3833 5431 +3 1354 6373 363 +3 3831 3835 4668 +3 4668 3835 333 +3 3065 2559 336 +3 1445 5726 4074 +3 336 3839 3065 +3 6106 3839 3415 +3 3815 5338 4763 +3 333 3415 3839 +3 2642 3840 5528 +3 2380 2427 3991 +3 1313 1454 195 +3 4875 3842 538 +3 6474 538 1454 +3 6189 3843 4516 +3 2062 5542 1312 +3 3389 7105 4196 +3 3198 7476 3596 +3 1169 4041 4004 +3 3640 4881 2948 +3 4501 6996 5314 +3 7309 3848 5335 +3 4464 3849 4855 +3 4855 3849 3955 +3 879 3851 905 +3 905 3851 4927 +3 6241 1484 4803 +3 2628 4041 1169 +3 4027 2793 5558 +3 4064 4065 778 +3 3802 2800 2154 +3 3673 3855 6787 +3 5386 3856 5031 +3 5031 3856 7490 +3 3527 3528 3355 +3 4726 3857 3859 +3 345 3442 2591 +3 346 5743 122 +3 4058 4062 7187 +3 7243 6024 4635 +3 6211 6647 6355 +3 4431 988 358 +3 347 3207 4320 +3 341 3861 4860 +3 4057 5403 6391 +3 4981 3863 2626 +3 3863 349 2317 +3 571 3866 3548 +3 2203 3866 349 +3 349 4334 2203 +3 2809 3868 2470 +3 631 6163 3496 +3 3869 7392 2886 +3 7392 3869 1287 +3 3903 3871 4137 +3 1074 4501 1617 +3 3102 3872 938 +3 938 3872 4466 +3 6067 6458 3971 +3 3879 3873 713 +3 357 3874 3875 +3 3875 695 357 +3 6646 3875 6473 +3 6473 3875 3873 +3 6640 3876 1200 +3 4062 3877 7187 +3 5200 1294 3194 +3 3662 4763 5338 +3 7187 3877 7288 +3 2377 5639 5642 +3 1873 728 1505 +3 1115 3878 713 +3 2962 3879 4075 +3 4075 3879 4074 +3 3875 3881 695 +3 5017 7270 7385 +3 3405 1956 5166 +3 695 3881 5516 +3 5605 3882 7279 +3 7279 3882 4154 +3 6349 7492 4551 +3 7515 3469 4742 +3 5176 2914 921 +3 7179 5038 6116 +3 3884 5797 146 +3 5797 3884 5053 +3 338 3885 5675 +3 156 2566 6861 +3 5675 3885 4178 +3 3914 6589 2634 +3 2951 3887 1358 +3 1358 3887 3888 +3 6370 3888 1048 +3 1820 1048 372 +3 2984 3889 5869 +3 5869 3889 2149 +3 1965 2799 1994 +3 3693 4374 1887 +3 6513 152 7312 +3 4896 1660 3090 +3 3358 3892 6983 +3 6983 3892 1138 +3 2322 3894 1909 +3 1725 3137 5820 +3 1909 4534 2322 +3 5176 7179 3222 +3 5543 1758 1235 +3 3898 1447 5504 +3 1447 3898 2715 +3 4042 4043 4985 +3 851 5364 5112 +3 1997 4137 5616 +3 4137 3901 3903 +3 383 6719 2903 +3 2736 3903 3899 +3 2871 6661 5043 +3 3899 1883 2736 +3 2326 7173 5202 +3 5128 862 6020 +3 6236 7090 4031 +3 6232 3078 5317 +3 5298 7203 803 +3 2994 3905 2897 +3 2456 2488 2321 +3 5710 2488 2456 +3 3051 394 3486 +3 1602 3797 3051 +3 1396 3907 5989 +3 5989 3907 5736 +3 713 3874 1026 +3 86 3911 5929 +3 5929 3911 1794 +3 701 5280 844 +3 3914 2634 2986 +3 4030 591 540 +3 6589 3914 614 +3 2573 5985 3727 +3 3479 1263 6976 +3 614 3914 6716 +3 6248 3915 2341 +3 1190 1623 2734 +3 3605 3917 5347 +3 5347 1364 3605 +3 1642 3515 1654 +3 1640 4787 359 +3 6260 3918 3920 +3 197 4116 2915 +3 4086 3920 1784 +3 5632 3540 3651 +3 5000 3540 5632 +3 1784 1264 4086 +3 6057 3922 2971 +3 3924 2521 6547 +3 2521 3924 3965 +3 2124 3925 2199 +3 2199 3925 4128 +3 6112 3927 6754 +3 5277 3930 4885 +3 2779 5715 1894 +3 4885 3930 5489 +3 6032 6901 4485 +3 613 3910 4677 +3 694 896 3218 +3 6368 3935 4787 +3 4787 3935 359 +3 360 3935 6015 +3 7491 7492 259 +3 6898 4327 4285 +3 381 5872 2423 +3 1457 1950 3938 +3 3938 6130 142 +3 1950 7435 640 +3 2349 4877 4024 +3 1046 4021 4793 +3 5881 6319 5694 +3 62 5215 6901 +3 136 3941 2333 +3 3644 3942 3496 +3 4387 1186 3496 +3 1554 3198 1147 +3 5165 6990 7039 +3 5215 62 1715 +3 1420 4793 3 +3 750 2336 3944 +3 5698 5700 2598 +3 4478 3946 7291 +3 5835 3139 1639 +3 3946 523 407 +3 771 2909 5927 +3 7034 3947 4529 +3 623 6893 6892 +3 5034 4097 4018 +3 3948 5885 1097 +3 5885 3948 689 +3 3552 3949 688 +3 6250 2054 2497 +3 688 7374 3552 +3 2776 4569 2228 +3 3951 5024 1353 +3 4246 5024 3951 +3 6739 3952 2631 +3 2631 3952 6128 +3 6275 489 3636 +3 2486 3953 847 +3 2739 5276 2307 +3 5024 4246 4717 +3 3848 3849 5335 +3 4855 3955 4544 +3 5405 3957 7311 +3 1176 4987 4015 +3 1630 3958 4446 +3 4446 3958 2130 +3 6637 3535 189 +3 3352 3959 6721 +3 1893 7446 4602 +3 436 4562 1449 +3 3800 3960 3289 +3 2827 6875 7153 +3 3289 3960 3961 +3 4963 3961 479 +3 479 3961 3959 +3 1094 1096 3963 +3 2623 3636 489 +3 4135 4150 2132 +3 1054 839 4189 +3 488 3966 1093 +3 6346 3967 5283 +3 950 4135 1143 +3 7153 7114 70 +3 3962 1683 2369 +3 1475 3969 536 +3 3295 3970 2519 +3 2519 3970 5452 +3 6129 5708 825 +3 6149 3973 6735 +3 4330 4961 3532 +3 6735 3973 4666 +3 5773 3975 6968 +3 6968 3975 4242 +3 4880 5135 6088 +3 5976 2724 2465 +3 6355 945 4027 +3 3226 3016 7239 +3 3977 6191 987 +3 2354 3978 6687 +3 5934 4104 4330 +3 901 3980 6125 +3 3018 3631 469 +3 247 6425 1091 +3 489 3631 3018 +3 6425 3980 1173 +3 1338 4150 2133 +3 2732 6178 1001 +3 7213 3986 2267 +3 902 3987 2714 +3 7182 4150 1338 +3 778 4065 4008 +3 370 4217 2356 +3 190 887 1426 +3 1489 3197 418 +3 6276 761 959 +3 374 686 2862 +3 5203 3995 1356 +3 4576 656 5863 +3 1356 3995 4448 +3 1222 4057 6391 +3 2585 1026 1027 +3 4738 4217 1198 +3 2909 872 5927 +3 379 5982 4692 +3 3779 4480 1843 +3 382 4052 7237 +3 3662 4589 915 +3 4792 4052 382 +3 5113 754 4550 +3 6459 859 5127 +3 1981 5997 667 +3 2128 14 4161 +3 1045 2571 6789 +3 713 1026 1115 +3 5427 5675 2991 +3 5068 5078 2615 +3 5805 3645 1117 +3 6836 160 6503 +3 5451 4400 1769 +3 2431 4007 3974 +3 2294 2235 5760 +3 3974 4007 5490 +3 1468 4008 2767 +3 2999 1733 6364 +3 4000 955 684 +3 6364 1733 4012 +3 2130 4161 59 +3 4336 4013 138 +3 849 6247 6329 +3 138 4013 5931 +3 2129 3958 3230 +3 4014 2295 3500 +3 4124 7409 289 +3 4104 4961 4330 +3 1609 1709 6069 +3 5309 6875 2827 +3 849 6329 7415 +3 4414 4305 4660 +3 2972 4015 3776 +3 1831 4281 589 +3 3775 5199 586 +3 4901 4018 3739 +3 1386 1042 877 +3 877 4097 562 +3 5959 4214 6048 +3 4240 3320 1024 +3 5502 1900 387 +3 4221 4022 2975 +3 3128 4024 4850 +3 1713 5280 2564 +3 3154 4030 1403 +3 1403 1472 3154 +3 2561 4031 3133 +3 4252 4032 7380 +3 4032 7090 2221 +3 390 2189 5021 +3 391 3006 4601 +3 2494 7111 7109 +3 5090 4042 4985 +3 5184 4043 7124 +3 7124 4043 4044 +3 432 4463 1197 +3 913 4044 5440 +3 5440 4044 4042 +3 3986 4917 3146 +3 3577 4045 6110 +3 499 5045 3984 +3 6110 4045 392 +3 5820 3137 5884 +3 6191 3977 901 +3 1138 4046 6983 +3 4651 2616 4601 +3 6314 4046 751 +3 2238 4854 2819 +3 392 751 4046 +3 1412 1424 2589 +3 3753 5081 3000 +3 529 1839 4839 +3 2997 4242 3976 +3 1574 3636 7457 +3 1472 2829 4016 +3 5675 4178 2991 +3 298 4666 3972 +3 5956 6481 2728 +3 7457 3636 615 +3 3969 5536 5453 +3 4823 4054 871 +3 4932 4633 5278 +3 871 4054 5551 +3 5624 4055 6031 +3 1446 4620 4057 +3 6211 5558 7046 +3 3476 4058 7187 +3 3326 4062 3796 +3 7520 4010 1916 +3 3796 4062 4063 +3 4332 4063 807 +3 676 561 1584 +3 807 4063 4058 +3 3477 4064 778 +3 4008 4012 2767 +3 6364 4065 4069 +3 5707 4762 5809 +3 3528 4069 3355 +3 3355 4069 4064 +3 3710 3708 3919 +3 5238 4070 6188 +3 4071 1311 1317 +3 3051 4073 394 +3 3963 2005 1848 +3 6186 3994 394 +3 3878 3879 713 +3 4622 4075 3107 +3 3107 4075 5726 +3 3035 5643 1076 +3 16 4269 4316 +3 4267 4079 6889 +3 6187 4080 925 +3 7515 4742 2438 +3 3089 3088 3305 +3 3959 3960 6721 +3 5651 4084 4088 +3 1580 4085 1264 +3 2129 3230 6576 +3 4701 4544 3957 +3 3056 4086 4868 +3 4868 4086 4085 +3 4080 4084 925 +3 4857 5316 4649 +3 4088 4085 395 +3 1317 6128 3953 +3 4874 4089 17 +3 3567 4090 5368 +3 5368 4090 4091 +3 396 4091 3155 +3 3624 2829 1472 +3 2360 3951 3161 +3 3572 808 405 +3 3155 4091 4089 +3 4024 4094 2349 +3 5201 5243 708 +3 4285 5888 7200 +3 2349 4094 4101 +3 5878 3989 895 +3 2332 4096 5367 +3 6710 5367 1546 +3 7095 7111 4569 +3 4018 4019 3739 +3 562 1386 877 +3 2358 3457 3340 +3 3340 6904 3364 +3 2037 4099 4100 +3 5189 4100 4061 +3 4061 4100 6596 +3 4220 2441 2709 +3 2430 3949 6138 +3 3984 5008 499 +3 4095 4094 5878 +3 4779 4102 3558 +3 3558 4102 5239 +3 3430 3379 3425 +3 3467 4103 5520 +3 2698 4105 4103 +3 1496 1083 7415 +3 4529 3947 4568 +3 4117 3850 4580 +3 1496 4106 7107 +3 4107 4202 7106 +3 4202 4107 6270 +3 3944 2061 4442 +3 670 3074 1706 +3 5865 4387 3941 +3 6354 2948 7119 +3 4887 5206 6903 +3 4268 4109 4685 +3 3674 4110 5161 +3 6319 69 6318 +3 5161 4110 4111 +3 3734 4111 1566 +3 2803 4232 5159 +3 1566 4111 4109 +3 1731 1567 5532 +3 2319 1193 2422 +3 5544 5548 399 +3 7391 7389 1149 +3 7510 2916 7514 +3 5997 2982 667 +3 595 4113 3701 +3 6046 4113 400 +3 4114 383 400 +3 2740 5692 1557 +3 3449 3105 3142 +3 5840 4114 446 +3 1727 2968 3383 +3 4203 4115 4445 +3 4445 4115 402 +3 3338 3337 1548 +3 2332 5367 3337 +3 3401 6800 4096 +3 2699 2523 4599 +3 403 4115 3261 +3 2234 4119 3171 +3 2458 4128 3927 +3 6773 3191 4996 +3 416 5207 4167 +3 5207 4121 4122 +3 1059 450 4041 +3 6305 3628 944 +3 2408 4122 3248 +3 4269 2935 12 +3 3248 4122 4120 +3 7012 7334 293 +3 6654 6617 263 +3 4027 6211 6355 +3 2249 4048 2578 +3 4318 1799 2889 +3 7488 7487 199 +3 3895 4319 4355 +3 3814 6842 5146 +3 2818 3918 221 +3 2978 4374 4359 +3 3128 4125 5878 +3 2469 4126 2471 +3 2471 4126 6107 +3 3927 3925 6754 +3 4753 6517 3709 +3 3855 4130 4551 +3 4551 4130 6352 +3 3537 4131 1067 +3 1908 1014 2812 +3 1908 1473 1014 +3 3271 4132 3170 +3 4494 7139 3134 +3 6134 6127 158 +3 3170 4132 5273 +3 3482 3483 3382 +3 1640 4134 4787 +3 4129 1275 2885 +3 4787 4134 6367 +3 3551 4148 4123 +3 1590 4127 1160 +3 407 7291 3946 +3 3169 4138 1401 +3 406 3711 4543 +3 2336 3711 406 +3 5342 4319 3895 +3 6294 5347 3915 +3 566 4154 3882 +3 6771 4140 4141 +3 2603 5744 3254 +3 4321 4141 1035 +3 1035 4141 5465 +3 4142 4183 166 +3 436 3774 4124 +3 4265 4144 4398 +3 2822 3911 5857 +3 3008 4145 5840 +3 5840 4145 1949 +3 4626 3157 186 +3 4123 3572 405 +3 3950 5342 6909 +3 6541 4149 2270 +3 2270 4149 1345 +3 5837 5836 3728 +3 3110 4343 4319 +3 4005 6504 4119 +3 885 4151 1035 +3 410 580 2648 +3 4783 580 2209 +3 562 680 1386 +3 1292 4555 5100 +3 2771 6652 7203 +3 4965 4152 2629 +3 2629 4152 4293 +3 5449 5675 5427 +3 4954 4153 5583 +3 412 6454 6311 +3 5532 4599 2523 +3 412 6091 6454 +3 2339 5967 797 +3 5808 6020 1100 +3 5302 4157 1479 +3 1479 4157 6650 +3 6537 5871 6267 +3 1077 2748 5657 +3 3322 5858 5152 +3 2730 5736 3908 +3 4013 4158 7344 +3 7344 4158 4579 +3 5504 6197 3898 +3 6965 4579 4158 +3 592 868 3061 +3 868 430 3061 +3 3266 4164 431 +3 798 3905 7009 +3 431 4548 3266 +3 5237 5712 1424 +3 1537 6078 413 +3 413 2343 1537 +3 7208 4343 3110 +3 1168 6859 1691 +3 3603 4502 2156 +3 676 1584 4165 +3 3073 6030 862 +3 6222 4165 3719 +3 3899 3901 5364 +3 3820 3564 4338 +3 1502 2168 3011 +3 1956 3325 3913 +3 1502 4167 4168 +3 6962 4168 802 +3 802 4168 4166 +3 6069 6848 852 +3 4171 3421 5432 +3 7482 7483 6428 +3 5089 3517 3634 +3 4082 2514 2701 +3 3828 4172 3608 +3 3604 4173 5049 +3 5147 7138 628 +3 5049 4173 4174 +3 2913 5544 4213 +3 4473 4174 5216 +3 5216 4174 4172 +3 2904 3247 5450 +3 4165 4222 676 +3 4213 4359 2913 +3 5237 3427 485 +3 7001 4175 6084 +3 5146 4175 7280 +3 3817 6806 2127 +3 7280 4175 2115 +3 6887 4177 6830 +3 3596 5156 340 +3 2912 6585 2125 +3 3243 4275 4178 +3 5053 4178 3578 +3 2190 5123 637 +3 4010 7066 4201 +3 637 6214 5043 +3 418 7248 3212 +3 7248 4181 6717 +3 2731 4184 343 +3 6238 3661 1972 +3 5975 6699 2958 +3 3116 5312 5221 +3 2090 420 5637 +3 481 2239 6 +3 4185 481 6 +3 2125 4389 2912 +3 5674 1799 4083 +3 2115 1515 5362 +3 4192 4193 4365 +3 4365 7401 4192 +3 2759 4396 5098 +3 2277 4193 1199 +3 1199 4193 4190 +3 1731 5494 5803 +3 6893 4325 3741 +3 1621 2395 2353 +3 5532 5494 1731 +3 2530 1576 3285 +3 6188 4198 1017 +3 1017 4198 4798 +3 3344 6197 5504 +3 7084 4199 6988 +3 3836 4232 2803 +3 4199 287 5576 +3 426 4200 841 +3 4115 3270 3261 +3 4891 829 553 +3 4206 297 1478 +3 841 297 4206 +3 1824 540 591 +3 2126 4389 753 +3 1138 3892 4964 +3 2171 5392 6111 +3 1161 6065 427 +3 6959 5693 428 +3 5449 5336 338 +3 428 4208 6959 +3 1777 4853 5922 +3 4277 3406 5267 +3 6126 4208 6687 +3 6687 4208 2354 +3 399 790 5544 +3 4213 5138 4727 +3 338 5675 5449 +3 4969 5138 790 +3 3061 430 431 +3 431 433 4548 +3 1154 2878 1441 +3 4215 4738 5229 +3 4217 4738 433 +3 432 3987 4463 +3 2356 2714 370 +3 2562 3887 6511 +3 4399 4218 501 +3 3656 5428 3886 +3 2975 6939 4078 +3 2975 4219 4221 +3 7216 4221 4730 +3 447 381 7303 +3 4730 4221 4218 +3 6754 3925 2126 +3 437 3534 2196 +3 4209 4223 6828 +3 1947 4224 3142 +3 1172 4226 591 +3 591 4226 4227 +3 3998 4435 4424 +3 2830 4227 5701 +3 5701 4227 4224 +3 6553 2495 1734 +3 4620 5875 3629 +3 3487 4229 7390 +3 667 225 3522 +3 828 4229 6677 +3 7390 4229 529 +3 4231 3343 934 +3 2123 5500 4425 +3 6032 4545 4939 +3 6237 4233 5461 +3 5461 4233 5297 +3 3013 7320 5493 +3 1690 7320 3013 +3 4972 4234 2517 +3 2517 4234 1667 +3 4394 4235 2708 +3 3505 3746 2346 +3 5811 4364 4804 +3 2708 4235 4436 +3 4019 4236 3739 +3 3856 4238 6787 +3 6787 4238 6180 +3 5100 4239 1292 +3 6091 4239 7110 +3 180 4425 5500 +3 3578 4178 3885 +3 916 921 7002 +3 4237 4240 1213 +3 2974 4241 2997 +3 4241 440 4242 +3 3976 3975 2802 +3 4376 2244 7088 +3 6968 4242 2357 +3 2298 4241 3201 +3 8 5620 7506 +3 442 7195 8 +3 4178 5053 3243 +3 912 4247 1108 +3 2878 6116 5038 +3 1358 3888 821 +3 1358 821 593 +3 5509 4400 6487 +3 3290 3096 4283 +3 1818 824 592 +3 2120 4425 2122 +3 3728 3714 2808 +3 3221 4250 5668 +3 3343 5811 4804 +3 5668 4250 6827 +3 3298 4252 5844 +3 602 5437 6766 +3 4253 4821 1811 +3 4821 4253 1002 +3 446 3008 5840 +3 4254 449 2361 +3 952 3138 2231 +3 952 2231 4255 +3 449 3701 4256 +3 1854 2773 2120 +3 4798 4257 241 +3 3227 4258 5948 +3 3882 1401 566 +3 5948 4258 5801 +3 1892 4262 508 +3 2934 4264 7277 +3 7277 7229 2934 +3 2540 4321 7146 +3 4903 4265 5760 +3 2413 4266 4685 +3 4685 4266 4268 +3 5480 6275 1574 +3 1526 1697 3709 +3 1412 2589 1766 +3 4003 4268 4398 +3 3855 3856 6787 +3 4398 4268 4265 +3 3194 1294 6749 +3 456 6383 1954 +3 4074 3878 386 +3 4949 6685 1853 +3 1196 4270 1679 +3 3876 2242 151 +3 4632 5281 7127 +3 2893 1799 5674 +3 1427 2597 1190 +3 3934 3929 1056 +3 1574 4082 2701 +3 3873 3874 713 +3 7229 4469 2123 +3 4271 1107 2943 +3 1107 4271 1679 +3 458 4170 752 +3 6069 4273 1609 +3 6906 7299 6869 +3 2991 4275 4751 +3 3852 4404 1506 +3 459 5689 6341 +3 459 1340 5689 +3 3727 2724 5976 +3 5068 863 4476 +3 2757 5973 176 +3 4278 1215 2750 +3 2750 1028 4278 +3 6830 7104 7112 +3 6830 4177 4279 +3 4520 4279 4284 +3 6830 4279 2737 +3 7329 7488 1120 +3 4565 4466 3871 +3 460 1813 5303 +3 1287 928 6163 +3 1813 4280 1605 +3 1799 2893 3363 +3 6860 4048 5876 +3 5927 872 756 +3 3775 4281 910 +3 892 4286 1234 +3 1234 5094 892 +3 4733 3540 3675 +3 316 7487 4316 +3 1551 4288 2164 +3 793 3675 816 +3 2317 2626 3863 +3 1428 2251 4602 +3 1111 3191 3771 +3 4411 7336 2769 +3 1595 4289 2008 +3 4289 2904 6401 +3 4842 4290 5960 +3 5410 4291 4997 +3 4997 4291 4556 +3 4292 1837 5857 +3 5214 5235 5907 +3 4153 4152 5583 +3 2000 4860 3860 +3 3190 4295 3313 +3 3313 4295 4391 +3 344 1398 5746 +3 4566 5694 2386 +3 4300 6302 1863 +3 6302 4300 5590 +3 3266 4301 3182 +3 3182 4301 6689 +3 1547 4302 3904 +3 914 4302 4348 +3 4497 4304 6865 +3 3434 1963 775 +3 4177 4308 4307 +3 6068 4309 2780 +3 6108 4310 2471 +3 2471 4310 5457 +3 4077 454 5408 +3 6324 1361 4311 +3 4288 4313 4835 +3 4835 165 4288 +3 6995 4314 4834 +3 4834 4314 6961 +3 1958 6341 5689 +3 2419 4483 4517 +3 1210 696 2800 +3 4854 1791 1786 +3 1088 1721 1541 +3 462 461 1088 +3 7248 5162 903 +3 6227 4317 3494 +3 6825 3494 2763 +3 2159 4483 2419 +3 4551 7490 3855 +3 1035 4151 4321 +3 6247 5863 6329 +3 6085 5470 4690 +3 1317 3953 4071 +3 2864 6135 4322 +3 4211 4495 4731 +3 717 4323 1785 +3 3741 4325 4327 +3 4285 4327 5888 +3 3134 846 2045 +3 5888 4327 2653 +3 5712 5237 5585 +3 3427 5237 1424 +3 2851 1955 6464 +3 3651 6336 5032 +3 354 6495 6726 +3 6981 4491 4483 +3 6431 3618 7204 +3 6536 4331 807 +3 4063 2969 3796 +3 7311 3955 3848 +3 7475 4332 6023 +3 2438 4742 2876 +3 6231 3371 271 +3 6965 4158 4336 +3 498 3755 6427 +3 2114 6113 893 +3 2315 1320 6226 +3 6226 3494 2315 +3 5371 2536 1332 +3 5149 2285 2705 +3 2313 421 251 +3 4517 5004 971 +3 369 7466 999 +3 3368 4337 5960 +3 3626 4396 7058 +3 3145 7010 3228 +3 2472 5441 1032 +3 4337 1451 883 +3 3264 5035 1195 +3 3264 4342 6714 +3 5253 960 4005 +3 2512 5574 2787 +3 4646 1052 6872 +3 6872 3646 4646 +3 4941 4344 3195 +3 3195 4344 7152 +3 6097 4345 786 +3 2885 2421 4129 +3 2368 2371 930 +3 2555 930 2371 +3 4349 787 1720 +3 787 4349 2707 +3 1263 3479 5433 +3 333 1038 4668 +3 5955 4351 4176 +3 6725 4351 4624 +3 3831 4668 5425 +3 4918 94 5243 +3 6233 7487 316 +3 2108 5113 4550 +3 2428 6895 3829 +3 2500 4352 2274 +3 5516 5517 695 +3 2274 4352 5714 +3 3852 4406 3998 +3 4353 4711 4151 +3 4711 4353 5714 +3 6301 6967 2557 +3 2821 6857 6121 +3 2167 4356 1224 +3 1224 4156 2167 +3 3928 4357 472 +3 472 6003 1223 +3 2472 5550 3828 +3 473 5092 2113 +3 473 719 5092 +3 5054 4360 5453 +3 3269 5637 2513 +3 4326 639 3473 +3 2502 4362 5996 +3 5470 5068 2615 +3 5996 4362 2582 +3 1801 6409 3405 +3 2375 4363 7262 +3 3502 4366 475 +3 4628 3248 475 +3 891 4367 4315 +3 3951 6304 3161 +3 5125 5586 3826 +3 4315 4367 4370 +3 5586 5125 4441 +3 2101 4368 7262 +3 3479 1466 1132 +3 7262 4368 2375 +3 5421 6571 6495 +3 3369 3371 6231 +3 478 2005 1237 +3 2005 4372 1845 +3 3220 5042 7418 +3 5815 3099 490 +3 6104 4975 3823 +3 4974 1162 1391 +3 2051 3237 7048 +3 858 2109 4578 +3 4441 4460 3602 +3 5248 923 4377 +3 2515 3158 7417 +3 2961 1407 968 +3 5498 5747 2250 +3 3905 4379 7009 +3 3480 3481 2834 +3 2393 4443 2555 +3 5681 4594 2859 +3 1493 4595 4725 +3 2994 2686 4379 +3 2898 3582 6552 +3 3010 4818 2409 +3 3393 6034 4984 +3 2255 496 3997 +3 3417 6561 3822 +3 496 5365 3997 +3 1288 5704 6169 +3 3686 4881 7433 +3 4699 631 4386 +3 2297 4386 1187 +3 5521 6437 7364 +3 3941 3942 2333 +3 3496 3942 4387 +3 5679 2521 5596 +3 7169 4388 82 +3 82 4388 990 +3 4338 6488 3820 +3 6982 4635 5761 +3 3767 4656 1357 +3 287 990 4305 +3 3896 7126 75 +3 3818 3149 175 +3 75 1573 3896 +3 330 3811 2086 +3 2861 2257 5850 +3 981 5502 503 +3 4293 4295 2629 +3 4392 3313 4391 +3 5945 4392 1024 +3 1024 3320 5945 +3 4900 4394 2896 +3 3485 3278 5708 +3 2048 6177 3810 +3 6315 4395 4397 +3 6175 4397 2708 +3 2708 4397 4394 +3 504 6776 1579 +3 3047 4399 501 +3 1078 3921 2737 +3 2691 6266 4908 +3 3483 4402 3382 +3 5815 2376 1217 +3 4448 4405 6883 +3 1176 3804 932 +3 3152 4443 2393 +3 6151 4407 361 +3 361 4407 4408 +3 3046 4408 5134 +3 5134 4408 4405 +3 5343 5757 2563 +3 3414 4409 7358 +3 505 3779 2015 +3 505 4479 3779 +3 4786 5415 3800 +3 3348 5607 1133 +3 6886 5411 3798 +3 506 5683 4973 +3 2385 2622 826 +3 2102 4914 5847 +3 5226 4415 5492 +3 6202 4416 2985 +3 2985 4416 5636 +3 4808 4809 2473 +3 3245 1961 5752 +3 1314 4417 4418 +3 804 7151 4525 +3 4682 4795 7015 +3 3692 4418 1402 +3 1402 4418 4725 +3 2754 4420 512 +3 512 6166 2754 +3 2304 4423 3216 +3 3216 4423 510 +3 1252 1404 514 +3 514 4420 1252 +3 2834 2979 1016 +3 4426 327 3507 +3 327 4426 6475 +3 702 4427 85 +3 85 4427 6475 +3 5991 1797 6763 +3 4966 2680 5613 +3 4429 4237 1213 +3 6774 6726 4812 +3 4237 4429 517 +3 3521 5563 2687 +3 515 7075 5941 +3 4433 2921 3233 +3 2920 7470 3591 +3 6172 2420 3234 +3 3571 6389 4318 +3 517 658 4433 +3 1691 4873 1168 +3 4236 4235 3739 +3 6287 6265 2252 +3 2115 5362 6797 +3 7425 5057 1090 +3 518 6174 6175 +3 7374 688 689 +3 520 1291 7374 +3 4439 2093 2983 +3 2470 3791 2809 +3 1174 6051 2570 +3 4312 3826 6607 +3 522 2061 6441 +3 7450 2883 5619 +3 6301 5443 3303 +3 525 4403 4422 +3 4350 4450 546 +3 4444 4442 1429 +3 1976 5568 756 +3 2033 6868 4143 +3 4405 3995 5134 +3 1356 4448 5217 +3 4567 4449 4350 +3 546 3062 4506 +3 3062 4450 6376 +3 5744 5767 2630 +3 4533 5279 87 +3 3042 464 3304 +3 44 4315 4370 +3 5533 3600 508 +3 3012 6743 2855 +3 146 3788 3884 +3 3598 4452 1444 +3 4453 5368 396 +3 5368 4453 4454 +3 4191 4454 4452 +3 2465 2724 2688 +3 851 528 1883 +3 6485 4456 7201 +3 2555 4443 2887 +3 4458 7201 528 +3 1079 4244 1208 +3 4458 2096 3037 +3 4546 4462 4855 +3 6746 4464 5483 +3 5483 4464 5890 +3 3880 3735 632 +3 4239 5100 3593 +3 415 4644 2906 +3 7385 703 5017 +3 3871 3872 4137 +3 938 4466 533 +3 7131 4467 4746 +3 3783 3785 5047 +3 4746 4467 2391 +3 534 4565 1529 +3 4568 5895 4529 +3 534 4466 4565 +3 4024 4471 4850 +3 5551 4472 5216 +3 5216 4472 4473 +3 4174 3315 5049 +3 2218 4473 4471 +3 3347 4474 5161 +3 4552 6317 3782 +3 6940 2803 5159 +3 2682 3780 976 +3 7351 4475 5148 +3 5148 4475 6731 +3 6963 6894 5909 +3 1394 1696 5499 +3 3655 4477 6294 +3 6294 4477 969 +3 6441 4478 1407 +3 2062 1312 4272 +3 1407 4478 968 +3 2384 5683 506 +3 1843 4480 2264 +3 1051 4480 4640 +3 2544 6817 2534 +3 3460 4481 4703 +3 3722 3724 5524 +3 6053 4644 415 +3 6313 3681 1722 +3 1183 4482 4434 +3 881 4222 4165 +3 4482 2392 1504 +3 2729 4481 5832 +3 5832 1507 2729 +3 677 3616 997 +3 7322 3954 5919 +3 4488 5730 2774 +3 6411 6409 4840 +3 6623 4489 1788 +3 3077 2338 2258 +3 4488 4489 1877 +3 2680 4966 3777 +3 2331 3183 6882 +3 7418 5042 7348 +3 2100 4644 7218 +3 3179 1864 3265 +3 6093 3314 7251 +3 1443 4490 5972 +3 6586 4674 2719 +3 5122 4507 3769 +3 2996 4220 6004 +3 5972 4490 2022 +3 2090 3768 2983 +3 1956 3029 3325 +3 577 6747 6626 +3 540 543 1403 +3 2099 2100 6888 +3 3698 3010 1761 +3 7243 6033 6024 +3 4862 4497 341 +3 3213 626 4984 +3 2000 3860 3760 +3 4497 4498 3533 +3 5991 4443 3152 +3 1905 4822 1144 +3 4498 6865 5922 +3 3016 4499 7239 +3 2426 4500 1736 +3 1736 4500 5404 +3 2506 6935 7145 +3 7228 3516 1462 +3 4503 1522 1153 +3 5221 5048 3116 +3 3916 3236 1633 +3 2101 7262 5141 +3 4687 4728 7063 +3 5008 6834 499 +3 3730 3993 5259 +3 1327 4505 4320 +3 6926 1624 3758 +3 6168 4505 88 +3 3079 2607 2664 +3 2524 6287 3436 +3 6277 6935 2506 +3 6763 2996 6004 +3 602 880 4647 +3 181 4693 4687 +3 88 4505 2673 +3 6165 6152 92 +3 831 3022 5784 +3 3769 3770 3633 +3 3833 4800 4524 +3 2200 4507 4509 +3 1406 4509 3062 +3 4340 3755 4830 +3 3062 4509 4506 +3 636 4511 6035 +3 6035 4511 4670 +3 1261 4047 3749 +3 7156 6631 3748 +3 5955 2155 3723 +3 194 4513 1746 +3 1746 4536 194 +3 2692 3738 4320 +3 2815 4514 492 +3 492 4514 6955 +3 225 667 2982 +3 7076 4515 81 +3 6189 4516 7300 +3 1814 2816 6192 +3 2359 548 4066 +3 548 6088 4066 +3 973 4521 2727 +3 2727 4521 6985 +3 5912 4522 7214 +3 643 4308 1621 +3 3452 6794 3771 +3 5850 7486 2861 +3 2273 4526 1717 +3 1717 4526 5631 +3 4528 5688 137 +3 3346 3183 2331 +3 1496 3845 3372 +3 4867 6710 1546 +3 7034 4529 6892 +3 1901 5377 6668 +3 6005 7341 2617 +3 3733 3734 1566 +3 55 7014 6935 +3 6641 6653 2137 +3 6800 3401 5831 +3 6247 4104 4670 +3 4693 181 2901 +3 4573 4476 6404 +3 4573 4533 6383 +3 6999 3619 4535 +3 6888 4728 2099 +3 7211 5137 4535 +3 172 7270 2764 +3 2544 4535 3619 +3 5146 7280 6676 +3 676 2188 561 +3 2299 2645 733 +3 6419 6793 560 +3 560 4537 6419 +3 4537 3945 278 +3 561 3945 4537 +3 2340 4538 6667 +3 3556 5311 3555 +3 6351 2527 563 +3 4577 3665 4559 +3 275 2377 5662 +3 4557 4540 4830 +3 7317 7017 1859 +3 4304 6487 5762 +3 3201 5351 2298 +3 3824 3048 5623 +3 3203 281 3123 +3 1953 870 2877 +3 1509 4543 3711 +3 2339 4543 5967 +3 7063 7064 2799 +3 5967 4543 983 +3 846 3134 4092 +3 4966 5613 3535 +3 5493 7320 162 +3 2878 5038 1966 +3 3957 3955 7311 +3 6038 6993 708 +3 1642 1654 3954 +3 4612 4546 3462 +3 3462 4546 4990 +3 5994 7353 6505 +3 567 4555 1292 +3 6487 4400 5762 +3 3996 2497 4943 +3 1861 111 3790 +3 111 1861 2870 +3 3388 4555 6148 +3 4290 4291 5960 +3 3353 4558 3497 +3 3497 4558 4791 +3 3100 3101 668 +3 6649 4697 4272 +3 6115 5597 3290 +3 5903 6969 1918 +3 572 679 3101 +3 2447 3183 3346 +3 5760 4266 2413 +3 172 6463 2537 +3 2317 4564 2626 +3 5685 4564 2364 +3 570 2364 4564 +3 1111 3071 3191 +3 5188 2718 3448 +3 6969 5903 5163 +3 5324 4567 2104 +3 1225 4778 2905 +3 1708 6193 2228 +3 5943 7085 4376 +3 2228 4569 1708 +3 656 6270 4107 +3 5476 730 2813 +3 4996 3191 3071 +3 3114 703 889 +3 3905 3906 2897 +3 2460 4571 2531 +3 2531 4571 4572 +3 2788 4778 1225 +3 3256 2193 6096 +3 6795 5269 2980 +3 1568 798 7009 +3 856 5478 1533 +3 2336 750 3711 +3 1797 7428 92 +3 6148 4547 5269 +3 3151 844 3147 +3 3151 966 3416 +3 2446 4575 967 +3 967 1329 2446 +3 3718 4795 5422 +3 196 2772 7185 +3 1077 498 6427 +3 498 4582 4852 +3 1253 6391 5403 +3 1899 2676 6846 +3 3717 7032 7327 +3 4557 4830 4852 +3 3402 4585 2325 +3 5757 4341 3121 +3 6919 4586 3617 +3 7256 5353 2862 +3 5214 7069 5236 +3 3617 4586 5173 +3 4587 6761 1755 +3 3758 2930 3377 +3 2597 1436 882 +3 4588 383 4114 +3 383 4588 6719 +3 5320 5906 5918 +3 5862 4794 2097 +3 575 3045 2276 +3 7078 1953 68 +3 2292 4614 1116 +3 6546 1081 5659 +3 6310 4794 5862 +3 2403 126 1081 +3 6538 3384 1087 +3 6388 4596 1220 +3 1368 4597 1088 +3 1088 4597 4598 +3 1883 3899 851 +3 4577 1729 1730 +3 1719 4598 2103 +3 2103 4598 4596 +3 6389 3571 3713 +3 1290 4600 4603 +3 4603 516 1290 +3 6620 4603 5005 +3 2022 4604 5972 +3 5972 4604 582 +3 2293 1876 2291 +3 772 4070 3710 +3 3700 3703 2206 +3 7117 6249 321 +3 2977 22 276 +3 3633 4605 2404 +3 6289 3454 583 +3 1194 4802 4870 +3 583 4604 577 +3 2288 4607 3064 +3 3064 4607 587 +3 605 4608 2405 +3 7004 5703 3705 +3 2405 6580 605 +3 3697 976 1378 +3 586 4281 3775 +3 589 4607 1831 +3 4015 4610 3776 +3 3330 4611 3462 +3 1962 4802 1194 +3 6797 5362 1095 +3 3462 4611 4612 +3 2870 1861 6934 +3 4462 4612 6469 +3 3209 4825 4802 +3 6469 4612 4610 +3 3988 4656 6704 +3 1256 4613 3669 +3 3669 4613 980 +3 5381 7354 2849 +3 7472 4825 3209 +3 4322 4618 2864 +3 3886 4619 1725 +3 3034 6720 3695 +3 2867 3087 457 +3 2837 1683 2542 +3 3457 3458 4884 +3 2132 7182 1808 +3 4870 2511 1983 +3 3693 3817 2127 +3 739 6602 3692 +3 4623 3271 3170 +3 3688 3689 4527 +3 2358 4623 4621 +3 7454 4628 1945 +3 6697 4625 1726 +3 1726 4625 5331 +3 574 5331 4625 +3 598 7454 1387 +3 4883 4648 2355 +3 596 4366 3764 +3 3248 4628 2408 +3 6061 3685 3117 +3 4338 3564 2407 +3 3089 4631 925 +3 5955 7096 2155 +3 925 4631 6190 +3 5781 1339 2887 +3 3516 4636 205 +3 2355 33 4883 +3 3577 6110 3005 +3 2048 4637 6453 +3 3501 650 2988 +3 6067 1894 5715 +3 758 1336 738 +3 304 3678 7290 +3 4234 4639 993 +3 993 4639 4718 +3 664 5166 2831 +3 4479 4480 3779 +3 1051 4640 601 +3 1548 4641 3680 +3 6035 5934 6671 +3 3291 4641 600 +3 600 4796 216 +3 3156 3127 1448 +3 4128 4643 2199 +3 7484 1466 3479 +3 2199 4643 5817 +3 550 5633 7407 +3 4185 4871 481 +3 6287 5473 3436 +3 1002 4647 4821 +3 5166 664 2587 +3 4821 4647 875 +3 1210 783 3176 +3 616 7241 4824 +3 4652 1398 7293 +3 632 4653 3880 +3 5903 7004 3705 +3 1067 4130 3673 +3 4474 4655 5630 +3 5630 4655 7161 +3 3444 4659 3985 +3 4907 4658 3447 +3 3985 5814 3444 +3 3985 4659 5435 +3 2828 5723 3801 +3 720 3064 587 +3 2414 4662 4694 +3 4858 4694 720 +3 5875 4620 1446 +3 2089 4439 521 +3 608 7314 7181 +3 608 731 2087 +3 1909 1910 4534 +3 3168 4664 42 +3 42 4664 607 +3 3972 3973 5430 +3 6735 4666 2411 +3 611 2086 5749 +3 131 3176 783 +3 611 298 2086 +3 3069 5856 4496 +3 3554 4991 6861 +3 3383 2790 1727 +3 826 4669 2385 +3 1164 4512 3045 +3 2050 4671 1543 +3 7383 2434 4832 +3 1543 4671 1674 +3 1456 4972 2517 +3 409 697 6268 +3 4040 6877 1615 +3 1313 7376 6217 +3 7376 4675 5295 +3 6676 7280 5061 +3 4676 195 3238 +3 4749 2271 3583 +3 7370 6282 1936 +3 7370 4678 4679 +3 4805 4679 3910 +3 4083 6389 3365 +3 3910 4679 4677 +3 4599 6977 2619 +3 1694 674 5938 +3 7115 4681 5600 +3 5600 31 4958 +3 7407 6549 3825 +3 6941 4911 4906 +3 4683 5467 1569 +3 3378 7251 3314 +3 5467 4683 4619 +3 3825 550 7407 +3 1725 4619 4406 +3 5816 5099 1134 +3 6860 80 5178 +3 4110 4684 4685 +3 4684 618 2413 +3 6549 6664 3825 +3 617 4686 1630 +3 7425 3236 800 +3 944 3628 6957 +3 2775 4686 618 +3 618 7190 2775 +3 5633 550 4566 +3 6123 2293 3715 +3 2293 5703 7004 +3 3919 3708 777 +3 6095 4911 6941 +3 625 5982 1418 +3 2165 4692 4428 +3 4639 4972 1336 +3 2440 624 2414 +3 355 2730 3908 +3 2414 4694 2440 +3 4748 5872 2713 +3 937 4695 5641 +3 6103 7460 6668 +3 4696 2897 1935 +3 2897 4696 4698 +3 5061 6797 5979 +3 630 1166 6331 +3 630 4695 1166 +3 2453 2001 2297 +3 1287 4699 7392 +3 5538 445 6224 +3 3028 4815 6507 +3 1471 4815 778 +3 4700 487 604 +3 4408 4706 361 +3 361 4706 4707 +3 3973 4707 5430 +3 5430 4707 4700 +3 5052 5527 335 +3 4710 4033 5460 +3 4712 6012 6432 +3 3918 4713 221 +3 3148 7386 4060 +3 6844 1703 4383 +3 634 3456 6289 +3 121 4714 7137 +3 3652 3653 3463 +3 3024 334 2157 +3 3425 4715 996 +3 3430 3431 2476 +3 1146 4716 1126 +3 758 4639 1336 +3 4511 4719 6267 +3 6267 4719 7226 +3 6200 460 1951 +3 1951 7313 6200 +3 6566 4721 483 +3 4721 1951 2417 +3 5537 5290 4035 +3 6225 4722 5290 +3 5079 3024 2157 +3 47 1493 2110 +3 3773 4724 2907 +3 369 3705 4001 +3 641 4725 4418 +3 1321 4251 2953 +3 1402 4725 4595 +3 1440 3660 2761 +3 5918 4727 5138 +3 2978 4727 5906 +3 7159 334 3441 +3 3633 3770 3657 +3 645 2593 4893 +3 645 4869 2593 +3 3575 725 3090 +3 5279 4533 6404 +3 2546 4982 3834 +3 2382 4732 781 +3 697 409 4646 +3 959 761 6767 +3 781 5704 2382 +3 301 7117 6986 +3 3659 1450 2842 +3 3205 1031 649 +3 3205 4734 784 +3 3517 1576 3634 +3 493 665 1228 +3 2546 4735 2041 +3 5264 4736 5652 +3 1816 2541 4715 +3 1852 7159 3441 +3 5652 4736 2043 +3 1450 3659 5837 +3 1938 2749 4050 +3 1760 2988 650 +3 1880 5180 5924 +3 2409 1761 3010 +3 7370 7372 6282 +3 6476 4737 1193 +3 1193 4737 655 +3 700 2287 3669 +3 4982 2546 2041 +3 13 1952 654 +3 3499 1320 2315 +3 654 4741 6182 +3 3673 4741 1067 +3 653 1067 4741 +3 3798 4744 6886 +3 4745 956 4826 +3 956 4745 4776 +3 857 657 2348 +3 1243 4748 2713 +3 5805 5363 3645 +3 5521 114 3217 +3 1515 7001 1793 +3 4754 1258 1241 +3 3496 6167 3644 +3 4754 5628 1070 +3 1060 5211 2212 +3 4756 3761 4510 +3 6677 4760 104 +3 3079 1915 5876 +3 1070 1258 4754 +3 2528 5224 5265 +3 7087 4761 3451 +3 4325 623 6365 +3 14 5064 5069 +3 4764 6117 5571 +3 4410 2574 4038 +3 323 3641 3112 +3 661 1267 4885 +3 1547 4766 6132 +3 6132 4766 5547 +3 4584 5547 4766 +3 6243 4767 5992 +3 5992 4767 5986 +3 4895 3702 972 +3 2816 4516 3395 +3 1590 6914 4127 +3 747 4988 6718 +3 4897 2450 1367 +3 2721 4771 124 +3 668 4593 3100 +3 7052 5900 6027 +3 2973 4773 63 +3 6580 4335 3638 +3 2286 5926 1419 +3 673 4775 3806 +3 1690 4895 972 +3 3630 4204 4945 +3 6076 6778 1856 +3 4775 2990 977 +3 2990 4775 2425 +3 4744 4745 6886 +3 214 594 2758 +3 5064 14 2128 +3 3558 704 956 +3 4879 4779 3684 +3 3684 4779 4776 +3 134 4918 5201 +3 1124 5069 5064 +3 4673 2893 308 +3 4780 6608 4781 +3 4263 4318 2889 +3 2087 5242 7314 +3 680 1562 1386 +3 580 4783 6101 +3 4784 4191 417 +3 4191 4784 332 +3 5368 4785 3567 +3 3567 6491 264 +3 3063 5286 727 +3 3984 4789 2840 +3 3512 3227 5948 +3 7298 7435 2319 +3 3637 6982 4468 +3 4556 4558 4997 +3 5911 6298 3622 +3 4002 5982 379 +3 999 5903 3705 +3 4052 4792 683 +3 6991 2426 1736 +3 2402 3621 2260 +3 955 3225 684 +3 684 4792 4000 +3 3240 2862 686 +3 4257 4198 772 +3 1017 4798 7070 +3 2068 687 5081 +3 626 3213 1134 +3 1029 687 1192 +3 4524 4800 3756 +3 2429 5910 3756 +3 689 520 7374 +3 689 4801 5885 +3 5095 731 3153 +3 6074 4704 690 +3 4803 1766 6241 +3 6064 7113 6118 +3 3619 1534 2544 +3 3172 5895 6632 +3 7370 4679 5070 +3 3616 677 6838 +3 5121 5153 1006 +3 726 2767 4012 +3 726 4829 2767 +3 6503 160 6817 +3 3080 4807 5687 +3 5733 4808 2473 +3 1725 5820 3886 +3 5297 4809 5421 +3 1938 6215 1441 +3 5421 4809 6571 +3 1004 5545 312 +3 5388 7146 5396 +3 6889 4810 6162 +3 1812 6162 4810 +3 5819 3135 5211 +3 2461 3894 208 +3 817 1228 665 +3 6913 5052 3794 +3 692 3162 6156 +3 693 335 3682 +3 2084 2648 580 +3 698 5055 5264 +3 4817 5503 140 +3 1828 3732 904 +3 3732 1961 1971 +3 5385 3395 3843 +3 3723 4624 5955 +3 1961 3732 1828 +3 5028 1359 7325 +3 4060 3560 7387 +3 1278 5136 79 +3 3509 2959 4274 +3 3839 4819 3065 +3 3065 4819 6456 +3 2212 6350 6879 +3 3135 5819 131 +3 4054 3731 4850 +3 4093 7066 4009 +3 2420 1511 3988 +3 453 2667 2150 +3 5385 2283 290 +3 279 3264 1665 +3 453 3504 5999 +3 694 1934 864 +3 1697 7155 3912 +3 1971 4468 2879 +3 4826 956 704 +3 4827 1108 375 +3 1455 5136 7267 +3 1108 4827 912 +3 4162 4828 2714 +3 3021 6757 453 +3 4828 4826 902 +3 162 7320 3983 +3 3968 7018 4410 +3 705 5110 1331 +3 705 4829 5110 +3 4339 5165 7332 +3 2098 4806 6353 +3 2767 4829 2432 +3 5385 5570 3400 +3 4340 4830 4540 +3 4540 6526 4340 +3 3006 664 4601 +3 6860 6321 4048 +3 2438 1500 7516 +3 4832 3670 1804 +3 815 4311 801 +3 2422 7298 2319 +3 7000 4836 3568 +3 7390 4839 4836 +3 4290 3357 4665 +3 5194 5879 1682 +3 1500 2438 3683 +3 6652 1924 7203 +3 1607 2285 4630 +3 883 5960 4337 +3 2993 5924 5180 +3 6035 6671 636 +3 2465 3559 711 +3 711 3751 2465 +3 322 4845 1488 +3 537 1544 4846 +3 4457 4846 4847 +3 5315 4847 3196 +3 3196 4847 4845 +3 4927 4848 2424 +3 2424 4848 1307 +3 958 1361 715 +3 5086 3391 1307 +3 1307 715 2424 +3 3611 2591 6449 +3 1615 5908 6963 +3 886 889 5424 +3 2357 3610 6968 +3 2437 2517 1667 +3 498 4852 4830 +3 4852 1266 5151 +3 6244 5203 6948 +3 264 1266 6092 +3 2676 2872 4630 +3 2296 2276 79 +3 716 970 4428 +3 719 5257 5092 +3 541 1090 5057 +3 720 4662 3064 +3 4694 4858 931 +3 1364 6730 3605 +3 6834 5050 499 +3 3860 3861 4334 +3 4304 4862 1734 +3 1734 4862 4863 +3 2000 4863 4860 +3 5674 4083 78 +3 78 4864 5674 +3 3262 4864 3817 +3 4864 2442 103 +3 3645 4865 1445 +3 1445 4865 5729 +3 7015 3145 4682 +3 7313 7298 1020 +3 4361 4362 5202 +3 5996 2582 4840 +3 5948 5802 3604 +3 1491 748 47 +3 1259 3412 806 +3 247 4799 6125 +3 735 4872 4873 +3 1168 7051 5864 +3 7051 4873 4872 +3 6002 4874 1329 +3 1329 4874 1270 +3 2653 2898 5374 +3 702 3002 6744 +3 955 4000 2976 +3 1172 591 4030 +3 3774 6404 7409 +3 4789 4876 2840 +3 2840 4876 6205 +3 4471 4877 2218 +3 3311 4878 3684 +3 3684 4878 4879 +3 4102 4879 2349 +3 1255 782 2917 +3 2349 4879 4877 +3 564 2899 1415 +3 2899 564 729 +3 545 3603 5393 +3 2567 4510 732 +3 732 730 2567 +3 6664 6463 4016 +3 386 1445 4074 +3 737 1381 6142 +3 737 738 4889 +3 4799 6128 6126 +3 4911 4889 1336 +3 2952 4147 7484 +3 738 4890 758 +3 6755 4890 4542 +3 2892 3602 7244 +3 4542 4890 2448 +3 55 5168 7346 +3 723 2552 6180 +3 4385 2382 5704 +3 2417 483 4721 +3 1915 2278 2451 +3 5171 3122 3150 +3 4771 4897 1367 +3 2337 6965 4336 +3 747 2450 4988 +3 5991 3152 1797 +3 7279 4154 7136 +3 5016 3314 6692 +3 4235 4900 3739 +3 4018 3492 5034 +3 3488 4901 4902 +3 3485 4902 2896 +3 905 4929 3598 +3 2896 4902 4900 +3 5102 4144 4265 +3 1688 4904 4905 +3 4905 1513 1688 +3 2235 4905 4903 +3 4903 5760 2235 +3 7347 5168 5491 +3 3825 6664 1633 +3 5611 4907 2 +3 2 4907 2080 +3 1236 6266 1653 +3 3825 3666 550 +3 5602 2418 7378 +3 2258 5219 484 +3 4909 3237 1434 +3 1633 3666 3825 +3 2249 5876 4048 +3 3237 4909 7048 +3 2051 5987 5671 +3 4910 1676 1674 +3 2080 3737 2918 +3 5521 2075 6437 +3 3585 5052 6913 +3 6557 746 2452 +3 4155 4460 5125 +3 2784 763 745 +3 745 4913 5323 +3 2078 4907 3447 +3 1915 2645 2278 +3 1581 4913 746 +3 4179 6222 3038 +3 6587 943 1921 +3 1881 5508 1167 +3 5847 4914 5036 +3 4986 4916 5039 +3 923 5248 2151 +3 3626 4634 6424 +3 2659 1607 3794 +3 4335 5606 4765 +3 5273 4919 5904 +3 289 863 6884 +3 1887 4374 444 +3 2337 6990 5165 +3 3596 7476 5012 +3 2803 4922 3836 +3 6463 6664 6549 +3 3836 4922 5108 +3 1140 5231 6254 +3 5855 755 5541 +3 753 3186 4393 +3 753 4925 3186 +3 2111 4925 6459 +3 176 5970 2275 +3 6459 4925 4923 +3 256 6899 6355 +3 4848 3851 342 +3 3666 3068 550 +3 4191 4452 706 +3 2982 4025 225 +3 4191 706 417 +3 3251 6494 3243 +3 6637 3193 4966 +3 2161 2929 6736 +3 2929 4930 757 +3 4930 4964 965 +3 3322 5352 5858 +3 3001 3333 2995 +3 7344 3111 760 +3 760 4934 7344 +3 5931 4934 2453 +3 6517 4753 4820 +3 2453 2297 5931 +3 3097 4936 6732 +3 3702 2091 646 +3 6732 4936 766 +3 490 4377 2376 +3 4774 2452 764 +3 764 4938 3398 +3 2387 282 3981 +3 553 4938 4891 +3 762 4891 4938 +3 768 5734 1185 +3 768 5448 1005 +3 773 4434 5838 +3 773 1007 4434 +3 695 2992 357 +3 3544 4940 3195 +3 1466 7484 4147 +3 5309 6192 6033 +3 1205 994 451 +3 6585 5468 3592 +3 4397 4942 6315 +3 2272 750 4444 +3 6315 4942 4940 +3 1463 4943 3294 +3 5527 5154 3376 +3 5713 5808 5632 +3 2861 1179 5262 +3 4944 4204 1517 +3 2483 4945 5096 +3 6190 4946 5238 +3 5238 4946 986 +3 1985 2367 779 +3 779 5395 1985 +3 7353 6738 6505 +3 2008 4289 780 +3 781 4734 2693 +3 784 4952 5984 +3 5984 4952 6235 +3 5024 4717 3091 +3 6235 4952 6401 +3 2611 1902 5968 +3 4955 938 533 +3 4955 4957 1704 +3 2649 7483 4355 +3 1903 4957 4954 +3 1639 7427 5215 +3 4841 1437 1579 +3 4954 5583 1903 +3 3249 4959 6999 +3 4330 3453 5934 +3 6999 4959 785 +3 788 2583 1534 +3 3938 480 1457 +3 789 1246 7022 +3 5995 4962 479 +3 4351 5955 4624 +3 3961 3272 3289 +3 2629 4963 4965 +3 3367 4965 5977 +3 5977 4965 4962 +3 3446 6432 6012 +3 3781 1949 4144 +3 2271 4749 2666 +3 3777 3773 2907 +3 568 454 4077 +3 2903 7336 6046 +3 5935 4967 6300 +3 3968 3867 7341 +3 5481 4968 4648 +3 790 4213 5544 +3 5138 4969 5224 +3 4175 6842 6084 +3 795 3650 5529 +3 4886 4970 6498 +3 700 3669 980 +3 3237 2051 796 +3 796 5929 3237 +3 2222 4973 6104 +3 4044 4975 7124 +3 7124 4975 5340 +3 3468 4976 3706 +3 3941 4977 5865 +3 5865 4977 4978 +3 727 4978 3063 +3 3063 4978 3396 +3 4410 7018 2574 +3 5752 646 2756 +3 2305 2000 3791 +3 805 2945 2859 +3 358 4981 6417 +3 6417 4431 358 +3 5770 7498 305 +3 4093 3240 761 +3 1162 4148 164 +3 806 891 4315 +3 5533 6173 2062 +3 1421 4983 3118 +3 3118 5462 1421 +3 5847 5036 1259 +3 810 233 3412 +3 639 4326 7301 +3 583 577 3581 +3 4610 4987 6469 +3 6469 4987 5889 +3 5158 1140 6254 +3 811 3341 2379 +3 5377 3580 5378 +3 6160 1483 813 +3 4544 4546 4855 +3 6519 4992 2989 +3 2989 4992 4994 +3 6034 4838 2703 +3 3127 2967 1448 +3 4701 4994 4990 +3 205 4637 278 +3 3590 6608 130 +3 6312 4998 3681 +3 3681 4998 4999 +3 3305 3178 5001 +3 5399 5690 814 +3 1189 987 6191 +3 1948 3781 1689 +3 2479 2617 1227 +3 5135 6426 6088 +3 5006 2922 6121 +3 4755 2019 2324 +3 818 7476 3198 +3 3448 2718 7189 +3 7092 6834 5008 +3 3774 436 7092 +3 87 6090 1954 +3 3740 1470 214 +3 820 3025 3642 +3 5011 2813 729 +3 2813 5011 6539 +3 2534 6817 2485 +3 5149 366 2447 +3 7476 818 5007 +3 5012 2742 3596 +3 920 7002 5160 +3 3890 5014 6672 +3 5144 5018 500 +3 500 5018 7258 +3 1 5274 2902 +3 409 6268 4680 +3 3646 5617 6857 +3 4435 3998 3253 +3 1401 4139 566 +3 4354 1277 1884 +3 6205 5019 1009 +3 4683 3253 4406 +3 4215 5020 4548 +3 4548 5020 5026 +3 4301 5026 3232 +3 3232 5026 5019 +3 7325 5233 5028 +3 5617 3646 6872 +3 3801 6306 588 +3 249 1094 5030 +3 279 659 3264 +3 3620 6836 6503 +3 2499 3575 3090 +3 659 5035 3264 +3 1195 4553 1337 +3 815 4313 3742 +3 4553 5035 1082 +3 4916 810 1259 +3 4916 823 5039 +3 289 6884 6914 +3 1052 2250 5574 +3 6700 568 4077 +3 4766 5039 823 +3 2074 5671 5987 +3 5331 6346 4411 +3 5860 5043 6661 +3 5043 6214 2871 +3 2905 2782 1225 +3 4789 5045 2622 +3 2072 6605 2717 +3 1527 4991 4924 +3 2622 5045 826 +3 2836 1467 4147 +3 6164 2674 1643 +3 5318 5344 1930 +3 826 499 5050 +3 149 3519 827 +3 149 827 5051 +3 3243 5053 3884 +3 7026 7027 4011 +3 3742 6336 4733 +3 5797 5053 1442 +3 5536 6533 5054 +3 3333 3508 3986 +3 830 3206 480 +3 3024 5079 5692 +3 5062 3359 5660 +3 2035 5063 7232 +3 1981 3939 7407 +3 1763 5063 2489 +3 2489 4536 1763 +3 4454 4785 5368 +3 2613 5065 2764 +3 2605 4383 1703 +3 5071 2261 255 +3 2261 5071 7174 +3 1696 3554 2380 +3 4211 5072 1904 +3 1904 5072 6573 +3 3755 4340 2003 +3 6021 6522 3565 +3 5072 4731 6251 +3 834 5074 7489 +3 3283 5075 3083 +3 3435 5076 5397 +3 5397 5076 6288 +3 3562 4884 850 +3 6049 1500 694 +3 4784 5077 835 +3 5692 5079 6408 +3 835 4926 4784 +3 3632 5048 6284 +3 5080 833 992 +3 5341 5080 5074 +3 2715 3561 422 +3 5074 5077 7489 +3 5701 4224 3807 +3 3755 2003 809 +3 4876 5083 3232 +3 3232 5083 6686 +3 2385 5084 2622 +3 2665 5109 6625 +3 2432 2560 2767 +3 2388 4579 7437 +3 6757 6816 6773 +3 3265 1864 3122 +3 3495 3173 4859 +3 5619 6165 4447 +3 6281 5090 3167 +3 2290 2853 6844 +3 3167 5090 2594 +3 1332 6192 2816 +3 2853 1802 2496 +3 2518 2347 7171 +3 5401 5327 5318 +3 6669 6666 633 +3 3687 7459 7456 +3 839 3200 3299 +3 639 4545 4485 +3 4204 4944 5096 +3 3441 4087 1852 +3 5455 3055 2571 +3 7363 2483 842 +3 1113 6461 2663 +3 6883 3725 845 +3 2118 4580 4396 +3 6667 4539 4782 +3 4650 6848 3553 +3 2829 7494 800 +3 845 1849 6883 +3 5099 4711 5716 +3 3593 7110 4239 +3 3847 6000 5155 +3 2866 5327 5401 +3 774 848 3797 +3 3971 6458 6858 +3 4073 5104 1483 +3 1483 5104 2498 +3 2351 828 6677 +3 573 1055 1042 +3 2054 3341 811 +3 3709 6517 1526 +3 5207 4122 597 +3 2829 3624 7494 +3 2828 3801 588 +3 4756 4760 3761 +3 4148 2150 164 +3 2156 6405 5108 +3 1142 3723 2155 +3 423 5108 4922 +3 1751 2003 4340 +3 2012 2665 1159 +3 4348 542 5244 +3 6624 5109 4459 +3 1532 4459 5109 +3 6690 5198 1653 +3 850 3574 3562 +3 4458 5112 2096 +3 5114 209 2096 +3 2499 3090 853 +3 5542 1366 1312 +3 5117 3075 6544 +3 3069 5118 2610 +3 2610 5118 5182 +3 6060 5119 2348 +3 256 5537 6899 +3 2348 5119 857 +3 49 2190 3472 +3 1960 2755 6341 +3 2947 4626 5721 +3 273 5311 6476 +3 857 2755 5123 +3 2672 859 32 +3 5126 6459 4923 +3 2109 858 1324 +3 4144 4145 4398 +3 465 5412 115 +3 2079 3547 2971 +3 7459 3687 740 +3 861 3022 831 +3 2768 6520 7286 +3 2887 3202 5781 +3 5414 3073 865 +3 865 1068 5414 +3 4618 5133 2500 +3 130 5137 3590 +3 3395 4516 3843 +3 1872 5139 5689 +3 5689 5139 1958 +3 3498 3495 4859 +3 2704 3078 202 +3 7262 4363 5582 +3 5142 5578 5469 +3 4447 1056 3929 +3 7143 5547 7431 +3 2583 3620 6503 +3 7422 5144 118 +3 118 5144 7408 +3 2806 3544 3195 +3 7259 5150 500 +3 5982 4002 2013 +3 5151 4557 4852 +3 4557 5151 873 +3 4092 4559 5155 +3 6794 5434 7281 +3 873 3847 5155 +3 3532 5156 318 +3 548 5157 6088 +3 4991 6276 6861 +3 903 5162 4831 +3 4831 5162 6828 +3 3393 5477 718 +3 2728 5164 5167 +3 6837 5167 6070 +3 6070 5167 5163 +3 7058 2759 7431 +3 6681 2067 165 +3 3523 5169 880 +3 880 5169 1122 +3 2690 6354 6375 +3 875 4652 1807 +3 2465 3751 5976 +3 4652 5746 1398 +3 3538 3539 2162 +3 5513 6681 2434 +3 4738 1198 878 +3 4585 4586 2325 +3 6530 5174 6998 +3 6998 5174 5175 +3 7493 5175 2964 +3 2964 5175 5173 +3 3172 6632 7332 +3 5507 4649 1160 +3 6830 7112 6887 +3 916 5176 921 +3 6096 2252 5409 +3 7186 4253 5572 +3 133 5177 5179 +3 1106 2464 184 +3 1106 5742 2464 +3 5181 2610 5182 +3 5117 5118 3075 +3 1533 1929 468 +3 1264 2238 1580 +3 786 4344 1300 +3 5426 3659 2842 +3 786 5183 6140 +3 3173 5184 4859 +3 6688 6873 1201 +3 3572 4974 6943 +3 6688 5185 5337 +3 4845 5186 3196 +3 3196 5186 1593 +3 3384 6538 1686 +3 3592 5187 5541 +3 1938 1441 6988 +3 2787 4432 2512 +3 797 5145 5479 +3 5484 5154 5010 +3 530 2868 3391 +3 3459 3331 2016 +3 2667 453 6757 +3 1125 5190 1420 +3 5190 5565 1046 +3 749 2567 6836 +3 1132 1466 4841 +3 7301 7450 5087 +3 5390 5192 4299 +3 558 676 4222 +3 5649 1342 4814 +3 6587 1921 2352 +3 2208 5193 311 +3 5692 2919 1557 +3 311 5193 1298 +3 2863 7066 4093 +3 883 4842 5960 +3 5879 5194 1299 +3 2673 4853 3640 +3 2011 1717 5631 +3 5967 6297 5145 +3 4353 2501 2274 +3 3194 5197 5200 +3 6548 5200 450 +3 450 5200 4081 +3 5152 1485 3322 +3 2652 3322 1485 +3 5202 7173 4361 +3 5182 2270 5181 +3 5475 3717 2519 +3 6644 7400 3883 +3 275 4949 2377 +3 5015 4155 3793 +3 5015 5130 7377 +3 2760 5204 5436 +3 3771 5562 1111 +3 6224 5205 5503 +3 5836 5208 5272 +3 5272 5208 5603 +3 3683 2876 945 +3 1157 5209 5926 +3 5209 6436 1419 +3 5210 6656 891 +3 2369 7468 3962 +3 5015 4920 6257 +3 638 4286 90 +3 90 5594 638 +3 19 61 1889 +3 4448 6883 1849 +3 1356 5217 6918 +3 3932 5218 2302 +3 812 275 5552 +3 2302 5218 894 +3 6302 2066 5562 +3 4560 5784 6552 +3 2053 870 2059 +3 2869 2059 870 +3 5775 5223 2463 +3 894 2463 5223 +3 4968 4969 2355 +3 5265 5224 5025 +3 2260 679 2402 +3 5225 5763 6701 +3 5763 5225 7171 +3 5913 5226 4581 +3 6440 5227 2381 +3 5979 2027 5343 +3 354 6726 3530 +3 5647 181 2052 +3 2381 5227 5228 +3 3259 5228 5492 +3 2565 2889 3363 +3 2608 3529 817 +3 5098 4396 4580 +3 5492 5228 5226 +3 6556 1113 2646 +3 1398 3857 3527 +3 621 4738 878 +3 1529 3526 534 +3 2027 5979 1095 +3 5020 5230 1009 +3 1009 5230 7035 +3 77 5231 5892 +3 4460 4441 5125 +3 5892 5231 1140 +3 897 3189 2792 +3 4314 5232 7325 +3 5233 7325 897 +3 7043 2487 2412 +3 3613 4894 5570 +3 2412 2505 6758 +3 5573 5208 2259 +3 4867 1995 5234 +3 5048 5393 1575 +3 3523 880 3757 +3 4817 5234 5511 +3 5511 5234 6811 +3 899 257 73 +3 5624 6036 3521 +3 669 6736 2929 +3 5235 5236 7042 +3 469 2739 2734 +3 5214 5236 5235 +3 2578 2697 6897 +3 7379 7377 6264 +3 696 5553 2800 +3 4101 4102 2349 +3 6458 3601 2688 +3 368 5240 5241 +3 368 5241 906 +3 2215 3589 7056 +3 3589 5241 5239 +3 2590 6454 6361 +3 1124 5242 5069 +3 6438 908 787 +3 5784 2898 6552 +3 707 1716 907 +3 907 5245 3481 +3 6916 5245 2936 +3 2584 4995 6618 +3 7228 6359 3516 +3 2936 5245 2507 +3 2141 5424 7385 +3 2968 3870 6461 +3 6087 5038 7179 +3 1742 7382 2059 +3 145 5666 2058 +3 7443 5666 145 +3 4302 2508 3904 +3 5649 6427 1342 +3 513 2421 2885 +3 1477 3535 5613 +3 7142 7144 3956 +3 917 6799 6796 +3 3094 3789 919 +3 2862 5353 2509 +3 5274 1 2074 +3 5641 2088 937 +3 250 7459 3595 +3 3006 5252 2587 +3 163 7002 920 +3 920 1724 163 +3 5343 135 5016 +3 5524 6894 3722 +3 1249 922 5254 +3 1873 5255 1226 +3 1226 728 1873 +3 5290 2055 1319 +3 931 2440 4694 +3 5258 5092 935 +3 324 5637 420 +3 324 2513 5637 +3 5259 4633 3730 +3 5814 2363 5858 +3 5948 3604 3512 +3 2725 5260 974 +3 2260 2183 679 +3 2990 5261 977 +3 5262 2257 2861 +3 1164 5263 4512 +3 4512 5263 5446 +3 1534 3619 788 +3 4736 5264 5055 +3 5264 5355 698 +3 3140 444 5073 +3 5266 1166 937 +3 3493 5268 6414 +3 6414 5268 5902 +3 4669 4899 939 +3 4670 4104 5934 +3 5338 2477 939 +3 5098 5526 941 +3 941 2759 5098 +3 2759 3765 7431 +3 2771 2661 2569 +3 6356 5271 5904 +3 4132 3364 6905 +3 3170 5273 6648 +3 5987 4671 2074 +3 5518 5277 1267 +3 1267 5277 4885 +3 3774 5279 6404 +3 3661 6181 3386 +3 6517 4820 1904 +3 6499 452 3192 +3 452 6749 890 +3 6018 6016 6019 +3 6933 5698 2598 +3 6650 5282 574 +3 5282 946 3967 +3 6346 5283 3968 +3 3867 3968 5283 +3 6143 6219 1711 +3 946 4833 5284 +3 3599 5286 6990 +3 6990 5286 7039 +3 5762 4400 1744 +3 7039 5286 5287 +3 3063 5287 5286 +3 380 5474 1450 +3 2186 380 2808 +3 1136 5609 948 +3 948 6590 1507 +3 2055 5290 5537 +3 3800 5291 4786 +3 5902 5292 799 +3 799 5292 5293 +3 4392 5293 3313 +3 6704 4880 3988 +3 3313 5293 5291 +3 4676 4675 195 +3 6475 5296 2057 +3 2057 5296 5493 +3 2952 7484 5950 +3 2204 3720 7163 +3 4809 4233 2473 +3 2739 1427 2734 +3 5599 1208 736 +3 5271 5299 1021 +3 1021 5299 5300 +3 197 5700 4116 +3 5516 5300 5421 +3 5421 5300 5297 +3 5147 5301 7138 +3 748 4634 4914 +3 7323 7326 438 +3 628 5908 4851 +3 6019 6391 6018 +3 985 5301 1712 +3 6768 5302 1813 +3 2417 5303 483 +3 7251 3378 3506 +3 483 5303 5621 +3 539 951 4419 +3 951 979 4419 +3 4182 736 1208 +3 5306 6615 1265 +3 6181 6238 5820 +3 3570 2490 443 +3 5380 6615 953 +3 5889 5307 3160 +3 3160 5307 6838 +3 3805 5308 1176 +3 2150 3551 3504 +3 954 569 3834 +3 3531 5310 6983 +3 5863 6247 1174 +3 6983 5310 961 +3 957 3053 4496 +3 5313 5321 3075 +3 3196 5314 5315 +3 736 7148 2771 +3 2441 6152 2883 +3 2667 4996 164 +3 261 3248 4120 +3 486 5719 5756 +3 3188 5315 6435 +3 6435 5315 6996 +3 2295 2756 3500 +3 3553 2091 6978 +3 7328 5719 486 +3 3557 2146 1064 +3 6482 5727 5719 +3 3172 2828 588 +3 3498 5432 2860 +3 6697 6172 1518 +3 962 4590 2152 +3 962 7355 4590 +3 745 5323 1842 +3 201 5417 3493 +3 1842 2784 745 +3 1826 4449 565 +3 7504 5727 6482 +3 691 2104 6613 +3 3892 5326 965 +3 965 4964 3892 +3 2699 5328 2523 +3 4496 5856 5329 +3 6144 5330 5346 +3 5346 5330 6862 +3 3967 5331 574 +3 1726 5331 4411 +3 5181 2270 1345 +3 2977 5332 22 +3 5332 1223 2526 +3 966 4575 3416 +3 967 6001 1329 +3 1624 7269 6761 +3 5339 3490 234 +3 7390 4836 1912 +3 7456 5334 3687 +3 3687 5334 1780 +3 4751 6494 3399 +3 2570 4576 5863 +3 2657 6479 212 +3 1639 1715 2547 +3 5184 5185 4859 +3 3490 3491 2261 +3 4402 4908 3382 +3 1852 4087 2746 +3 5683 5339 5340 +3 4973 4975 6104 +3 5884 5146 6676 +3 7124 5340 5337 +3 7397 5342 2372 +3 2372 5342 3950 +3 5597 6115 2444 +3 968 4477 2961 +3 7151 1323 5317 +3 3915 3917 2341 +3 4138 5348 7291 +3 7291 5348 5345 +3 3260 3259 5492 +3 5350 4338 2407 +3 4338 5350 6486 +3 4243 5351 5004 +3 5004 5351 971 +3 473 2113 971 +3 5707 338 5336 +3 970 3484 4428 +3 3201 5354 5351 +3 5355 5266 698 +3 5266 1392 1166 +3 3440 5357 4552 +3 5707 5336 1638 +3 4552 5357 6316 +3 5358 7214 549 +3 5359 2641 932 +3 2641 5359 975 +3 5958 5360 3569 +3 3569 5360 2529 +3 974 5261 269 +3 5708 6129 3485 +3 977 5359 4775 +3 4865 5363 2593 +3 3997 5365 5366 +3 5805 5366 5363 +3 6157 5369 4011 +3 1758 4133 3482 +3 6944 5370 373 +3 373 5370 6022 +3 5984 3205 784 +3 2868 84 4849 +3 7009 707 907 +3 7148 4182 6758 +3 6558 1272 2056 +3 3612 5373 929 +3 5160 7002 6743 +3 1099 5374 3082 +3 2388 2399 7088 +3 7019 5374 3445 +3 7460 1901 6668 +3 3580 3579 7041 +3 6156 5382 3477 +3 1901 7461 1170 +3 5377 5378 5379 +3 6818 6743 3012 +3 2514 4082 5994 +3 978 5379 6823 +3 6823 5010 978 +3 979 5306 4419 +3 980 1868 700 +3 7319 4272 1312 +3 4064 5382 3355 +3 1180 7481 7479 +3 2309 6603 869 +3 1107 6535 3476 +3 1860 5387 6388 +3 5387 5384 837 +3 4238 5386 1796 +3 5192 3166 7204 +3 6086 4020 3139 +3 4617 5390 2535 +3 4825 5756 2511 +3 6181 3661 6238 +3 5765 5787 2047 +3 984 4299 4660 +3 6333 5358 2253 +3 6846 4630 2285 +3 3342 5391 6644 +3 6644 5391 1975 +3 6799 1974 1365 +3 1019 6019 4326 +3 986 2462 5238 +3 4967 5398 6300 +3 4841 1466 1285 +3 5398 5399 2475 +3 1831 914 4281 +3 5073 444 5906 +3 987 5001 3178 +3 6389 4083 1799 +3 2153 378 158 +3 5399 5395 776 +3 3707 2581 989 +3 989 1558 3707 +3 2071 56 5327 +3 2253 2021 3475 +3 3614 5402 5545 +3 5545 5402 6682 +3 5721 6268 7010 +3 1444 4453 2248 +3 4499 4500 7239 +3 1736 5404 7264 +3 3957 2954 4701 +3 4596 5406 2103 +3 3278 5407 5708 +3 5708 5407 6137 +3 896 4035 3218 +3 6394 3162 3682 +3 3368 5410 384 +3 384 372 3368 +3 3798 3799 671 +3 5413 4926 835 +3 5722 3468 861 +3 4926 5413 5539 +3 3960 5415 6721 +3 6638 5416 201 +3 201 5416 5417 +3 5268 5417 4786 +3 4786 5417 5415 +3 3850 6344 4580 +3 4580 6344 5526 +3 6813 5752 1828 +3 2459 1007 245 +3 4682 5420 4795 +3 7171 5422 2539 +3 7171 2539 2518 +3 2911 5423 7229 +3 3647 5423 7200 +3 4921 2210 5027 +3 911 5765 2071 +3 4658 4659 3447 +3 5974 3466 2433 +3 2150 4148 3551 +3 1533 6850 856 +3 5314 3125 4501 +3 911 5785 5765 +3 4524 3756 3461 +3 5808 5713 1775 +3 162 3983 3607 +3 2724 6858 2688 +3 1528 4703 1184 +3 4619 5428 5467 +3 5371 2492 5044 +3 6567 5429 792 +3 995 4251 6602 +3 4251 995 635 +3 4140 5999 2895 +3 2358 4621 3457 +3 4716 3430 3425 +3 221 4714 2243 +3 5706 5785 911 +3 6289 3456 3454 +3 6096 5409 2845 +3 2795 2484 2069 +3 4422 5124 525 +3 5759 5772 998 +3 5198 5435 6262 +3 1000 5949 1362 +3 5204 5437 5436 +3 7186 5436 5437 +3 5437 5204 1592 +3 4499 5438 660 +3 2967 5439 1448 +3 3449 3142 6044 +3 1448 5439 5581 +3 6499 4837 5078 +3 1003 1795 6695 +3 777 5444 3919 +3 5657 4582 1077 +3 3919 5444 5445 +3 3828 5445 2472 +3 2718 3409 6345 +3 2472 5445 5441 +3 2257 5262 5446 +3 4545 639 3334 +3 4512 5446 1008 +3 1006 6843 1279 +3 6843 1006 5447 +3 4584 3626 7058 +3 2044 168 5085 +3 1005 5734 768 +3 950 5451 4135 +3 5449 5376 4765 +3 3969 3970 536 +3 7322 5919 5452 +3 5453 5536 5054 +3 5453 5452 3969 +3 290 5570 5385 +3 4126 3989 5878 +3 1010 2217 4189 +3 4743 5456 5457 +3 318 4330 3532 +3 4309 4310 2780 +3 2471 5457 2469 +3 7224 2616 4651 +3 3732 1970 904 +3 1884 5159 4354 +3 7021 5458 622 +3 6740 218 3332 +3 4894 2492 5570 +3 218 6740 3649 +3 148 4617 309 +3 4033 5459 3067 +3 4422 4403 6042 +3 3764 4928 4422 +3 717 5460 1559 +3 2172 6146 3890 +3 615 2623 672 +3 2895 3503 1089 +3 4141 2540 6771 +3 1035 5465 2543 +3 1745 2697 2578 +3 5187 5468 2873 +3 2873 5468 6950 +3 4883 2089 4648 +3 1904 4820 4211 +3 4648 2089 1015 +3 2368 930 5950 +3 2615 5481 1015 +3 4690 5470 1015 +3 2193 5473 2252 +3 1450 2788 2842 +3 5919 5475 2519 +3 7032 4346 1423 +3 2567 5476 6836 +3 6836 5476 160 +3 6704 4656 3114 +3 4520 2737 4279 +3 3211 3376 1301 +3 6619 5638 3438 +3 4009 2862 3240 +3 2240 884 6078 +3 5498 4646 409 +3 5163 999 6070 +3 1018 2522 1612 +3 1018 5717 2522 +3 5236 5478 7042 +3 3752 6014 3435 +3 5479 6197 797 +3 3870 1727 1730 +3 5022 5025 5481 +3 1222 5482 6363 +3 3846 223 5482 +3 3473 5482 1019 +3 4583 5484 5010 +3 5725 4560 5305 +3 1020 6200 7313 +3 5922 4853 4498 +3 6914 6884 4127 +3 6145 5346 5487 +3 2043 5859 5652 +3 610 5488 1022 +3 4885 5489 3933 +3 2545 3910 613 +3 2547 1715 1023 +3 6297 983 6607 +3 1023 5488 2547 +3 4854 2238 1264 +3 3425 996 4716 +3 5493 6581 3013 +3 5130 3793 3429 +3 5295 5296 7376 +3 5857 3911 4292 +3 3392 5495 4146 +3 1133 5496 5497 +3 1133 5497 6082 +3 5306 6082 5497 +3 4419 5497 1435 +3 2041 4736 4982 +3 5531 2547 5488 +3 6589 5501 2634 +3 3510 5646 5699 +3 5249 6903 3245 +3 2634 5501 6854 +3 3783 4928 3764 +3 1900 5502 5968 +3 5646 7037 6716 +3 218 5459 3428 +3 4153 5506 981 +3 5146 5884 3814 +3 6809 7458 48 +3 3816 5510 6076 +3 3686 6540 7119 +3 2606 5353 3325 +3 6076 5510 6780 +3 1027 2620 2585 +3 4278 5512 5514 +3 5514 3385 4278 +3 4163 4076 7514 +3 1214 5514 714 +3 2530 2141 1576 +3 6320 134 5201 +3 714 5514 2548 +3 4768 6172 3234 +3 5505 2599 1661 +3 2916 6949 4163 +3 5219 2636 627 +3 5300 3881 1021 +3 6138 3949 3423 +3 3413 5517 354 +3 354 5517 6495 +3 2647 137 5688 +3 5737 5519 5989 +3 2862 4009 7256 +3 5989 5519 1030 +3 1339 930 2887 +3 6021 3565 3418 +3 4103 2476 2698 +3 3467 5520 2550 +3 1213 5519 4429 +3 866 3434 6049 +3 2537 7270 172 +3 4761 5523 3451 +3 5149 2705 366 +3 3451 5523 6220 +3 2237 714 3413 +3 547 6064 2065 +3 6890 991 4267 +3 5159 4232 769 +3 1032 2312 2472 +3 3942 5530 2333 +3 2333 5530 291 +3 3820 5534 802 +3 5819 696 3176 +3 802 5534 6966 +3 2055 5537 5538 +3 6297 5967 983 +3 6493 5539 3847 +3 2388 2244 4579 +3 7088 2244 2388 +3 5371 3400 2492 +3 3847 5539 6000 +3 4419 1435 539 +3 2516 3897 171 +3 3050 5859 2042 +3 5425 2004 3831 +3 1758 5543 6366 +3 1896 3979 1036 +3 2362 806 4315 +3 5544 2913 93 +3 93 5548 5544 +3 2330 2239 481 +3 5623 5548 2556 +3 1038 2987 4668 +3 2987 5425 4668 +3 4172 5550 5216 +3 4472 4054 4850 +3 871 5551 5554 +3 2312 5554 2472 +3 2472 5554 5550 +3 2948 88 3640 +3 6714 5556 3117 +3 3117 5556 6061 +3 7275 7279 7130 +3 5588 2679 1041 +3 5171 3150 4029 +3 1555 5560 1043 +3 1276 3133 1555 +3 2223 6100 4261 +3 1095 5362 5696 +3 257 2027 5696 +3 2975 4022 229 +3 2234 3171 1347 +3 5189 5190 4036 +3 4958 7449 7451 +3 4566 541 5881 +3 1029 5431 2007 +3 1048 1049 372 +3 5996 4840 6409 +3 4337 5567 822 +3 5569 822 1049 +3 2709 6016 6018 +3 2530 2525 886 +3 2868 530 6511 +3 2562 6511 530 +3 5572 4470 3009 +3 5455 5613 2680 +3 1050 2250 5747 +3 5655 5575 3701 +3 3692 5577 739 +3 739 5577 6779 +3 5141 5142 2101 +3 2311 5480 674 +3 5859 3050 1796 +3 6211 4027 5558 +3 7193 5579 4750 +3 3975 5580 2802 +3 2802 5580 5581 +3 5352 3322 545 +3 7086 3573 812 +3 5438 5439 660 +3 1448 5581 5579 +3 5141 5582 3854 +3 3854 5582 7365 +3 7275 7130 7324 +3 3407 3408 516 +3 7112 7115 6587 +3 3576 3513 2568 +3 3522 225 2488 +3 5267 5557 1041 +3 5650 2211 5595 +3 3913 4651 2831 +3 4049 725 3404 +3 2825 6273 3211 +3 3991 6834 2741 +3 6152 6165 2883 +3 2500 2274 4618 +3 638 5594 1542 +3 5650 5595 1057 +3 1059 3924 450 +3 2521 3965 5596 +3 4673 5598 5059 +3 1057 5059 5598 +3 7115 5600 943 +3 943 5600 6588 +3 1843 1063 3779 +3 2018 5601 5573 +3 2039 1143 2132 +3 5272 5603 2572 +3 5205 2572 140 +3 3882 3169 1401 +3 1364 5605 6730 +3 5157 548 4519 +3 1637 5606 4335 +3 4765 5606 5336 +3 2592 5607 3129 +3 4481 5608 5832 +3 1136 5608 1065 +3 1066 3896 5777 +3 1808 7054 2040 +3 7008 2038 5356 +3 1066 7125 3896 +3 4658 5611 5949 +3 5949 5611 1362 +3 7254 5612 226 +3 3403 3193 6421 +3 352 6992 3402 +3 4212 5966 7008 +3 226 5612 6987 +3 3397 2723 1480 +3 633 7480 7481 +3 6698 5975 5614 +3 7457 4082 1574 +3 1068 5594 5414 +3 2650 6994 3366 +3 3872 5616 4137 +3 5616 5618 1997 +3 3394 422 3318 +3 5618 4260 2163 +3 4260 5618 3108 +3 1713 2564 1486 +3 4192 5642 5639 +3 4360 5054 1033 +3 5243 5201 4918 +3 681 5620 1479 +3 195 4675 1313 +3 5302 5303 1813 +3 483 5621 6564 +3 5047 3785 526 +3 415 6011 6053 +3 507 5626 337 +3 3689 5626 4527 +3 3831 3833 4524 +3 4527 5626 1508 +3 6697 5821 296 +3 2164 3393 4984 +3 4146 5378 3392 +3 4495 4216 6326 +3 4216 4495 4211 +3 5695 7215 3181 +3 5629 5627 3427 +3 7227 5628 4754 +3 2485 5628 2534 +3 2233 5653 1787 +3 1959 3391 5086 +3 792 2532 1330 +3 5627 5629 4755 +3 4755 5629 6118 +3 1766 6118 5629 +3 3515 3832 1430 +3 3134 4037 4494 +3 4523 4526 5584 +3 3009 4470 2002 +3 1071 4618 2274 +3 1514 2864 1071 +3 4511 5871 4670 +3 4409 5635 7358 +3 7443 6011 415 +3 3897 350 3387 +3 7358 5635 5634 +3 6818 4697 6649 +3 4415 4416 5492 +3 2985 5636 6852 +3 3438 3440 4552 +3 4758 5639 1073 +3 2688 3559 2465 +3 4190 2198 1199 +3 185 6387 3073 +3 4695 5640 5641 +3 6184 5319 2088 +3 6184 1064 5319 +3 1880 652 615 +3 2002 1489 3009 +3 2681 2029 4532 +3 319 6274 1976 +3 4488 1788 4489 +3 4488 1076 5730 +3 373 6022 6011 +3 5877 2940 1075 +3 4600 5645 4777 +3 1076 5643 5730 +3 5369 5370 4011 +3 614 6716 3931 +3 1572 5649 4814 +3 3947 5654 4568 +3 4568 5654 5656 +3 6031 5656 7057 +3 7057 5656 5654 +3 2877 1080 68 +3 7218 6053 258 +3 4723 3525 133 +3 7103 3733 2136 +3 1943 5927 1011 +3 7233 5660 3359 +3 5660 1494 5062 +3 2900 5661 7367 +3 2737 4520 1078 +3 6682 5664 4068 +3 5711 5665 3518 +3 7508 2573 1891 +3 3518 5665 5667 +3 6966 5667 1498 +3 1498 5667 5664 +3 6056 6109 2158 +3 5699 5669 3510 +3 2002 3211 1301 +3 5670 1937 1886 +3 6484 6485 7201 +3 3450 5388 2703 +3 6426 886 2525 +3 5835 2547 5531 +3 2597 1427 3902 +3 1543 1674 7049 +3 1085 6008 1759 +3 2331 4023 7508 +3 6050 3690 4324 +3 5168 5673 5491 +3 5491 5673 7278 +3 2543 1717 885 +3 1141 3369 3167 +3 5676 72 5717 +3 6749 5677 890 +3 6712 5677 1294 +3 1062 3966 5650 +3 915 6296 2191 +3 5392 3033 4594 +3 3252 5682 2364 +3 7039 2828 3172 +3 2364 5682 5685 +3 372 5567 3368 +3 1876 2293 7004 +3 2821 7010 697 +3 2945 5685 2859 +3 2859 5685 5681 +3 2005 3963 1096 +3 1096 1237 2005 +3 2240 5691 884 +3 6037 884 1098 +3 1519 4209 6717 +3 3445 1099 429 +3 1095 5696 2027 +3 2308 378 2646 +3 6685 812 3573 +3 257 5696 7345 +3 6717 5162 7248 +3 6612 4210 5697 +3 2986 5699 3914 +3 6716 5699 5646 +3 2528 5275 5320 +3 5977 5833 3367 +3 4175 7001 2115 +3 5571 7225 4764 +3 5702 2582 4362 +3 50 5834 7091 +3 4765 5376 1101 +3 385 6105 6056 +3 5089 667 3517 +3 6622 6105 385 +3 1810 603 629 +3 5542 3474 3647 +3 2137 2316 495 +3 6641 2137 495 +3 6503 1534 2583 +3 5412 789 7022 +3 5665 3411 4068 +3 6109 4657 398 +3 1131 5712 5585 +3 2274 5714 4353 +3 4711 5714 5716 +3 4447 7129 1056 +3 2445 3365 5535 +3 833 5662 4333 +3 3372 1083 1496 +3 6017 6258 5823 +3 3524 5716 5713 +3 6636 603 4220 +3 2230 3031 1476 +3 3540 6336 3651 +3 4306 1018 6874 +3 1109 5862 2097 +3 5862 5718 6327 +3 5509 6487 2495 +3 254 7383 3361 +3 6781 6736 5952 +3 6421 3193 4117 +3 3751 6400 2314 +3 2801 1469 2536 +3 5177 5720 5829 +3 3063 4976 494 +3 3801 5723 5725 +3 4560 5725 831 +3 831 5725 5722 +3 489 3018 2623 +3 3404 5728 4049 +3 4049 5728 5729 +3 4869 4865 2593 +3 1445 5729 5726 +3 6086 3139 5835 +3 5924 2993 393 +3 1858 2107 7166 +3 6382 5731 2341 +3 2630 3254 5744 +3 6573 5731 2338 +3 3813 6147 6246 +3 2925 7319 6959 +3 2213 5796 4053 +3 6147 3813 2491 +3 6772 5733 6565 +3 3745 5735 5911 +3 5911 5735 6295 +3 3908 3907 2654 +3 4429 5737 658 +3 3573 7086 2668 +3 2909 4921 872 +3 658 5737 6448 +3 1459 5738 6885 +3 6885 5738 1867 +3 5366 827 3997 +3 5326 3358 957 +3 4614 5739 1116 +3 2263 5418 224 +3 5740 2620 1114 +3 2620 5740 2585 +3 1117 5739 5805 +3 5179 4723 133 +3 2350 10 6158 +3 2195 5745 2370 +3 5745 5746 874 +3 5746 5743 344 +3 3811 5747 2086 +3 2086 5747 5749 +3 3497 3511 3353 +3 6007 5748 2586 +3 2586 409 4680 +3 5750 3409 5188 +3 7258 5751 2937 +3 2937 5751 7474 +3 6255 5753 1643 +3 7143 6235 1718 +3 1643 2674 6255 +3 6978 4895 3014 +3 3014 3013 6581 +3 3858 3720 2204 +3 7095 4569 2776 +3 1104 3256 6096 +3 1104 3096 1463 +3 3350 3351 3301 +3 1816 3803 949 +3 5758 5759 2541 +3 1126 998 1146 +3 5772 5759 5755 +3 1127 3381 4196 +3 3740 2758 6361 +3 1128 6395 7102 +3 1705 6447 7098 +3 6447 1705 1397 +3 6159 6158 1616 +3 4536 1746 5766 +3 338 5707 6460 +3 2282 2399 2388 +3 5161 4111 3347 +3 7234 5768 5961 +3 5769 5961 1129 +3 6304 5769 3161 +3 3161 5769 2588 +3 2589 6241 1766 +3 2224 1131 7314 +3 4228 5047 526 +3 3180 1151 5810 +3 1131 7181 7314 +3 5770 3030 5085 +3 5871 6537 1174 +3 1135 4146 5495 +3 1135 1596 4146 +3 5580 5773 4750 +3 6952 5774 2463 +3 2463 5774 5775 +3 940 2955 6134 +3 2308 6134 158 +3 3610 5775 6968 +3 6968 5775 5773 +3 5776 2949 1501 +3 2949 5776 6122 +3 2388 5563 2282 +3 1573 5777 3896 +3 1718 542 6132 +3 4964 4930 2161 +3 392 5779 6110 +3 6110 5779 5780 +3 4537 5780 6419 +3 6419 5780 5778 +3 3217 114 1139 +3 6777 5783 188 +3 188 5783 6120 +3 3538 2957 4527 +3 4822 5786 1144 +3 1884 5312 3116 +3 6666 7480 633 +3 1145 5786 2162 +3 3338 4445 402 +3 7088 2399 6230 +3 479 3959 3335 +3 3671 5789 5790 +3 3448 5790 147 +3 147 5466 3448 +3 4947 3020 477 +3 1147 5793 1554 +3 2320 1125 1420 +3 6903 5206 3637 +3 2409 5794 1761 +3 6568 5795 6063 +3 6063 5795 6543 +3 1567 1731 6600 +3 1567 5796 5732 +3 7066 2863 1527 +3 7037 5646 6006 +3 1567 2584 6977 +3 6745 5798 3439 +3 6397 5799 3766 +3 3766 5799 6839 +3 4257 4258 241 +3 4173 5802 3608 +3 3608 5802 5806 +3 3710 5806 772 +3 772 5806 5801 +3 513 4051 4072 +3 218 3426 3332 +3 425 484 627 +3 5807 6973 2817 +3 6020 5808 1775 +3 5632 5808 5000 +3 791 6196 2439 +3 6559 1485 4591 +3 4591 3141 6559 +3 5383 4401 2638 +3 5231 77 705 +3 1658 622 1662 +3 6399 2122 1851 +3 5810 1261 3749 +3 1261 5810 1150 +3 2601 7085 1881 +3 2601 2185 7085 +3 5810 511 3180 +3 4010 4009 7066 +3 5099 5816 4711 +3 4151 5816 4321 +3 5311 3549 3555 +3 2910 3327 805 +3 1575 3116 5048 +3 1078 6117 4764 +3 4642 4643 2989 +3 6665 5822 1308 +3 7160 5823 143 +3 3301 6639 3324 +3 143 5823 7081 +3 7250 6246 144 +3 1661 5824 5505 +3 5505 5824 2014 +3 1462 1153 7228 +3 4528 5826 5688 +3 5316 4857 7520 +3 1152 5827 6083 +3 5607 5827 3129 +3 3129 5827 5825 +3 72 6277 6327 +3 6907 5828 4484 +3 6844 4383 2290 +3 6676 6181 5884 +3 3822 5830 5977 +3 5977 5830 5833 +3 3367 3366 5583 +3 2650 5833 5830 +3 2106 6801 1645 +3 31 7449 4958 +3 1275 4953 1585 +3 5706 911 1923 +3 1504 5838 4434 +3 3137 1506 3814 +3 2245 6843 2459 +3 6741 5839 5841 +3 5254 5841 728 +3 728 5841 5838 +3 5655 4038 3323 +3 2284 5842 2665 +3 2665 5842 1159 +3 6935 7434 55 +3 5843 6656 888 +3 6656 5843 4367 +3 1156 4363 1163 +3 1163 5842 1156 +3 2610 5873 3069 +3 5198 6690 2363 +3 919 5846 3668 +3 2257 5263 1495 +3 5428 5850 5467 +3 2539 5848 2518 +3 3036 5852 665 +3 665 5852 2608 +3 2791 2609 6230 +3 7525 4201 7066 +3 5187 5854 5541 +3 5541 5854 6804 +3 5126 5855 32 +3 69 6319 5881 +3 3071 1391 4996 +3 4656 1511 1357 +3 69 2269 7123 +3 5860 2179 1819 +3 2179 5860 6119 +3 1881 1167 2601 +3 5927 756 1011 +3 2343 5864 1537 +3 4050 1119 7521 +3 1750 1583 1205 +3 2252 6096 2193 +3 2782 2842 1225 +3 6140 5867 7051 +3 7051 5867 5864 +3 6156 3162 6273 +3 3871 5868 4565 +3 4565 5868 1529 +3 3641 5870 3112 +3 3112 5870 1531 +3 3720 3858 2310 +3 3069 4496 3053 +3 1277 5312 1884 +3 3629 5875 3615 +3 5242 2224 7314 +3 2643 222 1202 +3 5880 3569 936 +3 3569 5880 1203 +3 156 6861 120 +3 3924 6548 450 +3 2871 5883 6661 +3 6661 5883 5887 +3 6119 5886 2949 +3 2949 5886 1501 +3 276 422 3561 +3 1171 559 1503 +3 612 2607 3079 +3 1239 6924 6040 +3 7163 3720 783 +3 1171 5883 1955 +3 55 6653 7014 +3 1363 5040 557 +3 5307 4987 1176 +3 4462 4464 4855 +3 5483 5890 5891 +3 2050 1543 1759 +3 5798 5891 3160 +3 3160 5891 5889 +3 2958 5896 3215 +3 4545 3334 4939 +3 5735 5897 6565 +3 3640 1777 4881 +3 6565 5897 5898 +3 6131 5898 371 +3 1162 3572 4123 +3 371 5898 5896 +3 3506 6502 1464 +3 2506 6310 6277 +3 3370 5899 3767 +3 4226 2612 6044 +3 513 4072 3696 +3 6921 5900 616 +3 612 3079 2249 +3 616 5900 7241 +3 5941 5901 799 +3 5219 2258 2338 +3 5292 5268 4786 +3 6414 5902 5905 +3 5742 5905 2464 +3 2464 5905 5901 +3 6315 4940 3312 +3 5214 5907 107 +3 5979 2563 5061 +3 3684 4744 3311 +3 6963 5908 6894 +3 3436 5909 6894 +3 5529 3650 3308 +3 2927 5912 4581 +3 4415 5913 3627 +3 2492 3400 5570 +3 3627 5913 5914 +3 1869 7410 1423 +3 5357 5914 7214 +3 7315 6310 2506 +3 7214 5914 5912 +3 1175 4712 4033 +3 7346 6653 55 +3 2618 5916 6444 +3 7053 5012 5917 +3 3867 5920 4898 +3 2617 4898 1227 +3 6306 5305 6365 +3 4231 4760 6677 +3 2008 2256 1595 +3 5921 5734 5262 +3 4124 4562 436 +3 5734 5921 1185 +3 318 134 6320 +3 4703 4482 1184 +3 1184 5925 1528 +3 2405 3306 6580 +3 2735 5925 208 +3 1182 208 5925 +3 6982 5761 2879 +3 4577 1730 6526 +3 2365 5671 1 +3 3237 5929 1434 +3 1186 4386 631 +3 4934 4013 7344 +3 5150 7479 2197 +3 1613 1187 5930 +3 4978 5932 5865 +3 4023 2310 6630 +3 5865 5932 2624 +3 4680 4626 6007 +3 1188 6065 1161 +3 2475 5933 6300 +3 6300 1191 2625 +3 5877 5645 3300 +3 3885 338 6460 +3 2333 1037 136 +3 3706 5935 2625 +3 2429 5939 5910 +3 1426 1010 6039 +3 2745 3298 5844 +3 5910 5939 1248 +3 2519 3717 3295 +3 5901 3520 2464 +3 156 5338 939 +3 568 6700 1506 +3 3320 5944 5945 +3 5293 5945 463 +3 463 799 5293 +3 6928 4210 6612 +3 5946 6228 3200 +3 6228 5946 5947 +3 2204 7163 3746 +3 3464 6068 2780 +3 4463 1681 1197 +3 1197 5951 432 +3 5951 4811 878 +3 5947 4811 5951 +3 5799 5953 3439 +3 3439 5953 6412 +3 5986 5954 4950 +3 2728 6160 5956 +3 1202 5880 3778 +3 6048 6577 314 +3 216 3291 600 +3 5959 6048 1203 +3 5064 5959 1124 +3 3286 3287 126 +3 1124 5959 2627 +3 3662 5338 156 +3 488 1093 5962 +3 5963 4811 5947 +3 1204 5964 5172 +3 5964 1169 621 +3 1169 5964 2628 +3 5287 3063 494 +3 5033 5965 249 +3 5287 2828 7039 +3 2220 3680 3279 +3 249 5965 1274 +3 1211 2143 5560 +3 5717 5718 2522 +3 5821 6697 947 +3 5506 5502 981 +3 732 3277 2044 +3 856 6850 7198 +3 6406 2894 2038 +3 4141 4321 2540 +3 3245 5752 2756 +3 362 3276 4431 +3 6903 3637 4468 +3 2345 2800 5553 +3 2550 5969 7132 +3 7132 3467 2550 +3 1436 4421 2953 +3 1574 6275 3636 +3 6673 6820 3274 +3 3607 2908 162 +3 231 7478 2875 +3 5971 3385 1214 +3 4385 1288 2219 +3 3934 2733 765 +3 3385 5971 5973 +3 1215 6808 2750 +3 176 5973 5970 +3 3466 3465 3261 +3 3677 2668 1360 +3 4530 5974 5981 +3 4530 3424 1668 +3 5980 5981 328 +3 5981 6337 1216 +3 1500 6049 7516 +3 6337 5981 5974 +3 815 5983 2632 +3 3677 1360 793 +3 7143 5984 6235 +3 2386 5633 4566 +3 1079 334 1039 +3 4999 3696 3681 +3 5954 4767 4328 +3 5992 5986 7162 +3 1217 3808 5815 +3 1218 3510 6790 +3 325 6429 876 +3 4057 5990 1446 +3 2769 2903 947 +3 5783 5990 6363 +3 1222 6363 5990 +3 3335 5993 479 +3 3822 5995 3417 +3 3417 5995 6234 +3 3170 4369 4623 +3 3307 950 1143 +3 453 5999 6771 +3 2526 22 5332 +3 4089 6002 3155 +3 6003 470 3293 +3 1224 2374 4156 +3 5767 5744 4194 +3 6003 6001 1223 +3 6138 3423 3204 +3 4361 3268 927 +3 7074 6087 1158 +3 1881 7085 7473 +3 6338 152 2036 +3 1690 5818 3983 +3 2196 4503 3267 +3 1226 5254 728 +3 3209 7477 7472 +3 1228 4810 493 +3 5677 6749 1294 +3 1229 6010 6162 +3 6862 6010 794 +3 3021 3450 6757 +3 7118 7120 6672 +3 1655 3140 5598 +3 3182 6334 4164 +3 794 6010 97 +3 4768 6651 1518 +3 5317 3078 7151 +3 2026 6442 6339 +3 6362 6013 2082 +3 699 6837 6922 +3 3265 6879 3179 +3 2082 6013 6452 +3 5076 6014 3083 +3 4924 1394 217 +3 6020 1775 5128 +3 2010 447 3931 +3 7516 6049 3434 +3 98 2036 45 +3 1100 5000 5808 +3 1429 4403 4444 +3 3993 6884 4688 +3 1231 4286 638 +3 5016 6692 5757 +3 4331 4332 807 +3 1232 6025 6628 +3 6478 4770 4059 +3 5646 7436 6006 +3 2958 6025 5975 +3 5800 5809 4762 +3 5975 6025 5614 +3 350 6026 1280 +3 1362 6028 1000 +3 6028 6029 1000 +3 4908 6029 3382 +3 3382 6029 6026 +3 5820 6238 3886 +3 6475 2057 85 +3 6030 1100 6020 +3 6030 6387 1853 +3 749 6836 3620 +3 4318 292 3571 +3 5656 4055 6632 +3 3285 3522 5710 +3 674 2701 5938 +3 5624 6031 7210 +3 6762 3521 6036 +3 1677 6036 7210 +3 782 1255 1238 +3 1238 6037 2581 +3 1237 5691 478 +3 2603 3254 1946 +3 884 6037 2640 +3 1239 2223 4261 +3 3985 5198 2363 +3 7094 6236 6675 +3 1429 1385 4403 +3 7454 1945 596 +3 7454 6042 1387 +3 2955 940 2671 +3 6044 3142 4226 +3 2633 1277 4354 +3 5248 2984 5869 +3 4113 5655 3701 +3 3817 3693 3262 +3 6087 7074 5038 +3 6046 383 2903 +3 3092 5535 3713 +3 3644 6054 3862 +3 2335 2847 455 +3 6338 2894 876 +3 3254 2630 1924 +3 871 5554 1040 +3 1242 1439 6456 +3 3922 3721 7012 +3 2716 6058 6059 +3 6059 5191 2716 +3 3547 6059 2971 +3 2971 6059 6058 +3 4748 1243 2348 +3 3406 6060 5267 +3 5557 5556 5588 +3 6241 2589 1245 +3 1245 1351 6241 +3 4309 1247 4743 +3 2482 6071 2644 +3 1246 5939 7022 +3 1248 3464 5910 +3 1249 1250 3204 +3 1250 1304 6138 +3 3696 1610 513 +3 690 1844 5885 +3 4704 6074 1305 +3 6075 3981 282 +3 5866 6077 1537 +3 1537 6077 6078 +3 2640 6078 884 +3 6078 6075 2240 +3 4799 6079 2631 +3 1257 6615 590 +3 1257 1265 6615 +3 6082 3348 1133 +3 7058 5547 4584 +3 6083 3348 1260 +3 6083 5688 1152 +3 6372 3587 5821 +3 5688 6083 2647 +3 734 1394 1599 +3 7254 7253 6027 +3 6936 5349 3260 +3 4920 4159 4076 +3 5215 2075 6901 +3 5259 6085 4690 +3 4420 6807 6578 +3 7179 5176 6087 +3 6087 916 1158 +3 2201 1069 1989 +3 5821 6719 6372 +3 5197 6089 15 +3 1697 2216 3709 +3 15 6089 6204 +3 4720 3740 6361 +3 1266 264 5151 +3 4090 6092 17 +3 1270 2446 1329 +3 4889 6095 1381 +3 1381 6095 6141 +3 4349 6097 6941 +3 538 3691 4875 +3 7244 6360 2892 +3 1272 5373 2056 +3 1274 1211 1552 +3 6099 6100 1043 +3 5499 1599 1394 +3 1276 2561 3133 +3 4261 6100 6098 +3 6667 4782 6101 +3 580 6101 2084 +3 2213 4053 1374 +3 2245 1279 6843 +3 1279 5121 1006 +3 4819 6106 5561 +3 3514 6111 3252 +3 4125 4126 5878 +3 2471 6107 6108 +3 4310 3542 2780 +3 3415 6108 6106 +3 3514 3235 1283 +3 5682 6111 5392 +3 1283 6112 2171 +3 1282 6754 4393 +3 6339 6442 45 +3 6702 6506 924 +3 4491 6981 2114 +3 1699 5693 1366 +3 1585 6116 6902 +3 6400 4844 7461 +3 4803 6118 1766 +3 5650 3966 2211 +3 4067 6579 2493 +3 7091 2034 6506 +3 3243 3884 3251 +3 6661 5887 5886 +3 5782 5783 6363 +3 188 6120 6122 +3 5777 5776 1066 +3 3250 4780 207 +3 4632 4555 3388 +3 3249 6999 4535 +3 2949 6122 6119 +3 6123 5703 2293 +3 5703 6123 6124 +3 6124 6123 6946 +3 6125 6687 901 +3 1907 4303 4709 +3 4208 3536 6959 +3 2391 3246 4746 +3 1317 6126 6128 +3 3953 3952 847 +3 2743 1533 5478 +3 2631 6128 4799 +3 6487 4304 1734 +3 4902 6129 3488 +3 3488 6129 7491 +3 6775 6131 556 +3 2217 3244 4189 +3 5087 7149 3334 +3 1514 6133 2864 +3 2864 6133 6135 +3 985 1712 5201 +3 6696 6135 371 +3 371 6135 6131 +3 1796 1343 5859 +3 2103 5406 1422 +3 825 6139 6129 +3 7491 6139 5031 +3 5031 6139 2858 +3 1342 2794 1993 +3 6066 6504 1484 +3 4554 5075 3239 +3 1205 451 1750 +3 6097 6095 6941 +3 1381 6141 6142 +3 4873 1691 735 +3 7051 6142 6140 +3 6891 6144 2552 +3 6144 6183 1789 +3 5486 5487 1604 +3 5014 6146 1180 +3 4035 896 6899 +3 3675 793 4733 +3 1180 6146 7481 +3 4170 6845 3238 +3 4302 542 4348 +3 5039 1547 3904 +3 4707 6149 361 +3 4407 3725 6883 +3 3514 6598 3235 +3 1088 461 1368 +3 6279 6151 6194 +3 3776 3419 2972 +3 4515 6154 7199 +3 890 5265 3192 +3 7027 6155 4011 +3 4011 6155 6157 +3 6157 6841 2881 +3 6841 6157 6154 +3 123 6158 10 +3 6158 6210 2350 +3 5822 6159 1308 +3 699 6186 1286 +3 5167 1286 2728 +3 393 4989 5924 +3 1060 1561 356 +3 1483 6160 2651 +3 5038 7074 1966 +3 6161 928 1438 +3 3543 2705 2285 +3 3496 6163 6167 +3 3263 464 3042 +3 6054 6167 578 +3 4917 5695 2455 +3 578 6167 6161 +3 2219 1660 4385 +3 6379 6782 1289 +3 7198 2557 2779 +3 5877 3300 1380 +3 3808 1216 3098 +3 6172 6697 296 +3 6173 508 4264 +3 2062 6173 5542 +3 4436 4236 573 +3 152 6513 6339 +3 296 2420 6172 +3 451 994 6175 +3 3981 6077 466 +3 7198 6863 2557 +3 6176 6174 2387 +3 3810 3809 751 +3 7394 6177 6508 +3 7092 2481 3774 +3 60 4026 1137 +3 4547 2322 4534 +3 6178 1292 2655 +3 1292 6178 567 +3 3050 991 723 +3 6182 13 654 +3 13 6182 6183 +3 1964 1267 6812 +3 275 5662 833 +3 2490 3570 5684 +3 6145 6144 5346 +3 1789 2552 6144 +3 5243 6396 6957 +3 2496 2236 6844 +3 699 6922 7170 +3 4076 6257 4920 +3 699 6185 6186 +3 2651 4073 1483 +3 3994 6186 6185 +3 5940 3144 6284 +3 833 5552 275 +3 7071 6187 1017 +3 4198 4070 772 +3 5238 6188 6190 +3 4946 4631 5690 +3 1286 6837 699 +3 925 6190 6187 +3 620 4762 6660 +3 4569 7111 1708 +3 6193 6198 2658 +3 6149 6151 361 +3 6735 2411 1296 +3 6194 6193 6279 +3 5199 855 620 +3 6198 1297 2658 +3 1783 3157 2704 +3 7136 4154 3344 +3 6849 6201 2985 +3 3261 3465 555 +3 3260 6202 6936 +3 6936 6202 6203 +3 5711 6203 4259 +3 4259 6203 6201 +3 6090 6089 1954 +3 3582 2898 2653 +3 5426 2842 2782 +3 15 6204 7030 +3 3224 3225 955 +3 5019 4876 3232 +3 1298 5194 4843 +3 1299 1303 5879 +3 6207 5928 6377 +3 1302 6208 6413 +3 6070 6871 6837 +3 4183 4142 6413 +3 771 6542 2909 +3 4183 6208 2660 +3 1304 6074 2430 +3 1305 1875 4704 +3 1847 1306 2112 +3 2719 6555 6586 +3 1310 7414 2850 +3 5817 6212 2199 +3 311 6468 2208 +3 2912 6213 6585 +3 6585 6213 6216 +3 2031 7218 258 +3 6950 6216 532 +3 532 6216 6212 +3 1311 6819 1317 +3 5846 3029 963 +3 3680 2220 426 +3 7376 4426 1711 +3 3146 3333 3986 +3 2313 6218 421 +3 7198 2779 1894 +3 7198 1894 856 +3 421 6218 6217 +3 5672 6219 6143 +3 1711 6219 6217 +3 1391 3242 4974 +3 4210 4169 3754 +3 3451 6220 5525 +3 544 6221 2032 +3 1684 3376 5154 +3 6442 6221 45 +3 3221 24 2142 +3 45 6221 98 +3 2206 5042 1723 +3 6373 6478 363 +3 5511 6223 4817 +3 5503 4817 6223 +3 6224 2055 5538 +3 6606 6225 2666 +3 4501 3719 1617 +3 2666 4749 6606 +3 4317 3115 5668 +3 2394 6227 6229 +3 7231 6229 7517 +3 6229 6226 7517 +3 6232 3255 202 +3 4001 6232 5317 +3 1810 629 5781 +3 1322 7489 6322 +3 5443 6301 6863 +3 1322 834 7489 +3 7197 6233 316 +3 5993 5995 479 +3 6940 4922 2803 +3 3329 1765 4169 +3 3417 6234 6357 +3 896 694 3683 +3 6299 6237 4549 +3 5535 3092 1741 +3 4438 3275 227 +3 2753 6240 32 +3 2358 3364 3271 +3 32 6240 2672 +3 6552 6365 5305 +3 3025 1324 2669 +3 6645 4369 3170 +3 6529 6243 6948 +3 3995 6244 5134 +3 5134 6244 6245 +3 7164 6245 5992 +3 5992 6245 6243 +3 7088 6230 5943 +3 4375 6575 6586 +3 5099 3524 2436 +3 2621 2826 3594 +3 1327 3533 4498 +3 2673 3640 88 +3 301 6248 7117 +3 81 4514 1747 +3 3125 3038 6171 +3 7102 1400 6393 +3 1252 6582 2580 +3 3699 3698 1761 +3 4731 6249 6251 +3 631 3496 1186 +3 5731 6251 2341 +3 2341 6251 6248 +3 2995 944 3001 +3 2850 6253 2112 +3 1804 3670 3208 +3 4055 7332 6632 +3 4334 3861 2203 +3 2785 6575 4375 +3 1334 2674 5158 +3 6038 3628 3724 +3 7336 4411 4410 +3 670 5753 1333 +3 298 3972 2202 +3 1333 6256 4807 +3 5110 2098 4807 +3 1331 5110 6256 +3 5823 6258 2009 +3 2009 6258 6925 +3 2782 2492 5426 +3 3056 6259 3920 +3 4055 6621 7332 +3 4713 6260 3317 +3 3317 6260 6614 +3 1335 2510 1984 +3 1335 7453 2510 +3 1337 4553 7361 +3 5393 5352 545 +3 5164 6868 6969 +3 1337 1341 6263 +3 3974 62 5143 +3 4342 6263 5588 +3 5588 6263 2679 +3 1872 1340 6253 +3 265 7036 4674 +3 2477 5338 3815 +3 2678 2112 6253 +3 2937 7474 7477 +3 648 6270 4576 +3 5129 3614 1004 +3 5129 6271 7369 +3 6093 7127 5281 +3 3397 6272 5936 +3 6704 889 5135 +3 3211 2002 2825 +3 2576 4149 6490 +3 1345 6274 319 +3 6773 4508 3191 +3 1348 5260 2725 +3 1349 6280 2643 +3 1351 6066 6241 +3 1715 62 3974 +3 1347 3171 6280 +3 2170 1611 3490 +3 5440 4042 448 +3 3795 5206 6875 +3 6899 896 945 +3 3704 3241 4861 +3 2168 6283 448 +3 6285 3167 3369 +3 3167 6285 6281 +3 436 1449 2741 +3 3546 6286 4554 +3 5075 5076 3083 +3 5397 6288 6290 +3 6201 6290 4259 +3 4259 6290 6286 +3 4927 4929 905 +3 5835 6589 6086 +3 5077 6292 7489 +3 7489 6292 6322 +3 3204 922 1249 +3 7378 1452 4797 +3 5989 4105 1396 +3 2993 4143 6868 +3 5733 5735 6565 +3 3622 3623 25 +3 76 1743 2812 +3 4549 6298 6299 +3 4233 6299 2473 +3 4312 6607 1509 +3 2473 6299 6295 +3 7384 6302 7281 +3 626 5032 2164 +3 4188 1623 792 +3 3091 6303 5024 +3 5531 5501 6589 +3 3931 2696 614 +3 5024 6303 1353 +3 5769 6304 5961 +3 5961 6304 2266 +3 1354 7202 1991 +3 652 2265 3679 +3 7202 1354 6307 +3 6961 6308 6293 +3 6293 6308 2683 +3 5893 3422 1700 +3 4708 4532 2029 +3 1359 6308 7325 +3 1142 4059 4026 +3 7084 6988 1966 +3 4046 3531 6983 +3 5358 5357 7214 +3 4552 6316 6317 +3 3809 6317 751 +3 3304 2621 5250 +3 6729 1154 96 +3 2254 2576 6490 +3 6104 3823 3199 +3 6813 2865 972 +3 2955 2835 2689 +3 751 6317 6314 +3 3595 740 69 +3 5697 6319 6612 +3 6612 6319 6318 +3 3197 1301 1684 +3 6321 1908 1745 +3 318 5156 2742 +3 417 6292 4784 +3 5017 703 3114 +3 6901 7178 4485 +3 2632 6323 4311 +3 6323 6324 4311 +3 715 6324 2424 +3 414 2424 6324 +3 4793 1420 1046 +3 6032 4485 4545 +3 1280 6028 2147 +3 9 2935 237 +3 2832 6328 4590 +3 3313 5291 3190 +3 5298 4709 2661 +3 7104 7115 7112 +3 3750 4590 6328 +3 3314 5016 3378 +3 3378 5016 135 +3 1220 4597 1369 +3 1369 6331 1395 +3 3446 2618 1821 +3 1392 6331 1166 +3 6331 1370 630 +3 4300 6332 3182 +3 4164 6334 1818 +3 1818 3061 4164 +3 2966 2951 1358 +3 7388 401 724 +3 4461 3188 6435 +3 5070 2733 7368 +3 5070 7372 7370 +3 6943 4763 808 +3 6954 6617 9 +3 7368 2733 3934 +3 1512 4861 6962 +3 6396 94 231 +3 6674 6340 4053 +3 4053 6340 1374 +3 1078 4520 5067 +3 231 2875 6396 +3 116 1372 6342 +3 2667 6773 4996 +3 4296 6342 2965 +3 927 3184 4361 +3 1373 2946 5246 +3 1375 6340 6515 +3 5885 4372 1097 +3 6345 192 1740 +3 7471 7304 6348 +3 7466 6871 6070 +3 6257 7013 4155 +3 5750 6348 3409 +3 3409 6348 1822 +3 1913 1376 5034 +3 4538 4539 6667 +3 6352 2527 1376 +3 4131 4130 1067 +3 4551 6352 6349 +3 2098 6353 722 +3 7099 5687 722 +3 5299 6356 5461 +3 6237 6234 4549 +3 3417 6357 6563 +3 678 7228 2963 +3 4636 6359 2082 +3 2082 6359 6362 +3 3383 7219 2790 +3 3308 6362 6358 +3 6358 5529 3308 +3 987 3178 3977 +3 1695 5543 351 +3 4133 4134 1521 +3 4787 6367 6368 +3 1698 6368 5540 +3 5952 1617 6793 +3 6368 6366 5540 +3 5411 5410 4997 +3 1108 4248 365 +3 375 6371 4827 +3 4745 6371 6886 +3 6886 6371 6369 +3 4320 4505 2692 +3 1377 270 3548 +3 1378 6375 3697 +3 2028 2069 2484 +3 4449 4450 4350 +3 6377 6378 6207 +3 2998 672 2623 +3 6207 3588 5879 +3 1941 7171 2347 +3 1449 5499 1696 +3 18 7464 1523 +3 6782 6379 6170 +3 924 6657 6702 +3 2192 6380 3316 +3 1383 3316 6380 +3 2026 924 6442 +3 2808 5837 3728 +3 2693 5704 781 +3 1384 5907 644 +3 3451 5525 547 +3 4844 6400 3751 +3 3736 6665 6657 +3 1591 6435 6996 +3 5228 6384 2381 +3 6384 1389 2695 +3 3175 1691 2140 +3 1385 6042 4403 +3 1387 6386 598 +3 7261 7456 3813 +3 7 18 4461 +3 1388 6386 1389 +3 1389 4298 1388 +3 1853 1100 6030 +3 5406 6388 5387 +3 6388 1393 1860 +3 5652 5859 1343 +3 5652 6390 5264 +3 1395 1220 1369 +3 5092 5258 2113 +3 1220 1395 1393 +3 2654 3907 1400 +3 1397 2232 6447 +3 6393 2207 7102 +3 516 3408 1290 +3 2476 236 2698 +3 5953 6397 4950 +3 4950 6397 6733 +3 6764 6398 3766 +3 5280 1713 844 +3 1561 353 7524 +3 7219 7141 5589 +3 1616 6402 1308 +3 4502 6403 2156 +3 7333 6665 3736 +3 2156 6403 6713 +3 1403 3624 1472 +3 3216 510 1738 +3 4802 6410 3209 +3 5954 5953 4950 +3 5943 7473 7085 +3 6413 5928 1302 +3 5928 6413 1405 +3 2200 4509 1409 +3 1409 6416 299 +3 6416 1405 4156 +3 4156 2374 6416 +3 4352 5128 1775 +3 1413 4981 2626 +3 2796 3168 42 +3 4431 6417 362 +3 2899 2044 1415 +3 1415 6418 408 +3 5091 6008 1084 +3 1417 2064 6420 +3 6402 6702 1308 +3 748 6422 4634 +3 4634 6422 6424 +3 2118 6424 6421 +3 1342 6427 809 +3 1086 4712 6430 +3 3594 4672 212 +3 2025 6747 2022 +3 6432 6430 4712 +3 353 6164 2290 +3 1418 619 625 +3 7290 6433 1425 +3 2023 5479 5145 +3 6436 5210 233 +3 4007 4805 3910 +3 5210 5209 888 +3 1419 5926 5209 +3 4898 7341 3867 +3 2617 2443 6005 +3 2636 6730 627 +3 6915 2936 908 +3 6360 6724 2892 +3 2695 6439 2381 +3 241 4258 3163 +3 1469 6192 1332 +3 5227 3076 4581 +3 2661 4709 4303 +3 1407 6440 6441 +3 3946 6441 2061 +3 6441 6439 522 +3 6153 1433 6360 +3 2164 4984 626 +3 1432 6444 5915 +3 1911 7024 2783 +3 5916 6012 1175 +3 1827 1280 2147 +3 2591 3611 1647 +3 6156 3477 692 +3 6724 6360 1431 +3 6809 6810 10 +3 3473 639 3846 +3 6626 6747 2024 +3 4866 5785 1516 +3 5736 5737 5989 +3 1406 3062 6376 +3 6084 6842 3159 +3 3442 6449 2591 +3 6449 6450 3611 +3 3667 6450 2730 +3 2730 6450 6448 +3 6508 6451 3752 +3 4299 2670 3263 +3 2137 5754 2316 +3 2595 5695 3310 +3 2515 6997 3158 +3 3083 6014 1673 +3 7139 4092 3134 +3 2082 6452 6453 +3 4636 4637 205 +3 2048 6453 6451 +3 4796 535 216 +3 5442 1940 1838 +3 6054 2642 3862 +3 7251 1470 6093 +3 4823 4819 5561 +3 1439 6457 2559 +3 5922 6865 5762 +3 6457 578 6161 +3 731 4664 3153 +3 4169 1991 5515 +3 5800 1996 6831 +3 2526 3147 22 +3 6462 1442 3578 +3 5724 3754 2478 +3 1442 2226 5797 +3 1440 149 6462 +3 1447 3865 5504 +3 3814 1506 6700 +3 422 6465 2715 +3 923 6815 6833 +3 4843 6467 311 +3 5473 6287 2252 +3 6468 5086 342 +3 2314 1899 1805 +3 3055 1499 6789 +3 5086 6468 1959 +3 6471 822 5569 +3 6471 6467 1451 +3 5679 6547 2521 +3 2151 6815 923 +3 337 1344 507 +3 5679 5073 2926 +3 1454 3842 195 +3 3727 5985 294 +3 327 6475 4427 +3 5296 6475 4426 +3 4737 3537 1067 +3 6817 1534 6503 +3 6832 6815 2078 +3 7409 4124 3774 +3 6477 6480 187 +3 2319 6480 1193 +3 1193 6480 6476 +3 6868 6481 2993 +3 5661 6483 7367 +3 7367 6483 2073 +3 5994 3729 7353 +3 3407 6484 7201 +3 366 2705 3150 +3 6134 2955 2449 +3 6663 6485 300 +3 7301 4326 6016 +3 300 6485 6056 +3 5349 5350 4298 +3 4764 3921 1078 +3 5534 6488 3518 +3 2449 6127 6134 +3 3518 6488 6489 +3 6203 6489 6936 +3 6936 6489 6486 +3 332 4454 4191 +3 6492 3847 873 +3 3847 6492 6493 +3 5539 5413 5066 +3 1607 3543 2285 +3 6493 6491 1458 +3 2758 3740 214 +3 3399 6494 3668 +3 7136 3344 5504 +3 2668 3677 3573 +3 7086 5552 5341 +3 3309 3283 3083 +3 5191 6496 1461 +3 2810 5738 1460 +3 6498 4970 4971 +3 4971 4970 2287 +3 1461 4886 6498 +3 2303 71 7496 +3 6410 6500 3041 +3 1739 6501 144 +3 144 6501 7252 +3 1464 2772 1470 +3 4804 4364 168 +3 7185 2772 1465 +3 1982 2856 1779 +3 6605 1058 1465 +3 7427 6437 5215 +3 4029 3543 2720 +3 778 4008 1471 +3 6542 5803 4921 +3 4760 934 3761 +3 7402 1957 3893 +3 934 4760 4231 +3 6451 6177 2048 +3 3438 6509 6619 +3 5922 1744 5998 +3 6619 6509 6510 +3 3435 6510 3752 +3 3752 6510 6508 +3 2930 6512 3377 +3 6512 1765 3329 +3 7473 5943 4956 +3 6063 6840 6923 +3 1474 771 1943 +3 7366 3865 6465 +3 2306 3138 952 +3 184 2464 3520 +3 1375 6515 2721 +3 5803 6542 6600 +3 6600 1731 5803 +3 2721 124 1375 +3 1473 6514 1014 +3 1977 6840 6063 +3 667 5089 1981 +3 5066 2045 6000 +3 6000 2045 846 +3 6794 3452 5472 +3 4992 3330 3462 +3 3565 3566 6081 +3 2458 6522 6524 +3 4643 6524 2989 +3 6361 2758 2590 +3 6423 7473 3422 +3 2989 6524 6519 +3 1561 5158 353 +3 1155 6525 651 +3 5521 3217 2075 +3 4791 4790 3497 +3 2192 3316 5526 +3 642 6528 5325 +3 1936 6606 4749 +3 5325 5324 2104 +3 565 1969 1025 +3 5455 2571 2187 +3 4767 6529 4328 +3 4328 6529 7307 +3 1911 3983 5818 +3 5103 6530 6948 +3 3031 6531 1476 +3 6532 5536 1475 +3 5536 6532 6533 +3 4749 4678 1936 +3 1934 6282 864 +3 7037 6006 7518 +3 2458 3927 1281 +3 4271 5246 1679 +3 4058 6535 807 +3 807 6535 6536 +3 6550 1523 2619 +3 4447 3929 5619 +3 4194 5744 1315 +3 3695 6536 3034 +3 2021 6840 576 +3 3034 6536 6534 +3 1174 6537 6051 +3 1686 6538 7230 +3 160 6539 2485 +3 817 665 2608 +3 2191 6296 1737 +3 4761 6540 4212 +3 3475 6333 2253 +3 3634 7507 1618 +3 4149 6541 6490 +3 5794 5795 1761 +3 6063 6543 1977 +3 5321 6544 3075 +3 6544 6541 5117 +3 6545 6143 3507 +3 5200 6548 1294 +3 1294 6548 6712 +3 2727 6986 315 +3 1523 4461 18 +3 1423 7410 2389 +3 6235 6401 2181 +3 5117 6541 2270 +3 4457 6551 537 +3 2305 4863 2000 +3 2873 6950 7011 +3 6701 6554 5225 +3 2904 5244 2181 +3 5353 7404 3325 +3 3893 1957 2418 +3 5878 4094 3128 +3 1459 6885 6057 +3 5906 444 2978 +3 1957 7378 2418 +3 6086 2696 4020 +3 1478 3398 553 +3 6262 5435 5949 +3 1480 1832 4774 +3 7512 7141 7219 +3 7337 7012 3302 +3 1485 5152 6196 +3 5576 6988 4199 +3 2652 6559 6560 +3 6403 6560 2056 +3 2056 6560 6558 +3 6216 5468 6585 +3 7227 4324 7211 +3 5830 6561 4484 +3 4919 6562 5904 +3 2821 697 3646 +3 5904 6562 6563 +3 7330 5751 3086 +3 6356 6357 5461 +3 3417 6563 6561 +3 5620 5621 1479 +3 4721 142 6130 +3 4513 6566 7196 +3 2638 2532 5383 +3 6421 4117 2118 +3 3236 1090 3666 +3 3149 6946 6123 +3 6567 1623 1190 +3 7117 321 315 +3 2981 3709 1490 +3 1490 1572 4814 +3 6454 6091 7110 +3 4575 2446 1571 +3 1571 3416 4575 +3 2689 2449 2955 +3 532 6952 6950 +3 3939 6549 7407 +3 6546 6572 5849 +3 1495 5850 2257 +3 5467 6572 1569 +3 5072 6251 5731 +3 7192 6952 532 +3 6573 2338 3077 +3 5218 7011 2463 +3 15 7030 4004 +3 975 1326 6574 +3 4320 3207 1327 +3 4487 6576 3230 +3 6576 6577 2129 +3 1726 4411 2769 +3 4214 6577 6048 +3 314 5958 6048 +3 2746 4303 1907 +3 3284 1748 6972 +3 6759 6725 177 +3 6578 1252 4420 +3 4759 405 1497 +3 4759 6582 6583 +3 5464 6583 2063 +3 2063 6723 5464 +3 6584 4958 7451 +3 4958 6584 6588 +3 3832 3515 1642 +3 6588 5057 7425 +3 5609 1501 948 +3 1507 5832 948 +3 728 5838 1505 +3 1505 6592 1873 +3 5950 1339 2952 +3 903 3212 7248 +3 339 752 4170 +3 7413 559 2227 +3 1503 559 6592 +3 3039 6595 4657 +3 1735 7327 6102 +3 4657 6595 1628 +3 7437 1262 2687 +3 2037 4100 2016 +3 4061 6596 1629 +3 3252 6597 3514 +3 3566 6598 6081 +3 6081 6598 6599 +3 1210 3176 696 +3 4773 6599 4593 +3 4593 6599 6597 +3 6780 6601 739 +3 5756 7472 486 +3 1321 3692 4251 +3 6211 5288 6647 +3 6602 6603 995 +3 4763 6943 3815 +3 4797 5602 7378 +3 6205 6204 2840 +3 869 6603 6601 +3 5229 5230 4215 +3 2838 6604 73 +3 73 6604 2072 +3 7060 7065 2844 +3 6605 2076 5285 +3 4781 3576 4780 +3 4838 3450 2703 +3 4781 292 4263 +3 77 5892 3664 +3 7070 6610 4034 +3 4034 6610 6613 +3 3163 6611 241 +3 1436 2597 2247 +3 6611 6610 241 +3 6259 6260 3920 +3 4440 4649 5507 +3 1692 3802 1597 +3 1880 5924 2379 +3 4797 4753 2981 +3 3317 6614 6616 +3 4645 960 7087 +3 6049 694 864 +3 4820 1452 4216 +3 4567 6616 2104 +3 2104 6616 6613 +3 7501 7060 1408 +3 4995 6550 6618 +3 373 7062 7060 +3 4603 3478 516 +3 3039 6622 6623 +3 6623 1788 3039 +3 5005 4777 1371 +3 4697 2062 4272 +3 6789 1499 2247 +3 5005 6623 6620 +3 4400 5509 1769 +3 6993 7138 708 +3 2571 3055 6789 +3 3058 6624 4459 +3 4204 2284 1517 +3 1517 6627 5217 +3 6918 6627 1181 +3 6625 1181 6627 +3 6628 7475 1232 +3 3059 6629 7156 +3 7156 6629 6631 +3 2326 3120 7173 +3 3748 3745 5911 +3 3215 6631 6628 +3 2242 3470 302 +3 5829 5720 6821 +3 5829 6634 6635 +3 6127 2778 7402 +3 6423 5893 2397 +3 5905 6635 6414 +3 6414 6635 6633 +3 1436 1499 4421 +3 3351 6638 3301 +3 3324 3326 3796 +3 1200 6639 6640 +3 2242 3876 6640 +3 201 6640 6638 +3 4369 6645 2962 +3 4722 6606 5485 +3 1301 3376 1684 +3 644 5235 3971 +3 6538 1087 6051 +3 3881 6646 1021 +3 844 1713 3829 +3 1021 6646 6648 +3 5271 5273 5904 +3 4601 664 4651 +3 1911 6521 3607 +3 3170 6648 6645 +3 5282 4157 4833 +3 6650 6651 681 +3 4768 2398 6651 +3 574 4625 1518 +3 574 6651 6650 +3 2196 3534 1520 +3 5825 6655 3129 +3 4348 5244 5450 +3 135 257 899 +3 5876 2249 3079 +3 5016 5757 5343 +3 1056 7129 866 +3 5094 3694 892 +3 2762 1524 2731 +3 2731 343 2762 +3 208 3894 1525 +3 1045 4360 1033 +3 1528 3460 4703 +3 102 7128 11 +3 1529 5870 3526 +3 2158 6662 300 +3 6663 300 1531 +3 4456 6663 1883 +3 7129 125 1963 +3 1883 6663 2736 +3 4460 7013 7244 +3 1650 3663 6313 +3 177 5684 6759 +3 2318 2671 940 +3 6011 7062 373 +3 3891 6666 2649 +3 2649 6666 7483 +3 6987 6669 633 +3 5796 6670 4053 +3 6670 771 6674 +3 6674 771 1474 +3 7094 1535 3747 +3 5236 6678 5478 +3 5478 6678 2743 +3 1536 6040 6924 +3 6680 5513 2434 +3 1538 4835 3165 +3 5664 5402 1498 +3 3922 293 2079 +3 249 1552 1094 +3 6934 2060 2870 +3 2079 2971 3922 +3 1654 4346 5475 +3 3547 3546 4554 +3 4068 6684 6682 +3 4999 702 1610 +3 5084 5083 2622 +3 3232 6686 1540 +3 3182 6689 4300 +3 872 5027 319 +3 5549 6691 283 +3 1540 283 6691 +3 1985 5398 4967 +3 6637 3850 4117 +3 1795 5444 4329 +3 4956 5943 6230 +3 1795 6694 6695 +3 5034 3492 1913 +3 5528 5530 3862 +3 291 6693 2468 +3 4322 6696 1072 +3 1542 5614 638 +3 2659 3028 2720 +3 2244 6792 3111 +3 5975 6698 6699 +3 5896 6699 371 +3 371 6699 6696 +3 3609 4194 3007 +3 2185 6792 7085 +3 6871 6701 5763 +3 6554 6701 1323 +3 6988 5576 1938 +3 4438 6703 6709 +3 6550 6551 1523 +3 5152 5858 6690 +3 6792 2185 759 +3 5152 6690 2474 +3 3087 2867 2744 +3 4296 3087 116 +3 1545 6709 6705 +3 537 6703 1544 +3 4494 5222 7139 +3 4438 6709 2744 +3 4096 6800 7038 +3 601 6711 1051 +3 1051 6711 6710 +3 6547 6548 3924 +3 2156 6713 6405 +3 2433 6337 5974 +3 6405 1549 3117 +3 5556 4342 5588 +3 3971 2346 644 +3 2394 6753 3103 +3 1665 6715 279 +3 7149 5087 3929 +3 1704 938 4955 +3 5373 6715 2056 +3 2056 6715 6403 +3 4184 4181 343 +3 3034 4270 3084 +3 3695 3694 5094 +3 61 6720 7445 +3 5834 1942 1620 +3 6479 2657 112 +3 2019 7091 5834 +3 3821 6725 5029 +3 5819 356 696 +3 3707 1558 2138 +3 6118 7113 4755 +3 2139 2745 5844 +3 5560 1558 1211 +3 262 6642 7077 +3 6690 2770 2474 +3 627 6730 7275 +3 5067 485 6117 +3 7275 5605 7279 +3 5816 1134 7146 +3 4474 4475 5161 +3 6398 6397 3766 +3 6850 468 6863 +3 4950 6733 6734 +3 7162 6734 5630 +3 5630 6734 6731 +3 6079 6737 2631 +3 376 6408 5079 +3 468 5443 6863 +3 3332 6739 6740 +3 6189 7140 2888 +3 3649 3432 1013 +3 1614 6740 6737 +3 4880 6704 5135 +3 7301 3334 639 +3 3626 6424 2118 +3 4831 6828 881 +3 4561 3100 3252 +3 7140 6189 1817 +3 410 2648 246 +3 6742 922 3204 +3 5470 6085 4688 +3 7278 4306 1919 +3 2015 5071 505 +3 679 2183 666 +3 5891 6745 5483 +3 3849 6746 5335 +3 5335 6746 6748 +3 6412 6748 3439 +3 3439 6748 6745 +3 1095 5979 6797 +3 2846 2031 258 +3 6750 1536 6924 +3 6555 2719 2031 +3 2613 3114 3767 +3 2847 1929 6752 +3 6752 6750 3109 +3 3154 1472 172 +3 3174 6753 4542 +3 4638 6755 5663 +3 5663 6755 6756 +3 6229 6756 2394 +3 2394 6756 6753 +3 6725 6759 5029 +3 5029 6759 1565 +3 7218 2719 2100 +3 119 5926 2286 +3 5589 809 2003 +3 1398 3527 7293 +3 1569 3253 4683 +3 1882 1933 1836 +3 4435 6759 5684 +3 2282 2194 2399 +3 6974 648 3284 +3 4303 2569 2661 +3 4440 4932 2616 +3 7350 6764 6593 +3 4487 6765 677 +3 677 6765 6835 +3 7159 7000 2157 +3 3097 3098 6337 +3 4157 6768 4833 +3 6719 5821 947 +3 2635 6769 794 +3 794 6769 6866 +3 343 4181 3672 +3 2286 7222 119 +3 1571 2726 3416 +3 4305 4414 287 +3 4808 6772 4812 +3 7146 1134 3213 +3 3530 6774 556 +3 2334 1908 6321 +3 869 5510 3095 +3 556 6774 6775 +3 7237 7222 382 +3 125 7428 1797 +3 5898 6775 6565 +3 6565 6775 6772 +3 4275 6494 4751 +3 188 5777 1577 +3 5990 6777 1446 +3 1221 1253 5403 +3 1578 1446 6777 +3 1855 1856 6778 +3 5578 5577 5469 +3 739 6779 6780 +3 6601 5510 869 +3 6076 6780 6778 +3 5778 6781 6419 +3 1925 6722 7077 +3 6736 6781 2161 +3 6737 6783 1614 +3 6784 5651 395 +3 7156 3748 3093 +3 5651 6784 6785 +3 3088 3052 3305 +3 1091 6785 2738 +3 5323 6786 2848 +3 2751 6786 1581 +3 6885 1867 1582 +3 1582 6791 3302 +3 3302 6791 746 +3 1581 746 6791 +3 5472 2467 5434 +3 2344 6793 1617 +3 6781 6793 6419 +3 5434 6794 5472 +3 2495 4194 5509 +3 3713 1241 3092 +3 6219 6796 421 +3 6474 6472 538 +3 6799 1344 251 +3 2533 5250 2621 +3 917 6796 5672 +3 7287 6801 2106 +3 4025 7202 6303 +3 2891 5888 7019 +3 6802 7179 6116 +3 7179 6802 860 +3 2915 6803 197 +3 197 6803 6801 +3 5633 2386 5724 +3 7129 4447 7428 +3 5541 6804 5855 +3 32 5855 2753 +3 103 3817 4864 +3 103 6806 3817 +3 925 4084 3089 +3 1482 6806 35 +3 2744 3085 4438 +3 35 6806 2752 +3 2063 1588 6723 +3 2670 2826 464 +3 5546 3643 7519 +3 1589 6166 313 +3 1589 2754 6166 +3 2350 6809 10 +3 7393 6810 5046 +3 1799 4318 6389 +3 5046 6810 7448 +3 800 3236 3916 +3 6811 6812 2271 +3 3032 7237 4052 +3 3125 6814 2760 +3 5613 5455 1477 +3 6718 3084 747 +3 6814 1592 5204 +3 3125 6171 4501 +3 5784 3022 3082 +3 2418 7141 3893 +3 1592 5186 6766 +3 1593 6814 5314 +3 2012 5109 2665 +3 6743 6818 5160 +3 3082 2898 5784 +3 5160 6818 1594 +3 2925 6819 6649 +3 6346 3968 4410 +3 1594 6649 6819 +3 2904 4289 1601 +3 3275 4438 3085 +3 238 2242 302 +3 151 2242 238 +3 5379 6668 5377 +3 4583 5010 6823 +3 5484 3672 3197 +3 343 6824 2762 +3 3494 6825 2315 +3 2221 7380 4032 +3 6827 7380 1598 +3 4252 4250 5844 +3 3080 670 1333 +3 4169 4210 3329 +3 5668 6827 2763 +3 4222 4223 558 +3 6044 6829 3449 +3 4588 6829 6372 +3 2761 149 1440 +3 1906 7185 1058 +3 3247 2904 1601 +3 1745 4048 6321 +3 4602 4262 1893 +3 2722 7494 1921 +3 644 2346 3746 +3 2004 5431 3833 +3 5804 903 4831 +3 890 2528 5265 +3 6969 6868 2033 +3 6764 6765 6593 +3 5308 5307 1176 +3 3160 6838 6839 +3 5798 5799 3439 +3 3766 6839 6835 +3 3554 1696 4924 +3 4188 4882 1623 +3 4170 3238 339 +3 3535 6637 4966 +3 3345 3509 6738 +3 3014 6847 4650 +3 4014 6848 6069 +3 6290 6849 5397 +3 6510 6851 6619 +3 5122 3769 581 +3 6619 6851 6852 +3 5638 5636 3627 +3 2985 6852 6849 +3 7392 7294 2886 +3 2634 6854 6855 +3 750 2272 2182 +3 3231 6855 2205 +3 2205 6855 6853 +3 3175 3174 4542 +3 24 6856 2142 +3 5137 7211 4324 +3 169 1111 2066 +3 4535 5137 3249 +3 2210 4921 5803 +3 2510 7453 2857 +3 5719 6722 6482 +3 1691 6859 2140 +3 3125 5314 6814 +3 903 5804 898 +3 6321 6860 5178 +3 2001 4699 2297 +3 6010 5330 6162 +3 5346 6862 1606 +3 1604 4280 6200 +3 4324 7227 6050 +3 1890 5115 7446 +3 1605 6866 6768 +3 6768 6769 4833 +3 6236 4031 1044 +3 1606 794 6866 +3 1611 6870 234 +3 1011 756 5568 +3 234 6688 5339 +3 5185 3081 4859 +3 1201 2131 6867 +3 942 6874 1671 +3 7077 1120 199 +3 942 1671 1619 +3 1748 2853 6164 +3 7153 6875 4887 +3 6915 6438 6876 +3 7513 2998 4882 +3 2437 6877 2517 +3 2517 6877 1456 +3 50 6402 6878 +3 6810 6880 10 +3 5725 5305 3801 +3 10 6880 123 +3 1619 4028 942 +3 1619 1833 4028 +3 4205 5804 4757 +3 6052 1132 2590 +3 6542 4921 2909 +3 6898 6881 3741 +3 3741 6881 6893 +3 4633 4932 5507 +3 2968 6556 3383 +3 2477 3242 2178 +3 4810 4079 493 +3 709 6890 6891 +3 6891 2552 709 +3 3301 3324 3060 +3 5757 6692 4341 +3 4127 3993 3730 +3 5330 6891 6162 +3 6162 6891 6889 +3 6881 1854 1664 +3 3626 2118 4396 +3 4341 6148 6795 +3 4179 4757 5804 +3 511 7302 2006 +3 2124 2199 6212 +3 6892 1973 623 +3 3829 3830 844 +3 511 3749 3000 +3 6881 6898 2773 +3 352 3402 1207 +3 2773 1854 6881 +3 2119 4285 7200 +3 3364 2358 3340 +3 3364 6904 6907 +3 7032 1423 6102 +3 5316 7426 4649 +3 4868 7072 3056 +3 5479 3898 6197 +3 6562 6905 4484 +3 4484 6905 6907 +3 957 4496 5326 +3 5615 6907 6904 +3 6904 4260 5615 +3 6185 7170 1064 +3 6925 6908 3956 +3 3956 6908 7142 +3 6523 7045 3950 +3 3836 6910 6911 +3 2700 6911 5872 +3 6266 2691 2639 +3 2247 7007 6789 +3 5872 6911 2713 +3 6912 1622 4702 +3 6916 2936 1622 +3 3481 6916 2834 +3 2834 6916 2979 +3 5188 3448 5466 +3 6155 6917 7199 +3 4060 7386 3560 +3 1517 5217 4944 +3 5042 2206 2070 +3 1356 6918 5060 +3 1935 2897 3906 +3 4586 2924 2325 +3 1142 4026 60 +3 4935 6920 616 +3 6929 6921 3956 +3 3956 6921 6925 +3 6908 6258 6523 +3 629 2952 5781 +3 2009 6925 6920 +3 2070 7348 5042 +3 1794 2677 5929 +3 6612 6927 6928 +3 5129 7369 7348 +3 3377 6928 6926 +3 6102 7327 7032 +3 5900 6929 6027 +3 5612 6930 6428 +3 6428 6930 7144 +3 1625 265 6586 +3 3740 6093 1470 +3 2811 6932 2598 +3 2598 6932 6933 +3 7373 6933 1293 +3 1293 6933 6931 +3 6272 6271 5936 +3 5894 6934 7316 +3 2718 5188 3409 +3 1742 2059 2869 +3 1628 6596 4099 +3 1499 1436 2247 +3 5730 6939 2774 +3 3230 3958 1840 +3 6765 6942 6593 +3 7026 6944 5401 +3 3818 1632 3149 +3 6946 3255 6124 +3 6947 2135 1587 +3 2658 6947 2228 +3 2397 2919 5508 +3 1268 960 5253 +3 2228 6947 2776 +3 1666 1634 1636 +3 1636 5466 1666 +3 5750 6951 6399 +3 1635 1854 2120 +3 1970 117 2786 +3 2444 1735 4274 +3 2553 6520 2768 +3 2444 4486 1735 +3 2120 2122 1635 +3 3282 7418 5555 +3 7421 7471 7221 +3 5336 5606 1638 +3 4762 1638 6953 +3 6917 6954 7199 +3 4515 4514 81 +3 492 6955 237 +3 4404 4424 454 +3 7391 6956 2935 +3 501 3296 3047 +3 237 2935 6956 +3 6920 6958 2009 +3 7081 6960 6293 +3 6293 6960 6961 +3 6016 7450 7301 +3 6308 4314 7325 +3 4834 6961 6958 +3 3241 6962 4861 +3 2599 4772 132 +3 4831 881 4179 +3 3185 3187 5129 +3 1498 6964 6966 +3 5667 5534 3518 +3 802 6966 6962 +3 2557 6967 6970 +3 2843 1156 3630 +3 4020 838 7364 +3 3303 5443 2335 +3 704 3558 5240 +3 1521 4134 6967 +3 2296 3286 575 +3 7442 7421 132 +3 4402 6971 3303 +3 4410 4411 6346 +3 4831 4179 5804 +3 1999 7306 81 +3 2768 6744 2553 +3 5624 3521 6621 +3 7223 6399 1851 +3 1643 1748 6164 +3 4202 6974 6975 +3 1706 6975 670 +3 3026 6354 7119 +3 6975 6972 5753 +3 6978 4650 3553 +3 5542 3647 474 +3 7311 7493 7264 +3 557 5040 4360 +3 2884 6979 5610 +3 1732 6980 265 +3 265 6980 7036 +3 3654 3655 6294 +3 5546 672 2998 +3 4522 4521 7214 +3 2727 6985 6986 +3 315 6986 7117 +3 6986 6984 301 +3 6669 5612 6428 +3 226 6987 7028 +3 7481 6989 633 +3 1644 3032 4052 +3 5175 2939 6998 +3 4585 6992 2964 +3 2964 6992 7503 +3 7138 6993 628 +3 2175 4176 1767 +3 628 6993 3722 +3 5232 6995 3189 +3 2174 5508 2919 +3 27 1646 6997 +3 3159 6997 6084 +3 2115 7001 1515 +3 6976 2368 5950 +3 3443 1648 7003 +3 4069 7003 6364 +3 6701 7466 1323 +3 1648 7005 2712 +3 7099 7005 2781 +3 1869 3515 1430 +3 905 3598 2173 +3 2781 154 7099 +3 7433 7006 4212 +3 4212 7006 5966 +3 5523 7008 5356 +3 1785 1649 717 +3 2416 1649 1651 +3 4485 7178 3846 +3 1651 7016 6443 +3 5653 1652 2942 +3 2964 7503 7493 +3 2033 1556 1918 +3 1858 7017 2107 +3 2107 7017 7145 +3 6911 4232 3836 +3 1658 7020 622 +3 7021 5500 4469 +3 5500 7021 7023 +3 1918 7004 5903 +3 1563 1309 7025 +3 7023 7020 1656 +3 6521 2783 6520 +3 7025 1309 1656 +3 671 3354 3040 +3 7025 7421 1563 +3 5370 7026 4011 +3 6917 7027 263 +3 263 7027 5318 +3 4657 6105 3039 +3 6989 6987 633 +3 226 7028 6429 +3 5259 521 153 +3 5458 7029 622 +3 622 7029 1662 +3 1661 4375 5824 +3 1504 4434 4482 +3 6991 6992 352 +3 4375 1661 2785 +3 2484 7197 2028 +3 1293 2030 1663 +3 1663 7029 7375 +3 2379 5924 4989 +3 5790 1355 3671 +3 5079 2157 3568 +3 147 2694 5466 +3 5405 5404 660 +3 1998 5831 554 +3 7057 5654 2694 +3 6979 6980 5610 +3 1547 6132 542 +3 2894 5356 2038 +3 2226 4614 2281 +3 5143 62 6032 +3 2038 28 6406 +3 1669 993 636 +3 1667 5147 2437 +3 1466 4147 1285 +3 5100 4632 3593 +3 82 4199 7168 +3 5147 1667 5301 +3 1668 5277 1998 +3 7040 6671 3453 +3 2783 1800 6520 +3 866 864 7372 +3 6909 5342 3895 +3 3950 7430 2372 +3 4697 6818 3012 +3 7438 7197 2484 +3 3446 5916 2618 +3 2096 854 5114 +3 7046 5288 6211 +3 1966 1441 2878 +3 1225 2842 2788 +3 2522 2094 1672 +3 1672 7046 1612 +3 5604 4681 7104 +3 6102 4274 1735 +3 1930 6654 263 +3 7336 2903 2769 +3 2150 3504 453 +3 1675 7050 1886 +3 1882 7050 1350 +3 1350 7050 2789 +3 2687 6621 3521 +3 4339 6621 2687 +3 2399 2194 2791 +3 7441 3939 5089 +3 1561 7524 356 +3 7241 7052 1808 +3 28 2038 5882 +3 28 7054 7253 +3 3007 4187 2792 +3 944 2995 6305 +3 2792 3609 3007 +3 6039 3299 190 +3 4095 7056 3589 +3 7056 7059 2215 +3 536 3970 3035 +3 5432 7465 2860 +3 6228 7059 7055 +3 2833 7089 4742 +3 3606 2555 2406 +3 1683 3962 1988 +3 5787 4866 5670 +3 5113 2108 4594 +3 2052 7063 2799 +3 718 4197 6034 +3 1990 7064 6888 +3 2045 4333 4037 +3 2891 7200 5888 +3 6888 7064 4728 +3 6539 160 5476 +3 7110 6361 6454 +3 1275 6902 6729 +3 1776 1687 1779 +3 1779 1687 1982 +3 5102 4904 1689 +3 1689 3781 5102 +3 2280 1113 2663 +3 1692 435 3802 +3 1023 1715 3974 +3 107 7069 5214 +3 3121 2563 5757 +3 6678 7069 3747 +3 3747 7069 2797 +3 4837 3192 5265 +3 6610 4798 241 +3 2557 6863 6301 +3 3002 2908 6521 +3 4080 7071 4868 +3 6594 7519 3643 +3 4868 7071 7072 +3 6259 7072 4034 +3 4034 7072 7070 +3 7073 4739 2554 +3 4739 7073 7411 +3 6154 7076 6841 +3 6033 6192 1469 +3 1930 263 5318 +3 3388 5281 4632 +3 6841 7076 4740 +3 4991 1527 2863 +3 2884 5610 7249 +3 1350 7505 1933 +3 2799 7064 3841 +3 3078 4525 7151 +3 1080 7079 68 +3 2536 7078 2801 +3 7119 1268 3026 +3 2427 3554 6861 +3 2683 1701 6293 +3 5116 5586 4441 +3 6960 5823 2009 +3 143 7081 2804 +3 3422 4956 1702 +3 4383 2605 7524 +3 7087 3451 4645 +3 5863 656 6329 +3 6540 7087 1268 +3 584 131 3720 +3 855 909 3247 +3 4742 3469 2833 +3 3568 376 5079 +3 4031 4032 3133 +3 3747 7093 7094 +3 7415 4961 849 +3 6668 5379 7242 +3 6236 7094 7090 +3 3080 3074 670 +3 355 7098 154 +3 154 7098 7099 +3 2999 6364 7003 +3 3572 1162 4974 +3 5687 7099 7097 +3 7265 7100 3489 +3 3489 7100 1986 +3 1069 3890 4186 +3 5727 7101 2511 +3 2511 7101 1983 +3 5792 3198 340 +3 4196 7105 7107 +3 7106 7107 4107 +3 1269 4431 3276 +3 2373 584 4993 +3 4107 4106 656 +3 1496 7107 7105 +3 7109 7095 1707 +3 7200 2891 474 +3 3890 1069 2172 +3 6672 4056 3890 +3 2345 2154 2800 +3 4691 2657 7510 +3 1709 4014 6069 +3 4354 7436 2633 +3 4887 5249 7114 +3 7153 4887 7114 +3 5653 2233 280 +3 1484 6241 6066 +3 5014 7118 6672 +3 6410 7120 3209 +3 3209 7120 7477 +3 7121 48 250 +3 48 7121 7451 +3 7333 7331 3041 +3 7126 1001 411 +3 1001 7126 7128 +3 1525 2735 208 +3 3608 5806 3023 +3 4880 5157 3234 +3 4660 4305 984 +3 3543 1607 2659 +3 4656 3988 1511 +3 7128 7125 1065 +3 1012 7131 1902 +3 5968 5969 1900 +3 3467 7132 7133 +3 2874 4186 3736 +3 2916 1821 2618 +3 3003 7133 4746 +3 4746 7133 7131 +3 546 7134 4350 +3 6616 7135 3317 +3 3317 7135 7137 +3 4713 4714 221 +3 121 7137 7134 +3 6909 6908 6523 +3 6929 6930 6027 +3 6428 7144 7482 +3 7150 787 908 +3 787 7150 1720 +3 7375 7373 1293 +3 4345 4344 786 +3 3195 7152 2806 +3 5744 2603 1315 +3 5568 712 7305 +3 1088 4598 1721 +3 3738 348 347 +3 1541 7150 908 +3 4038 5655 6047 +3 4382 1539 2542 +3 861 831 5722 +3 1988 2542 1683 +3 143 7158 7160 +3 5305 6306 3801 +3 6523 6258 6017 +3 6017 7157 7045 +3 2207 3019 7102 +3 4653 4655 3880 +3 6734 5986 4950 +3 5992 7162 7164 +3 6245 3046 5134 +3 487 7164 7161 +3 5942 7165 6833 +3 6833 491 923 +3 5285 2073 4294 +3 3415 3835 3017 +3 6641 7166 2107 +3 2844 7167 1408 +3 1408 7167 7499 +3 71 4382 4287 +3 7500 163 1724 +3 1724 1728 7500 +3 309 4617 2535 +3 2807 847 1895 +3 5527 3682 335 +3 3557 1941 2347 +3 5422 5225 3718 +3 1986 4531 1687 +3 1983 7100 4870 +3 4804 168 3277 +3 3142 3105 1947 +3 7411 7175 118 +3 118 7175 7424 +3 6767 3240 686 +3 686 1737 6767 +3 1737 2702 2191 +3 2889 5591 4263 +3 607 4308 643 +3 1926 4451 2882 +3 7181 1131 5585 +3 7181 7177 608 +3 356 5553 696 +3 7505 1350 1927 +3 7188 7183 198 +3 7183 7184 198 +3 2144 1866 7184 +3 2711 1927 4909 +3 1058 4294 1906 +3 2510 4531 1984 +3 6345 7188 2718 +3 5790 7189 1355 +3 2980 3661 3121 +3 1355 7189 7420 +3 6212 7191 532 +3 5774 7192 4750 +3 353 5158 2674 +3 2170 2261 2017 +3 3421 7465 5432 +3 4750 7192 7193 +3 5579 3156 1448 +3 6043 7193 7191 +3 2588 7194 7195 +3 2689 7305 712 +3 2321 2359 4066 +3 8 7195 7194 +3 2421 702 6744 +3 6564 6566 483 +3 1170 360 6015 +3 2010 3931 7037 +3 7196 7194 1746 +3 4705 3663 6643 +3 19 1889 286 +3 1898 252 27 +3 2137 6653 1838 +3 1747 3214 81 +3 1749 1768 1740 +3 5061 3386 6676 +3 7410 1869 2514 +3 2510 2857 7455 +3 2169 6166 512 +3 7235 2144 1752 +3 1014 6514 1943 +3 7523 2537 307 +3 3386 6181 6676 +3 7236 7206 2144 +3 1753 3110 7397 +3 3110 7207 7208 +3 3900 7208 4739 +3 3014 4650 6978 +3 7208 7206 2554 +3 1980 4772 5505 +3 2456 4066 6426 +3 7209 7057 1550 +3 5624 7210 6036 +3 1354 1991 6373 +3 1677 7210 7212 +3 6231 4121 416 +3 685 7212 2246 +3 4730 7215 7216 +3 4022 7216 3004 +3 3004 7216 7213 +3 1137 7217 1781 +3 2607 612 3870 +3 1756 6973 7416 +3 1757 7271 2817 +3 2168 1502 6283 +3 1838 5754 2137 +3 3281 7220 1940 +3 1940 5442 3281 +3 3144 4659 3444 +3 6348 7223 7471 +3 4718 4719 993 +3 6537 6538 6051 +3 1686 7230 7231 +3 7148 1946 6652 +3 6756 7231 5663 +3 6326 4216 7255 +3 5663 7231 7226 +3 6110 5780 3005 +3 7232 3359 2035 +3 5639 2377 4949 +3 5660 3821 5029 +3 5527 5052 3585 +3 2266 7234 5961 +3 126 5062 1081 +3 1740 1768 1752 +3 173 7073 2554 +3 6718 6720 3034 +3 6956 7238 492 +3 179 2815 492 +3 1926 7505 6446 +3 6674 4053 6670 +3 6766 5186 322 +3 3009 898 5572 +3 6153 7013 4163 +3 4205 7186 5572 +3 1778 7245 1774 +3 6579 4067 1907 +3 1774 1779 1778 +3 950 5998 1744 +3 1219 7266 7265 +3 2157 334 7159 +3 2150 2667 164 +3 1772 7263 1219 +3 2823 108 1773 +3 1830 7249 5610 +3 2846 258 7395 +3 7260 7250 1219 +3 1219 7250 7266 +3 3041 6500 3219 +3 7052 7054 1808 +3 6406 28 434 +3 6930 7254 6027 +3 2073 5285 7367 +3 468 6850 1533 +3 6841 4740 2881 +3 7118 7257 2937 +3 5751 5018 3086 +3 500 7258 7259 +3 7479 7259 1180 +3 1180 7259 7257 +3 6246 7260 3813 +3 5334 7261 1273 +3 7261 7263 1771 +3 2697 1745 3066 +3 1774 1776 1779 +3 388 4793 4021 +3 1219 7263 7260 +3 3489 1687 1776 +3 1194 4870 7100 +3 1194 7265 7266 +3 7306 7076 81 +3 7252 7250 144 +3 7457 3679 3729 +3 7265 1772 1219 +3 1273 7245 1782 +3 1780 6926 6927 +3 1755 1782 7268 +3 5073 5679 3140 +3 3066 1743 2697 +3 1781 2378 1137 +3 2817 6973 1757 +3 7504 1926 2882 +3 4508 6816 3452 +3 1784 1791 1264 +3 1905 7465 3258 +3 7149 4939 3334 +3 5653 7016 1787 +3 1787 1786 26 +3 2243 7274 221 +3 221 7274 2818 +3 4939 5143 6032 +3 150 4772 1979 +3 4262 4264 508 +3 7229 7277 4469 +3 2047 56 5765 +3 5344 56 2069 +3 765 5143 4939 +3 5676 5673 72 +3 5491 7278 7495 +3 1793 5857 2839 +3 1793 2822 5857 +3 27 2515 1878 +3 7286 2106 1645 +3 2106 1800 7285 +3 7326 7287 438 +3 438 7287 2823 +3 3876 3877 1200 +3 6673 7289 7292 +3 6820 6821 2435 +3 151 7288 3876 +3 1807 4821 875 +3 1807 1811 4821 +3 4470 2825 2002 +3 6156 7295 5382 +3 5382 2824 3355 +3 6995 7296 3189 +3 3189 7296 7297 +3 7296 1338 2133 +3 132 7421 7025 +3 5451 1744 4400 +3 2740 1039 3024 +3 70 7299 7153 +3 7153 7299 1815 +3 3607 6521 2908 +3 1814 4516 2816 +3 4142 166 2167 +3 616 4824 4935 +3 1650 1722 1119 +3 196 7399 594 +3 1925 1928 6482 +3 7434 5168 55 +3 3214 1823 1999 +3 4991 3554 4924 +3 3280 2724 3727 +3 1999 81 3214 +3 6033 7243 3795 +3 7306 150 1979 +3 7442 150 1999 +3 6530 6529 6948 +3 6748 7308 5335 +3 5335 7308 7309 +3 2939 7309 6998 +3 6998 7309 7307 +3 2830 5701 1948 +3 3993 4127 6884 +3 4601 2616 4932 +3 643 2353 1825 +3 2490 5684 177 +3 1825 42 643 +3 6429 7312 152 +3 7312 1989 6513 +3 5380 5381 590 +3 1925 6482 6722 +3 171 3387 1827 +3 1829 1841 171 +3 2767 2560 1468 +3 3790 7315 1861 +3 856 1894 7042 +3 6148 4341 3388 +3 5353 7256 7404 +3 7316 7317 1859 +3 2212 3664 5892 +3 7145 7317 2506 +3 2506 7317 7315 +3 1923 7499 7166 +3 2623 615 3636 +3 1366 7319 1312 +3 3254 6652 1946 +3 3954 7322 5040 +3 7323 438 1773 +3 6801 7326 197 +3 197 7326 5700 +3 5159 1884 6940 +3 6722 7328 1120 +3 7423 7329 3086 +3 3086 7329 7330 +3 905 2173 879 +3 7474 7330 486 +3 486 7330 7328 +3 7120 7331 6672 +3 6672 7331 4056 +3 3403 4724 3773 +3 7333 3041 3219 +3 5545 6683 312 +3 6271 7335 5936 +3 141 7337 1832 +3 1832 6557 4774 +3 7012 7337 7334 +3 48 7451 7448 +3 1833 1834 4028 +3 2542 1988 4382 +3 2542 7339 2837 +3 1835 2833 3469 +3 4476 7409 6404 +3 7342 262 7438 +3 6642 262 1836 +3 1837 2839 5857 +3 73 257 2838 +3 7182 7241 1808 +3 1338 4915 4824 +3 2573 2314 1891 +3 911 2071 7502 +3 3688 7463 4875 +3 3517 667 3522 +3 1981 5089 3939 +3 2396 4047 1261 +3 2553 6521 6520 +3 5046 7449 31 +3 7296 4915 1338 +3 4839 7390 529 +3 6958 4935 4834 +3 7178 2075 3217 +3 6398 7350 5148 +3 4475 3674 5161 +3 7351 7352 2775 +3 1840 6942 3230 +3 6593 7352 7350 +3 5401 7501 2866 +3 7354 7405 2849 +3 468 2847 5443 +3 1842 2148 2784 +3 6710 6711 5367 +3 5542 6173 3474 +3 204 4364 5811 +3 140 5503 5205 +3 140 7359 4817 +3 69 7123 3595 +3 1657 2865 904 +3 5234 7359 4867 +3 4867 7359 7356 +3 1844 4372 5885 +3 754 3186 4925 +3 1845 1848 2005 +3 1082 7361 4553 +3 769 6006 7436 +3 1846 7362 6261 +3 1306 7362 2841 +3 2841 4704 1306 +3 1467 2836 1221 +3 1849 5096 4944 +3 2483 7363 1857 +3 5587 5582 4363 +3 4673 5059 3363 +3 3290 4283 2845 +3 3772 4730 4218 +3 945 896 3683 +3 1855 7371 3625 +3 5598 4673 1655 +3 1850 7109 3625 +3 4520 7068 5067 +3 5067 7068 5237 +3 7372 7368 866 +3 5698 7373 5115 +3 5115 7373 7446 +3 7375 1293 1663 +3 7336 4038 6047 +3 1654 5475 5919 +3 833 5341 5552 +3 5341 834 7086 +3 1615 4702 4040 +3 4920 7377 3883 +3 3124 2551 7379 +3 1859 5894 7316 +3 1859 2020 5894 +3 4988 7444 7445 +3 1862 145 2058 +3 1862 7065 145 +3 1729 471 5106 +3 7383 1865 2434 +3 5983 3742 4733 +3 6944 7501 5401 +3 1408 7499 1922 +3 1863 7388 724 +3 7388 254 401 +3 5724 5997 5633 +3 1865 254 7388 +3 2407 1388 5350 +3 7424 7389 16 +3 16 7389 4269 +3 7391 1149 7238 +3 7393 7225 1620 +3 7225 7393 1914 +3 3921 1914 5604 +3 1328 7395 258 +3 7395 1978 2846 +3 2014 1980 5505 +3 4319 7397 3110 +3 1365 1344 6799 +3 7398 7419 129 +3 4160 7400 4691 +3 1356 5060 5203 +3 6518 7401 4037 +3 2751 7403 2848 +3 480 3938 2166 +3 2848 7403 1870 +3 6919 6918 1181 +3 2832 7355 7405 +3 2849 4615 5381 +3 5436 4205 4757 +3 2810 4971 1871 +3 6085 3993 4688 +3 1871 7403 1112 +3 6982 2879 4468 +3 3617 5103 5060 +3 4494 4365 5222 +3 1394 4924 1696 +3 7404 4857 7224 +3 5150 5144 500 +3 5602 3545 2418 +3 695 5517 2992 +3 7175 7073 1149 +3 1858 7166 7499 +3 4739 7411 3923 +3 1788 4488 2774 +3 1955 2851 2227 +3 926 5255 1874 +3 1874 7414 2662 +3 1310 1306 4704 +3 2850 2112 1310 +3 6279 1708 843 +3 7415 4106 1496 +3 3858 2204 3505 +3 4688 6884 863 +3 4106 6329 656 +3 5027 872 4921 +3 5807 7416 6973 +3 6743 7002 921 +3 1756 7416 1878 +3 27 1878 1898 +3 1753 7397 7419 +3 7188 7189 2718 +3 7432 1355 1553 +3 5018 7422 3086 +3 6355 6647 256 +3 7488 7423 16 +3 16 7423 7424 +3 6556 378 2153 +3 5056 5724 2478 +3 7389 7175 1149 +3 118 7424 7422 +3 685 2246 2301 +3 7045 6523 6017 +3 7430 7432 2300 +3 129 198 7398 +3 1355 7432 3671 +3 7006 3307 1143 +3 5673 7434 72 +3 72 7434 6277 +3 1751 2790 2003 +3 6643 4414 4660 +3 5219 627 484 +3 2795 2854 2484 +3 6233 7438 262 +3 4573 6499 5078 +3 7438 2854 7342 +3 1886 1937 1675 +3 2634 6855 2986 +3 1886 2852 5670 +3 3285 2525 2530 +3 7062 7443 145 +3 7444 4988 741 +3 844 3151 701 +3 441 7506 5620 +3 7506 441 4245 +3 2537 6463 307 +3 307 7441 1618 +3 7401 6518 5642 +3 4023 6630 106 +3 3584 7509 935 +3 3184 7509 3584 +3 1821 7510 2657 +3 2916 7510 1821 +3 7511 1320 2236 +3 1686 7511 3384 +3 158 7512 2153 +3 7512 158 6127 +3 3643 7513 6594 +3 5546 2998 3643 +3 4160 7514 4159 +3 7514 4160 7510 +3 7515 775 3606 +3 5642 6518 5662 +3 775 7516 3434 +3 7515 7516 775 +3 7517 6226 1320 +3 1686 7517 7511 +3 2010 7518 381 +3 7518 2010 7037 +3 7519 2121 1556 +3 4143 7519 2033 +3 7520 4857 7404 +3 4010 7520 7256 +3 2537 7523 5978 +3 6215 7521 96 +3 4025 7522 7202 +3 7522 4025 2982 +3 1119 1627 7521 +3 191 7507 2141 +3 7524 353 4383 +3 5553 7524 2605 +3 217 7525 1527 +3 377 217 5559 \ No newline at end of file diff --git a/src/Unittests/unittests_tutorials.cc b/src/Unittests/unittests_tutorials.cc index 5503d2ab..1a35b4c7 100644 --- a/src/Unittests/unittests_tutorials.cc +++ b/src/Unittests/unittests_tutorials.cc @@ -446,14 +446,14 @@ TEST_F(OpenMeshTutorials, using_iterators_and_circulators) { TEST_F(OpenMeshTutorials, using_custom_properties) { MyMesh mesh; - bool ok = OpenMesh::IO::read_mesh(mesh, "output.off"); - EXPECT_TRUE(ok) << "Cannot read mesh from file 'output.off'"; + bool ok = OpenMesh::IO::read_mesh(mesh, "cube_noisy.off"); + EXPECT_TRUE(ok) << "Cannot read mesh from file 'cube_noisy.off'"; const int iterations = 100; { // Add a vertex property storing the computed centers of gravity - auto cog = OpenMesh::makeTemporaryProperty(mesh); + auto cog = OpenMesh::VProp(mesh); // Smooth the mesh several times for (int i = 0; i < iterations; ++i) { @@ -484,8 +484,8 @@ TEST_F(OpenMeshTutorials, using_custom_properties) { TEST_F(OpenMeshTutorials, using_STL_algorithms) { MyMeshWithTraits mesh; - bool ok = OpenMesh::IO::read_mesh(mesh, "output.off"); - EXPECT_TRUE(ok) << "Cannot read mesh from file 'output.off'"; + bool ok = OpenMesh::IO::read_mesh(mesh, "cube_noisy.off"); + EXPECT_TRUE(ok) << "Cannot read mesh from file 'cube_noisy.off'"; SmootherT smoother(mesh); smoother.smooth(100); @@ -882,4 +882,44 @@ TEST_F(OpenMeshTutorials, collapsing_edges) { // Our mesh now looks like in the illustration above after the collapsing. } +TEST_F(OpenMeshTutorials, using_smart_handles_and_smart_ranges) { + MyMesh mesh; + + bool ok = OpenMesh::IO::read_mesh(mesh, "cube_noisy.off"); + EXPECT_TRUE(ok) << "Cannot read mesh from file 'cube_noisy.off'"; + + const int iterations = 100; + + { + // Add a vertex property storing the laplace vector + auto laplace = OpenMesh::VProp(mesh); + + // Add a vertex property storing the laplace of the laplace + auto bi_laplace = OpenMesh::VProp(mesh); + + // Get a propertymanager of the points property of the mesh to use as functor + auto points = OpenMesh::getPointsProperty(mesh); + + // Smooth the mesh several times + for (int i = 0; i < iterations; ++i) { + // Iterate over all vertices to compute laplace vector + for (const auto& vh : mesh.vertices()) + laplace(vh) = vh.vertices().avg(points) - points(vh); + + // Iterate over all vertices to compte update vectors as the negative of the laplace of the laplace damped by 0.5 + for (const auto& vh : mesh.vertices()) + bi_laplace(vh) = (vh.vertices().avg(laplace) - laplace(vh)); + + // update points + for (const auto& vh : mesh.vertices()) + points(vh) += -0.5 * bi_laplace(vh); + } + } // The laplace and update properties are removed is removed from the mesh at the end of this scope. + + // write mesh + ok = OpenMesh::IO::write_mesh(mesh, "smoothed_smart_output.off"); + + EXPECT_TRUE(ok) << "Cannot write mesh to file 'smoothed_smart_output.off'"; +} + } From 147ae217e4ee0527a9279d4b42c75d09675c2de1 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 6 Nov 2019 12:05:27 +0100 Subject: [PATCH 53/60] update changelog --- Doc/changelog.docu | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Doc/changelog.docu b/Doc/changelog.docu index 716ce284..ce4a7404 100644 --- a/Doc/changelog.docu +++ b/Doc/changelog.docu @@ -13,7 +13,9 @@
  • Property System: Get rid of the OM_FORCE_STATIC_CAST defines. We use the type ids to check if the cast is valid or not. This will add more type safety.
  • Default Traits: Added DefaultTraitsDouble as a version of the default traits that uses double precision for positions and normals as well as float for colors.
  • Default Mesh Types: Added typdefs for a Triangle Mesh and a PolyMesh which use DefaultTraitsDouble and can be used as default mesh type be the user.
  • -
  • Template Programming Convenience: Added n_elements which returns the number of elements corresponding to the handle type given as template argument. Also added elements and all_elements methods returning ranges of the elements corresponding to the handle type given as template argument. +
  • Template Programming Convenience: Added n_elements which returns the number of elements corresponding to the handle type given as template argument. Also added elements and all_elements methods returning ranges of the elements corresponding to the handle type given as template argument.
  • +
  • Smart Handles: Most userfacing functions returning handles should now return smart handles instead. Smart handles know their corresponding mesh and give convenient access to mesh navigation methods. +
  • Smart Ranges: OpenMesh ranges now provide a few methods that simplify a few calculations. See documentation for more details. @@ -28,7 +30,7 @@
    • Change PropertyManager::operator* to access the property value for mesh properties
    • PropertyManager: add hasProperty function
    • -
    • PropertyManager rework: The behavior of the PropertyManager has been changed, hoepfully making it more usable. See tutoial. +
    • PropertyManager rework: The behavior of the PropertyManager has been changed, hopefully making it more usable. See tutoial.
    IO From 4c15ff6e60af4a9f72bcd840ee5c0034e4007c18 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Thu, 17 Oct 2019 16:02:00 +0200 Subject: [PATCH 54/60] add any of and all of to smart ranges --- src/OpenMesh/Core/Mesh/SmartRange.hh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index 8b40e6e2..07299d48 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -116,6 +116,26 @@ struct SmartRangeT return (1.0 / n_elements) * sum; } + template + auto any_of(Functor&& f) -> bool + { + auto range = static_cast(this); + for (auto e : *range) + if (f(e)) + return true; + return false; + } + + template + auto all_of(Functor&& f) -> bool + { + auto range = static_cast(this); + for (auto e : *range) + if (!f(e)) + return false; + return true; + } + /** @brief Convert range to array. * * Converts the range of elements into an array of objects returned by functor \p f. From b0276d485a309dd4a1a2b1f06f063fdd0159230e Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 6 Nov 2019 13:02:01 +0100 Subject: [PATCH 55/60] add documentation for any_of and all_of --- src/OpenMesh/Core/Mesh/SmartRange.hh | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/OpenMesh/Core/Mesh/SmartRange.hh b/src/OpenMesh/Core/Mesh/SmartRange.hh index 07299d48..a2405a68 100644 --- a/src/OpenMesh/Core/Mesh/SmartRange.hh +++ b/src/OpenMesh/Core/Mesh/SmartRange.hh @@ -116,6 +116,13 @@ struct SmartRangeT return (1.0 / n_elements) * sum; } + /** @brief Check if any element fulfils condition. + * + * Checks if functor \p f returns true for any of the elements in the range. + * Returns true if that is the case, false otherwise. + * + * @param f Functor that is evaluated for all elements. + */ template auto any_of(Functor&& f) -> bool { @@ -126,6 +133,13 @@ struct SmartRangeT return false; } + /** @brief Check if all elements fulfil condition. + * + * Checks if functor \p f returns true for all of the elements in the range. + * Returns true if that is the case, false otherwise. + * + * @param f Functor that is evaluated for all elements. + */ template auto all_of(Functor&& f) -> bool { From 35c31dd422224e3818a509460585398ee7155cc4 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 6 Nov 2019 14:03:11 +0100 Subject: [PATCH 56/60] update changelog --- Doc/changelog.docu | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Doc/changelog.docu b/Doc/changelog.docu index ce4a7404..c335c46e 100644 --- a/Doc/changelog.docu +++ b/Doc/changelog.docu @@ -8,6 +8,12 @@ 8.1 (?/?/?) +Breaking Changes +
      +
    • PropertyManager: PropertyManager only gives const access to the underlying mesh.
    • +
    + + Core
    • Property System: Get rid of the OM_FORCE_STATIC_CAST defines. We use the type ids to check if the cast is valid or not. This will add more type safety.
    • From 4160fc42d8f48786425a97406c00c0899025230b Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 6 Nov 2019 14:04:29 +0100 Subject: [PATCH 57/60] for better backwards compatibility add retain function which does nothing to property manager --- src/OpenMesh/Core/Utils/PropertyManager.hh | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index 2053b645..fabb4118 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -299,6 +299,15 @@ class PropertyManager { const MeshT& getMesh() const { return dynamic_cast(mesh_); } + + /** + * @deprecated This method no longer has any effect. Instead, named properties are always retained, while unnamed ones are not + * + * Tells the PropertyManager whether lifetime should be managed or not. + */ + OM_DEPRECATED("retain no longer has any effect. Instead, named properties are always retained, while unnamed ones are not.") + void retain(bool = true) {} + /** * Move constructor. Transfers ownership (delete responsibility). */ From 96fb20fdeb349ed6baa5fc9e61eeb5dd236f5409 Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 6 Nov 2019 14:04:55 +0100 Subject: [PATCH 58/60] for better backwards compatibility add second template parameter to makePropertyManagerFromExisting(orNew) --- src/OpenMesh/Core/Utils/PropertyManager.hh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/OpenMesh/Core/Utils/PropertyManager.hh b/src/OpenMesh/Core/Utils/PropertyManager.hh index fabb4118..0c79d4c6 100644 --- a/src/OpenMesh/Core/Utils/PropertyManager.hh +++ b/src/OpenMesh/Core/Utils/PropertyManager.hh @@ -818,11 +818,11 @@ PropertyManager makePropertyManagerFromNew(PolyConnectivity &mesh, con * @throws std::runtime_error if no property with the name \p propname of * matching type exists. */ -template +template OM_DEPRECATED("Use getProperty instead.") -PropertyManager makePropertyManagerFromExisting(PolyConnectivity &mesh, const char *propname) +PropertyManager makePropertyManagerFromExisting(PolyConnectivity &mesh, const char *propname) { - return PropertyManager(mesh, propname, true); + return PropertyManager(mesh, propname, true); } /** @relates PropertyManager @@ -833,11 +833,11 @@ PropertyManager makePropertyManagerFromExisting(PolyConnectivity &mesh * * Intended for creating or accessing persistent properties. */ -template +template OM_DEPRECATED("Use getOrMakeProperty instead.") -PropertyManager makePropertyManagerFromExistingOrNew(PolyConnectivity &mesh, const char *propname) +PropertyManager makePropertyManagerFromExistingOrNew(PolyConnectivity &mesh, const char *propname) { - return PropertyManager::createIfNotExists(mesh, propname); + return PropertyManager::createIfNotExists(mesh, propname); } /** @relates PropertyManager From eae634fe94decd21dbc91cdebd5f8cfb3a17d2ad Mon Sep 17 00:00:00 2001 From: Max Lyon Date: Wed, 6 Nov 2019 14:16:25 +0100 Subject: [PATCH 59/60] add method to move construct vector from array --- src/OpenMesh/Core/Geometry/Vector11T.hh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/OpenMesh/Core/Geometry/Vector11T.hh b/src/OpenMesh/Core/Geometry/Vector11T.hh index 6c78777e..e05a843b 100644 --- a/src/OpenMesh/Core/Geometry/Vector11T.hh +++ b/src/OpenMesh/Core/Geometry/Vector11T.hh @@ -169,6 +169,11 @@ class VectorT { std::copy_n(it, DIM, values_.begin()); } + /// construct from an array + explicit VectorT(container&& _array) { + values_ = _array; + } + /// copy & cast constructor (explicit) template Date: Fri, 8 Nov 2019 09:49:42 +0100 Subject: [PATCH 60/60] fix non-member min and max functions --- src/OpenMesh/Core/Geometry/Vector11T.hh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OpenMesh/Core/Geometry/Vector11T.hh b/src/OpenMesh/Core/Geometry/Vector11T.hh index e05a843b..c11a77e9 100644 --- a/src/OpenMesh/Core/Geometry/Vector11T.hh +++ b/src/OpenMesh/Core/Geometry/Vector11T.hh @@ -767,15 +767,15 @@ VectorT& minimize(VectorT& _v1, VectorT& /// \relates OpenMesh::VectorT /// non-member max template -VectorT max(VectorT& _v1, VectorT& _v2) { - return VectorT(_v1).maximize(_v2); +VectorT max(const VectorT& _v1, const VectorT& _v2) { + return _v1.max(_v2); } /// \relates OpenMesh::VectorT /// non-member min template -VectorT min(VectorT& _v1, VectorT& _v2) { - return VectorT(_v1).minimize(_v2); +VectorT min(const VectorT& _v1, const VectorT& _v2) { + return _v1.min(_v2); }