pyrove 3.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. pyrove-3.0.0/.editorconfig +20 -0
  2. pyrove-3.0.0/.gitignore +23 -0
  3. pyrove-3.0.0/CHANGELOG.md +8 -0
  4. pyrove-3.0.0/CMakeLists.txt +247 -0
  5. pyrove-3.0.0/CONTRIBUTING.md +7 -0
  6. pyrove-3.0.0/LICENSE.md +21 -0
  7. pyrove-3.0.0/PKG-INFO +458 -0
  8. pyrove-3.0.0/README.md +429 -0
  9. pyrove-3.0.0/SECURITY.md +6 -0
  10. pyrove-3.0.0/conanfile.py +70 -0
  11. pyrove-3.0.0/include/rove/a_star.h +1 -0
  12. pyrove-3.0.0/include/rove/aabb.h +1 -0
  13. pyrove-3.0.0/include/rove/bresenham_supercover.h +1 -0
  14. pyrove-3.0.0/include/rove/capsule.h +1 -0
  15. pyrove-3.0.0/include/rove/collision.h +1 -0
  16. pyrove-3.0.0/include/rove/cone.h +1 -0
  17. pyrove-3.0.0/include/rove/contact_info.h +1 -0
  18. pyrove-3.0.0/include/rove/dfloat.h +1 -0
  19. pyrove-3.0.0/include/rove/format.h +1 -0
  20. pyrove-3.0.0/include/rove/frustum.h +1 -0
  21. pyrove-3.0.0/include/rove/hash.h +1 -0
  22. pyrove-3.0.0/include/rove/hash_grid.h +1 -0
  23. pyrove-3.0.0/include/rove/heightfield.h +1 -0
  24. pyrove-3.0.0/include/rove/intersect.h +1 -0
  25. pyrove-3.0.0/include/rove/interval.h +1 -0
  26. pyrove-3.0.0/include/rove/matrix.h +1 -0
  27. pyrove-3.0.0/include/rove/noise.h +1 -0
  28. pyrove-3.0.0/include/rove/obb.h +1 -0
  29. pyrove-3.0.0/include/rove/octree.h +1 -0
  30. pyrove-3.0.0/include/rove/plane.h +1 -0
  31. pyrove-3.0.0/include/rove/quaternion.h +1 -0
  32. pyrove-3.0.0/include/rove/random.h +1 -0
  33. pyrove-3.0.0/include/rove/ray.h +1 -0
  34. pyrove-3.0.0/include/rove/scalar.h +1 -0
  35. pyrove-3.0.0/include/rove/segment.h +1 -0
  36. pyrove-3.0.0/include/rove/sphere.h +1 -0
  37. pyrove-3.0.0/include/rove/traits.h +1 -0
  38. pyrove-3.0.0/include/rove/transform.h +1 -0
  39. pyrove-3.0.0/include/rove/triangle.h +1 -0
  40. pyrove-3.0.0/include/rove/vec.h +1 -0
  41. pyrove-3.0.0/pyproject.toml +61 -0
  42. pyrove-3.0.0/pyrove/__init__.py +130 -0
  43. pyrove-3.0.0/python/bind_a_star.cc +73 -0
  44. pyrove-3.0.0/python/bind_aabb.cc +179 -0
  45. pyrove-3.0.0/python/bind_capsule.cc +103 -0
  46. pyrove-3.0.0/python/bind_collision.cc +50 -0
  47. pyrove-3.0.0/python/bind_frustum.cc +121 -0
  48. pyrove-3.0.0/python/bind_line.cc +140 -0
  49. pyrove-3.0.0/python/bind_matrix.cc +362 -0
  50. pyrove-3.0.0/python/bind_obb.cc +180 -0
  51. pyrove-3.0.0/python/bind_octree.cc +176 -0
  52. pyrove-3.0.0/python/bind_plane.cc +98 -0
  53. pyrove-3.0.0/python/bind_quaternion.cc +137 -0
  54. pyrove-3.0.0/python/bind_random.cc +69 -0
  55. pyrove-3.0.0/python/bind_ray.cc +126 -0
  56. pyrove-3.0.0/python/bind_rays.h +72 -0
  57. pyrove-3.0.0/python/bind_scalar.cc +72 -0
  58. pyrove-3.0.0/python/bind_sphere.cc +144 -0
  59. pyrove-3.0.0/python/bind_transform.cc +61 -0
  60. pyrove-3.0.0/python/bind_triangle.cc +111 -0
  61. pyrove-3.0.0/python/bind_vec.cc +317 -0
  62. pyrove-3.0.0/python/python_bindings.cc +116 -0
  63. pyrove-3.0.0/python/python_bindings.h +139 -0
  64. pyrove-3.0.0/src/a_star.h +431 -0
  65. pyrove-3.0.0/src/aabb.cc +142 -0
  66. pyrove-3.0.0/src/aabb.h +366 -0
  67. pyrove-3.0.0/src/bresenham_supercover.cc +165 -0
  68. pyrove-3.0.0/src/bresenham_supercover.h +39 -0
  69. pyrove-3.0.0/src/capsule.cc +54 -0
  70. pyrove-3.0.0/src/capsule.h +56 -0
  71. pyrove-3.0.0/src/collision.h +267 -0
  72. pyrove-3.0.0/src/cone.h +84 -0
  73. pyrove-3.0.0/src/contact_info.cc +9 -0
  74. pyrove-3.0.0/src/contact_info.h +36 -0
  75. pyrove-3.0.0/src/dfloat.cc +335 -0
  76. pyrove-3.0.0/src/dfloat.h +191 -0
  77. pyrove-3.0.0/src/format.h +118 -0
  78. pyrove-3.0.0/src/frustum.cc +123 -0
  79. pyrove-3.0.0/src/frustum.h +54 -0
  80. pyrove-3.0.0/src/hash.h +48 -0
  81. pyrove-3.0.0/src/hash_grid.h +393 -0
  82. pyrove-3.0.0/src/heightfield.cc +309 -0
  83. pyrove-3.0.0/src/heightfield.h +71 -0
  84. pyrove-3.0.0/src/intersect.cc +220 -0
  85. pyrove-3.0.0/src/intersect.h +29 -0
  86. pyrove-3.0.0/src/interval.cc +9 -0
  87. pyrove-3.0.0/src/interval.h +34 -0
  88. pyrove-3.0.0/src/matrix.cc +566 -0
  89. pyrove-3.0.0/src/matrix.h +906 -0
  90. pyrove-3.0.0/src/noise.h +104 -0
  91. pyrove-3.0.0/src/obb.cc +390 -0
  92. pyrove-3.0.0/src/obb.h +633 -0
  93. pyrove-3.0.0/src/octree.cc +13 -0
  94. pyrove-3.0.0/src/octree.h +679 -0
  95. pyrove-3.0.0/src/plane.cc +116 -0
  96. pyrove-3.0.0/src/plane.h +112 -0
  97. pyrove-3.0.0/src/quaternion.h +478 -0
  98. pyrove-3.0.0/src/random.h +183 -0
  99. pyrove-3.0.0/src/ray.cc +89 -0
  100. pyrove-3.0.0/src/ray.h +92 -0
  101. pyrove-3.0.0/src/scalar.h +286 -0
  102. pyrove-3.0.0/src/segment.h +145 -0
  103. pyrove-3.0.0/src/sphere.cc +110 -0
  104. pyrove-3.0.0/src/sphere.h +178 -0
  105. pyrove-3.0.0/src/traits.h +249 -0
  106. pyrove-3.0.0/src/transform.h +176 -0
  107. pyrove-3.0.0/src/triangle.cc +197 -0
  108. pyrove-3.0.0/src/triangle.h +468 -0
  109. pyrove-3.0.0/src/vec.cc +52 -0
  110. pyrove-3.0.0/src/vec.h +1627 -0
@@ -0,0 +1,20 @@
1
+ root = true
2
+
3
+ [*]
4
+ charset = utf-8
5
+ end_of_line = lf
6
+ insert_final_newline = true
7
+ trim_trailing_whitespace = true
8
+
9
+ [*.{h,cc}]
10
+ indent_style = tab
11
+ indent_size = 4
12
+ tab_width = 4
13
+ max_line_length = 135
14
+
15
+ [{CMakeLists.txt,*.cmake,*.py,*.toml}]
16
+ indent_style = space
17
+ indent_size = 4
18
+
19
+ [*.md]
20
+ trim_trailing_whitespace = false
@@ -0,0 +1,23 @@
1
+ build/
2
+ docs/html/
3
+ docs/python/_build/
4
+
5
+ # Python
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+ *.so
10
+ *.egg
11
+ *.egg-info/
12
+ dist/
13
+ .eggs/
14
+ pip-wheel-metadata/
15
+ *.whl
16
+ .Python
17
+ .venv/
18
+ venv/
19
+ ENV/
20
+
21
+ # Conan
22
+ CMakeUserPresets.json
23
+ tests/test_conan_package/build/
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ All notable changes to rove are written here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/);
4
+ versions follow [Semantic Versioning](https://semver.org/).
5
+
6
+ ## [3.0.0]
7
+
8
+ First public release.
@@ -0,0 +1,247 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2004-2026 Manvel Avetisian
3
+
4
+ cmake_minimum_required(VERSION 3.15)
5
+ project(rove VERSION 3.0.0 LANGUAGES CXX)
6
+ include(GNUInstallDirs)
7
+
8
+ set(CMAKE_CXX_STANDARD 20)
9
+ set(CMAKE_CXX_STANDARD_REQUIRED ON)
10
+
11
+ # Built by itself, rove picks its build type and link-time optimisation; added by a project (add_subdirectory), it leaves both to it:
12
+ # a library that forces Release on its parent, or LTO on its own archive (which GNU ld cannot read without the LTO plugin), is in the
13
+ # way. ROVE_LTO asks for it either way.
14
+ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
15
+ set(ROVE_TOP_LEVEL ON)
16
+ else()
17
+ set(ROVE_TOP_LEVEL OFF)
18
+ endif()
19
+
20
+ if(ROVE_TOP_LEVEL AND NOT CMAKE_BUILD_TYPE)
21
+ set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
22
+ message(STATUS "Build type not specified, defaulting to Release")
23
+ endif()
24
+
25
+ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
26
+
27
+ option(ROVE_LTO "Link-time optimisation of rove in Release and RelWithDebInfo (on when rove is built by itself)" ${ROVE_TOP_LEVEL})
28
+ if(ROVE_LTO AND (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo"))
29
+ include(CheckIPOSupported)
30
+ check_ipo_supported(RESULT ipo_supported OUTPUT ipo_error)
31
+ if(ipo_supported)
32
+ message(STATUS "IPO/LTO enabled")
33
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
34
+ else()
35
+ message(STATUS "IPO/LTO not supported: ${ipo_error}")
36
+ endif()
37
+ endif()
38
+
39
+ # Library sources
40
+ set(ROVE_SOURCES
41
+ src/aabb.cc
42
+ src/bresenham_supercover.cc
43
+ src/capsule.cc
44
+ src/contact_info.cc
45
+ src/frustum.cc
46
+ src/heightfield.cc
47
+ src/intersect.cc
48
+ src/interval.cc
49
+ src/matrix.cc
50
+ src/obb.cc
51
+ src/octree.cc
52
+ src/plane.cc
53
+ src/ray.cc
54
+ src/sphere.cc
55
+ src/triangle.cc
56
+ src/vec.cc
57
+ )
58
+
59
+ # dfloat (src/dfloat.h): a float that gives the same bits on every platform, for lockstep simulations. Off by default: without it
60
+ # rove is built and behaves as before. On, it builds dfloat and rove's instantiations for it, and adds -ffp-contract=off to rove and
61
+ # to whoever links it (a multiply and an add fused into one rounding on one machine and not on another would undo it).
62
+ option(ROVE_DFLOAT "Build rove::dfloat, the deterministic float" OFF)
63
+ if(ROVE_DFLOAT)
64
+ list(APPEND ROVE_SOURCES src/dfloat.cc)
65
+ endif()
66
+
67
+ # Create static library
68
+ add_library(rove STATIC ${ROVE_SOURCES})
69
+ # Position-independent, so it links into a shared object (pyrove, pyedge, an Android app's libmain.so) whoever builds it. It used
70
+ # to link there only because rove forced link-time optimisation on itself, whose code is generated at the final link.
71
+ set_target_properties(rove PROPERTIES POSITION_INDEPENDENT_CODE ON)
72
+ if(ROVE_DFLOAT)
73
+ target_compile_definitions(rove PUBLIC ROVE_DFLOAT)
74
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
75
+ target_compile_options(rove PUBLIC -ffp-contract=off)
76
+ else()
77
+ message(FATAL_ERROR "ROVE_DFLOAT: no flag known to keep ${CMAKE_CXX_COMPILER_ID} from fusing multiply-adds")
78
+ endif()
79
+ endif()
80
+
81
+ add_library(rove::rove ALIAS rove)
82
+ set_target_properties(rove PROPERTIES VERSION ${PROJECT_VERSION})
83
+
84
+ # The public headers are include/rove/*.h (one-line shims to src/), included as <rove/vec.h>. rove's parent directory is on the
85
+ # path too, so code written for <rove/src/vec.h> keeps compiling where rove is checked out as a directory named rove.
86
+ get_filename_component(ROVE_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}" DIRECTORY)
87
+ target_include_directories(rove PUBLIC
88
+ $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
89
+ $<BUILD_INTERFACE:${ROVE_PARENT_DIR}>
90
+ $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>)
91
+ target_compile_features(rove PUBLIC cxx_std_20)
92
+
93
+ # Warnings for rove's own sources, in every build type
94
+ option(ROVE_WARNINGS "Compile rove with the compiler's warnings on" ${ROVE_TOP_LEVEL})
95
+ if(ROVE_WARNINGS)
96
+ if(MSVC)
97
+ # (C4201: a vector's components are named through anonymous structs in a union, on purpose)
98
+ target_compile_options(rove PRIVATE /W4 /wd4201)
99
+ else()
100
+ target_compile_options(rove PRIVATE -Wall -Wextra)
101
+ endif()
102
+ endif()
103
+
104
+ # Tests
105
+ option(ROVE_TESTS "Build tests" ${ROVE_TOP_LEVEL})
106
+
107
+ if(ROVE_TESTS)
108
+ find_package(Boost REQUIRED COMPONENTS unit_test_framework)
109
+
110
+ set(ROVE_TEST_SOURCES
111
+ tests/test_main.cc
112
+ tests/test_aabb.cc
113
+ tests/test_a_star.cc
114
+ tests/test_bresenham_supercover.cc
115
+ tests/test_capsule.cc
116
+ tests/test_checks.cc
117
+ tests/test_collision.cc
118
+ tests/test_float_maths.cc
119
+ tests/test_format.cc
120
+ tests/test_frustum.cc
121
+ tests/test_hash_grid.cc
122
+ tests/test_heightfield.cc
123
+ tests/test_line.cc
124
+ tests/test_matrix.cc
125
+ tests/test_obb.cc
126
+ tests/test_octree.cc
127
+ tests/test_plane.cc
128
+ tests/test_quaternion.cc
129
+ tests/test_random.cc
130
+ tests/test_ray.cc
131
+ tests/test_scalar.cc
132
+ tests/test_sphere.cc
133
+ tests/test_traits.cc
134
+ tests/test_transform.cc
135
+ tests/test_triangle.cc
136
+ tests/test_vec.cc
137
+ )
138
+ if(ROVE_DFLOAT)
139
+ list(APPEND ROVE_TEST_SOURCES tests/test_dfloat.cc)
140
+ endif()
141
+
142
+ add_executable(rove_tests ${ROVE_TEST_SOURCES})
143
+ # (a double rounded back to float in what this instantiates is an error: rove's templates of float compute in float)
144
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
145
+ set_source_files_properties(tests/test_float_maths.cc PROPERTIES COMPILE_OPTIONS "-Werror=float-conversion")
146
+ endif()
147
+ target_link_libraries(rove_tests PRIVATE rove Boost::unit_test_framework)
148
+ # The tests compare rove's results bit for bit with the same expressions written out: a compiler that fuses a multiply and an add
149
+ # in one and not the other (Apple Clang does by default) would make them differ in the last bit.
150
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
151
+ target_compile_options(rove_tests PRIVATE -ffp-contract=off)
152
+ endif()
153
+
154
+ enable_testing()
155
+ add_test(NAME rove_tests COMMAND rove_tests)
156
+ endif()
157
+
158
+ # Python bindings
159
+ option(ROVE_PYTHON "Build Python bindings" OFF)
160
+
161
+ if(ROVE_PYTHON)
162
+ find_package(Python 3.9 COMPONENTS Interpreter Development.Module REQUIRED)
163
+
164
+ # nanobind: a wheel build takes the one pip installed for it (pyproject.toml), a CMake build fetches it
165
+ if(SKBUILD)
166
+ execute_process(COMMAND ${Python_EXECUTABLE} -m nanobind --cmake_dir
167
+ OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE nanobind_ROOT)
168
+ find_package(nanobind CONFIG REQUIRED)
169
+ else()
170
+ include(FetchContent)
171
+ FetchContent_Declare(
172
+ nanobind
173
+ GIT_REPOSITORY https://github.com/wjakob/nanobind
174
+ GIT_TAG v2.4.0
175
+ )
176
+ FetchContent_MakeAvailable(nanobind)
177
+ endif()
178
+
179
+ # Python binding sources (organized by class)
180
+ set(PYROVE_SOURCES
181
+ python/python_bindings.cc
182
+ python/bind_vec.cc
183
+ python/bind_matrix.cc
184
+ python/bind_quaternion.cc
185
+ python/bind_sphere.cc
186
+ python/bind_aabb.cc
187
+ python/bind_obb.cc
188
+ python/bind_ray.cc
189
+ python/bind_line.cc
190
+ python/bind_plane.cc
191
+ python/bind_triangle.cc
192
+ python/bind_capsule.cc
193
+ python/bind_collision.cc
194
+ python/bind_frustum.cc
195
+ python/bind_octree.cc
196
+ python/bind_a_star.cc
197
+ python/bind_scalar.cc
198
+ python/bind_transform.cc
199
+ python/bind_random.cc
200
+ )
201
+
202
+ # FREE_THREADED: declares the module safe without the GIL on a free-threaded
203
+ # interpreter (python3.14t), which would otherwise turn the GIL back on for
204
+ # the whole process when it is imported; no effect on a GIL build.
205
+ nanobind_add_module(pyrove_bind FREE_THREADED ${PYROVE_SOURCES})
206
+ target_link_libraries(pyrove_bind PRIVATE rove)
207
+ target_include_directories(pyrove_bind PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/python)
208
+
209
+ # Override nanobind's default -Os with -O3 for maximum performance.
210
+ # nanobind_add_module adds -Os to minimize binary size, but for a math
211
+ # library the binding code benefits from full optimization. The last -O
212
+ # flag wins with GCC/Clang.
213
+ if(CMAKE_BUILD_TYPE STREQUAL "Release")
214
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
215
+ target_compile_options(pyrove_bind PRIVATE -O3)
216
+ endif()
217
+ endif()
218
+
219
+ # a wheel (scikit-build-core) puts the module inside the pyrove package
220
+ if(SKBUILD)
221
+ install(TARGETS pyrove_bind LIBRARY DESTINATION pyrove)
222
+ endif()
223
+
224
+ # pyrove's own tests (pytest and numpy), against the module just built
225
+ if(ROVE_TESTS)
226
+ add_test(NAME pyrove_py COMMAND ${Python_EXECUTABLE} -m pytest -q -p no:cacheprovider tests
227
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
228
+ set_tests_properties(pyrove_py PROPERTIES ENVIRONMENT
229
+ "PYTHONPATH=${CMAKE_CURRENT_SOURCE_DIR};ROVE_PYTHON_BINDINGS_DIR=$<TARGET_FILE_DIR:pyrove_bind>;PYTHONDONTWRITEBYTECODE=1")
230
+ endif()
231
+ endif()
232
+
233
+ # Install: the library, the headers as <rove/x.h>, and a CMake package (find_package(rove 3 CONFIG), target rove::rove)
234
+ option(ROVE_INSTALL "Generate rove's install rules" ${ROVE_TOP_LEVEL})
235
+ if(ROVE_INSTALL AND NOT SKBUILD)
236
+ include(CMakePackageConfigHelpers)
237
+ install(TARGETS rove EXPORT roveTargets
238
+ ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
239
+ INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
240
+ # the real headers go where the shims would point: <rove/x.h> is the header itself once installed
241
+ install(DIRECTORY src/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/rove FILES_MATCHING PATTERN "*.h")
242
+ install(EXPORT roveTargets NAMESPACE rove:: DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/rove)
243
+ write_basic_package_version_file(${CMAKE_CURRENT_BINARY_DIR}/roveConfigVersion.cmake COMPATIBILITY SameMajorVersion)
244
+ file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/roveConfig.cmake "include(\${CMAKE_CURRENT_LIST_DIR}/roveTargets.cmake)\n")
245
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/roveConfig.cmake ${CMAKE_CURRENT_BINARY_DIR}/roveConfigVersion.cmake
246
+ DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/rove)
247
+ endif()
@@ -0,0 +1,7 @@
1
+ # Contributing
2
+
3
+ Contributions are welcome as GitHub pull requests.
4
+
5
+ You are also welcome to fork the project under the terms of its [license](LICENSE.md).
6
+
7
+ For a security problem, see [SECURITY.md](SECURITY.md).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2004-2026 Manvel Avetisian
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.