diff options
Diffstat (limited to 'third_party/immer')
311 files changed, 0 insertions, 74216 deletions
diff --git a/third_party/immer/.clang-format b/third_party/immer/.clang-format deleted file mode 100644 index f7308d25886e..000000000000 --- a/third_party/immer/.clang-format +++ /dev/null @@ -1,38 +0,0 @@ ---- -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: 'true' -AlignEscapedNewlines: Right -AlignTrailingComments: 'true' -AllowShortFunctionsOnASingleLine: 'true' -AllowShortBlocksOnASingleLine: 'true' -AlwaysBreakTemplateDeclarations: 'true' -AccessModifierOffset: -4 -BinPackArguments: 'false' -BinPackParameters: 'false' -BreakBeforeBraces: Mozilla -BreakBeforeInheritanceComma: 'true' -BreakBeforeTernaryOperators: 'true' -BreakConstructorInitializers: BeforeComma -BreakStringLiterals: 'true' -ColumnLimit: '80' -CompactNamespaces: 'false' -ConstructorInitializerAllOnOneLineOrOnePerLine: 'false' -FixNamespaceComments: 'true' -IndentCaseLabels: 'false' -IndentWidth: '4' -IndentWrappedFunctionNames: 'false' -KeepEmptyLinesAtTheStartOfBlocks: 'false' -Language: Cpp -MaxEmptyLinesToKeep: '1' -NamespaceIndentation: None -PointerAlignment: Left -ReflowComments: 'true' -SortIncludes: 'true' -SortUsingDeclarations: 'true' -SpaceAfterCStyleCast: 'true' -SpaceAfterTemplateKeyword: 'true' -SpaceBeforeAssignmentOperators: 'true' -SpaceBeforeParens: ControlStatements -TabWidth: '4' -UseTab: Never -... diff --git a/third_party/immer/.dir-locals.el b/third_party/immer/.dir-locals.el deleted file mode 100644 index 8adc4f1d2032..000000000000 --- a/third_party/immer/.dir-locals.el +++ /dev/null @@ -1,7 +0,0 @@ -((nil . - ((indent-tabs-mode . nil) - (show-trailing-whitespace . t))) - (c-mode . - ((mode . c++))) - (c++-mode . - ((eval add-hook 'before-save-hook #'clang-format-buffer nil t)))) diff --git a/third_party/immer/.github/FUNDING.yml b/third_party/immer/.github/FUNDING.yml deleted file mode 100644 index defc6ca1fa1d..000000000000 --- a/third_party/immer/.github/FUNDING.yml +++ /dev/null @@ -1,3 +0,0 @@ -github: arximboldi -patreon: sinusoidal -custom: ["paypal.me/sinusoidal", sinusoid.al] diff --git a/third_party/immer/.gitignore b/third_party/immer/.gitignore deleted file mode 100644 index 2074141ec261..000000000000 --- a/third_party/immer/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -bazel-* -build/ -build-*/ -reports/ -doc/_build -doc/_doxygen -bazel-* - -tools/travis/ssh-key -tools/clojure/target/ -tools/scala/target/ -tools/scala/project/target/ - -extra/js/out -extra/js/boost - -__pycache__ - -.gdb_history - -.cache -tools/clojure/.lein* - -*.pyc diff --git a/third_party/immer/.skip-subtree b/third_party/immer/.skip-subtree deleted file mode 100644 index d49b47f75a16..000000000000 --- a/third_party/immer/.skip-subtree +++ /dev/null @@ -1 +0,0 @@ -Third-party code with non-depot layout. diff --git a/third_party/immer/.travis.yml b/third_party/immer/.travis.yml deleted file mode 100644 index cdbe09bf92fb..000000000000 --- a/third_party/immer/.travis.yml +++ /dev/null @@ -1,84 +0,0 @@ -language: nix -dist: trusty - -git: - depth: false - -matrix: - include: - - env: DO=check TYPE=Debug TOOLCHAIN=llvm-5 SANITIZE=true - - env: DO=check TYPE=Release TOOLCHAIN=llvm-5 BENCHMARKS=true - - env: DO=check TYPE=Debug TOOLCHAIN=gnu-6 COVERAGE=true - - env: DO=check TYPE=Release TOOLCHAIN=gnu-6 BENCHMARKS=true - - env: DO=check TYPE=Debug TOOLCHAIN=gnu-7 STD=17 - - env: DO=check TYPE=Debug TOOLCHAIN=llvm-9 STD=17 FUZZERS=true - - env: DO=build - - env: DO=docs - -before_install: - - | - : ${TOOLCHAIN:=gnu-6} - : ${TYPE:=Debug} - : ${STD:=14} - function build-p { [[ "${DO}" == build ]]; } - function check-p { [[ "${DO}" == check ]]; } - function docs-p { [[ "${DO}" == docs ]]; } - function coverage-p { [[ "${COVERAGE}" == true ]]; } - function benchmarks-p { [[ "${BENCHMARKS}" == true ]]; } - function deploy-p { - [[ "${TRAVIS_PULL_REQUEST}" == "false" && \ - "${TRAVIS_BRANCH}" == "master" ]] - } - function upload-p { - [[ -n "$encrypted_1c8d51d72e41_key" && \ - -n "$encrypted_1c8d51d72e41_iv" ]] - } - function decrypt-ssh-key { - openssl aes-256-cbc \ - -K $encrypted_1c8d51d72e41_key \ - -iv $encrypted_1c8d51d72e41_iv \ - -in tools/travis/ssh-key.enc \ - -out tools/travis/ssh-key -d - chmod 600 tools/travis/ssh-key - } - function with-nix { - nix-shell --argstr toolchain $TOOLCHAIN --run "set -e; $1" - } - -install: - - with-nix "echo == nix environment ok" - -before_script: - - | - with-nix " - mkdir build && cd build - cmake .. \ - -DCMAKE_BUILD_TYPE=${TYPE} \ - -DCHECK_SLOW_TESTS=false \ - -DCXX_STANDARD=${STD} \ - -DCHECK_BENCHMARKS=${BENCHMARKS} \ - -DENABLE_COVERAGE=${COVERAGE} \ - -DENABLE_SANITIZE=${SANITIZE} \ - -DCHECK_FUZZERS=${FUZZERS} \ - -DDISABLE_FREE_LIST=${SANITIZE} - " - -script: - - | - set -e - ! build-p || nix-build - ! check-p || with-nix "cd build && make -j2 check" - ! docs-p || with-nix "cd build && make docs" - -after_success: - - | - ! coverage-p || with-nix " - cd build - find . -name \"*.gcno\" | xargs gcov -bcprs ${PWD} - bash <(curl -s https://codecov.io/bash) -x gcov - " - if upload-p; then - decrypt-ssh-key - ! benchmarks-p || with-nix "cd build && make upload-benchmark-reports" - ! docs-p || ! deploy-p || with-nix "cd build && make upload-docs" - fi diff --git a/third_party/immer/BUILD b/third_party/immer/BUILD deleted file mode 100644 index 3d79830b60a3..000000000000 --- a/third_party/immer/BUILD +++ /dev/null @@ -1,11 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -cc_library( - name = "immer", - include_prefix = "immer", - strip_include_prefix = - "immer", - hdrs = glob([ - "immer/**/*.hpp", - ]), -) diff --git a/third_party/immer/CMakeLists.txt b/third_party/immer/CMakeLists.txt deleted file mode 100644 index dedfdf74013b..000000000000 --- a/third_party/immer/CMakeLists.txt +++ /dev/null @@ -1,141 +0,0 @@ - -cmake_minimum_required(VERSION 3.5.1) -cmake_policy(SET CMP0048 NEW) # enable project VERSION -cmake_policy(SET CMP0056 NEW) # honor link flags in try_compile() -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") - -project(immer VERSION 0.6.2) - -if (NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Wno-unused-parameter -Wno-extended-offsetof -Wno-c++17-extensions -Wno-c++1z-extensions -Wno-unknown-warning-option") -endif() -set(CMAKE_EXPORT_COMPILE_COMMANDS on) -set(CMAKE_CXX_EXTENSIONS off) -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments") -endif() - -include(GNUInstallDirs) -include(ImmerUtils) - -# Options -# ======= - -option(ENABLE_SANITIZE "compile with sanitizers enabled") -option(ENABLE_COVERAGE "compile with test coverage support") -option(DISABLE_WERROR "enable --werror") -option(DISABLE_FREE_LIST "disables the free list heap") -option(DISABLE_THREAD_SAFETY "disables thread safety by default") -option(CHECK_FUZZERS "Add fuzzers as part of make check") - -option(ENABLE_PYTHON "enable building python module" off) -option(ENABLE_GUILE "enable building guile module" off) -option(ENABLE_BOOST_COROUTINE "run benchmarks with boost coroutine" off) - -option(immer_BUILD_TESTS "Build tests" ON) -option(immer_BUILD_EXAMPLES "Build examples" ON) -option(immer_BUILD_DOCS "Build docs" ON) -option(immer_BUILD_EXTRAS "Build extras" ON) - -set(CXX_STANDARD 14 CACHE STRING "c++ standard number") - -set(CMAKE_CXX_STANDARD ${CXX_STANDARD}) -set(CMAKE_CXX_STANDARD_REQUIRED on) - -if (ENABLE_SANITIZE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fsanitize=leak") -endif() -if (NOT MSVC AND NOT DISABLE_WERROR) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") -endif() - -# Dependencies -# ============ - -if (ENABLE_BOOST_COROUTINE) - set(immer_boost_components coroutine) -endif() - -find_package(Threads) -find_package(BoehmGC) -find_package(Boost 1.56 COMPONENTS ${immer_boost_components}) - -find_program(CCACHE ccache) -if (CCACHE) - message(STATUS "Using ccache: ${CCACHE}") - set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE}) - set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE}) -else() - message(STATUS "Could not find ccache") -endif() - -if (NOT BOEHM_GC_FOUND) - set(BOEHM_GC_LIBRARIES "") -endif() - -# Targets -# ======= - -# the library -add_library(immer INTERFACE) -target_include_directories(immer INTERFACE - $<BUILD_INTERFACE:${immer_BINARY_DIR}/> - $<BUILD_INTERFACE:${immer_SOURCE_DIR}/> - $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>) -install(TARGETS immer EXPORT ImmerConfig) -install(EXPORT ImmerConfig DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Immer") -install(DIRECTORY immer DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") - -# development target to be used in tests, examples, benchmarks... -immer_canonicalize_cmake_booleans( - DISABLE_FREE_LIST - DISABLE_THREAD_SAFETY - CHECK_SLOW_TESTS) -add_library(immer-dev INTERFACE) -target_include_directories(immer-dev SYSTEM INTERFACE - ${Boost_INCLUDE_DIR} - ${BOEHM_GC_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/tools/include) -target_link_libraries(immer-dev INTERFACE - immer - ${BOEHM_GC_LIBRARIES} - ${CMAKE_THREAD_LIBS_INIT}) -target_compile_definitions(immer-dev INTERFACE - -DIMMER_CXX_STANDARD=${CXX_STANDARD} - -DIMMER_HAS_LIBGC=1 - -DIMMER_NO_FREE_LIST=${DISABLE_FREE_LIST} - -DIMMER_NO_THREAD_SAFETY=${DISABLE_THREAD_SAFETY} - -DIMMER_SLOW_TESTS=${CHECK_SLOW_TESTS}) -if (ENABLE_COVERAGE) - target_compile_options(immer-dev INTERFACE "--coverage") - target_link_libraries(immer-dev INTERFACE "--coverage") -endif() - -# Testing -# ======= - -if (immer_BUILD_TESTS) - enable_testing() - - add_custom_target(check - COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Build and run all the tests and examples.") - - add_subdirectory(test) - add_subdirectory(benchmark) -endif() - -if (immer_BUILD_EXAMPLES) - add_subdirectory(example) -endif() - -if (immer_BUILD_DOCS) - add_subdirectory(doc) -endif() - -if (immer_BUILD_EXTRAS) - add_subdirectory(extra/fuzzer) - add_subdirectory(extra/python) - add_subdirectory(extra/guile) -endif() diff --git a/third_party/immer/LICENSE b/third_party/immer/LICENSE deleted file mode 100644 index 36b7cd93cdfb..000000000000 --- a/third_party/immer/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Boost Software License - Version 1.0 - August 17th, 2003 - -Permission is hereby granted, free of charge, to any person or organization -obtaining a copy of the software and accompanying documentation covered by -this license (the "Software") to use, reproduce, display, distribute, -execute, and transmit the Software, and to prepare derivative works of the -Software, and to permit third-parties to whom the Software is furnished to -do so, all subject to the following: - -The copyright notices in the Software and this entire statement, including -the above license grant, this restriction and the following disclaimer, -must be included in all copies of the Software, in whole or in part, and -all derivative works of the Software, unless such copies or derivative -works are solely in the form of machine-executable object code generated by -a source language processor. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT -SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE -FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, -ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/third_party/immer/README.rst b/third_party/immer/README.rst deleted file mode 100644 index afa2fecbb3bc..000000000000 --- a/third_party/immer/README.rst +++ /dev/null @@ -1,225 +0,0 @@ - -.. image:: https://travis-ci.org/arximboldi/immer.svg?branch=master - :target: https://travis-ci.org/arximboldi/immer - :alt: Travis Badge - -.. image:: https://codecov.io/gh/arximboldi/immer/branch/master/graph/badge.svg - :target: https://codecov.io/gh/arximboldi/immer - :alt: CodeCov Badge - -.. image:: https://cdn.rawgit.com/arximboldi/immer/355a113782aedc2ea22463444014809269c2376d/doc/_static/sinusoidal-badge.svg - :target: https://sinusoid.al - :alt: Sinusoidal Engineering badge - :align: right - -.. raw:: html - - <img width="100%" src="https://cdn.rawgit.com/arximboldi/immer/3888170d247359cc0905eed548cd46897caef0f4/doc/_static/logo-front.svg" alt="Logotype"/> - -.. include:introduction/start - -**immer** is a library of persistent_ and immutable_ data structures -written in C++. These enable whole new kinds of architectures for -interactive and concurrent programs of striking simplicity, -correctness, and performance. - -.. _persistent: https://en.wikipedia.org/wiki/Persistent_data_structure -.. _immutable: https://en.wikipedia.org/wiki/Immutable_object - -* **Documentation** (Contents_) -* **Code** (GitHub_) -* **CppCon'17 Talk**: *Postmodern Immutable Data Structures* (YouTube_, Slides_) -* **ICFP'17 Paper**: *Persistence for the masses* (Preprint_) - -.. _contents: https://sinusoid.es/immer/#contents -.. _github: https://github.com/arximboldi/immer -.. _youtube: https://www.youtube.com/watch?v=sPhpelUfu8Q -.. _slides: https://sinusoid.es/talks/immer-cppcon17 -.. _preprint: https://public.sinusoid.es/misc/immer/immer-icfp17.pdf - - - .. raw:: html - - <a href="https://www.patreon.com/sinusoidal"> - <img align="right" src="https://cdn.rawgit.com/arximboldi/immer/master/doc/_static/patreon.svg"> - </a> - - This library has full months of *pro bono* research and development - invested in it. This is just the first step in a long-term vision - of making interactive and concurrent C++ programs easier to - write. **Put your logo here and help this project's long term - sustainability by buying a sponsorship package:** immer@sinusoid.al - -.. include:index/end - -Example -------- - -.. github does not support the ``literalinclude`` directive. This - example is copy pasted from ``example/vector/intro.cpp`` - -.. code-block:: c++ - - #include <immer/vector.hpp> - int main() - { - const auto v0 = immer::vector<int>{}; - const auto v1 = v0.push_back(13); - assert(v0.size() == 0 && v1.size() == 1 && v1[0] == 13); - - const auto v2 = v1.set(0, 42); - assert(v1[0] == 13 && v2[0] == 42); - } -.. - - For a **complete example** check `Ewig, a simple didactic - text-editor <https://github.com/arximboldi/ewig>`_ built with this - library. You may also wanna check `Lager, a Redux-like library - <https://github.com/arximboldi/lager>`_ for writting interactive - software in C++ using a value-oriented design. - - -Why? ----- - -In the last few years, there has been a growing interest in immutable -data structures, motivated by the horizontal scaling of our processing -power and the ubiquity of highly interactive systems. Languages like -Clojure_ and Scala_ provide them by default, and implementations -for JavaScript like Mori_ and Immutable.js_ are widely used, -specially in combination with modern UI frameworks like React_. - -Interactivity - Thanks to *persistence* and *structural sharing*, new values can - be efficiently compared with old ones. This enables simpler ways of - *reasoning about change* that sit at the core of modern - interactive systems programming paradigms like `reactive - programming`_. - -Concurrency - Passing immutable data structures by value does not need to copy - any data. In the absence of mutation, data can be safely read - from multiple concurrent processes, and enable concurrency - patterns like `share by communicating`_ efficiently. - -Parallelism - Some recent immutable data structures have interesting properties - like :math:`O(log(n))` concatenation, which enable new kinds of - `parallelization algorithms`_. - -.. _clojure: http://clojure.org/reference/data_structures -.. _scala: http://docs.scala-lang.org/overviews/collections/overview.html - -.. _mori: https://swannodette.github.io/mori/ -.. _immutable.js: https://github.com/facebook/immutable-js -.. _react: https://facebook.github.io/react/ - -.. _reactive programming: https://en.wikipedia.org/wiki/Reactive_programming -.. _share by communicating: https://blog.golang.org/share-memory-by-communicating -.. _parallelization algorithms: http://docs.scala-lang.org/overviews/parallel-collections/overview.html - -Features --------- - -Idiomatic - This library doesn't pretend that it is written in Haskell. It - leverages features from recent standards to provide an API that is - both efficient and natural for a C++ developer. - -Performant - You use C++ because you need this. *Immer* implements state of - the art data structures with efficient cache utilization and have - been proven production ready in other languages. It also includes - our own improvements over that are only possible because of the - C++'s ability to abstract over memory layout. We monitor the - performance impact of every change by collecting `benchmark - results`_ directly from CI. - -.. _benchmark results: https://public.sinusoid.es/misc/immer/reports/ - -Customizable - We leverage templates and `policy-based design`_ to build - data-structures that can be adapted to work efficiently for - various purposes and architectures, for example, by choosing among - various `memory management strategies`. This turns - *immer* into a good foundation to provide immutable data - structures to higher level languages with a C runtime, like - Python_ or Guile_. - -.. _python: https://www.python.org/ -.. _guile: https://www.gnu.org/software/guile/ -.. _policy-based design: https://en.wikipedia.org/wiki/Policy-based_design -.. _memory management strategies: https://sinusoid.es/immer/memory.html - -Dependencies ------------- - -This library is written in **C++14** and a compliant compiler is -necessary. It is `continuously tested`_ with Clang 3.8 and GCC 6, but -it might work with other compilers and versions. - -No external library is necessary and there are no other requirements. - -.. _continuously tested: https://travis-ci.org/arximboldi/immer - -Usage ------ - -This is a **header only** library. You can just copy the ``immer`` -subfolder somewhere in your *include path*. - -If you are using the `Nix package manager`_ (we strongly recommend it) -you can just:: - - nix-env -if https://github.com/arximboldi/immer/archive/master.tar.gz - -Alternatively, you can use `CMake`_ to install the library in your -system once you have manually cloned the repository:: - - mkdir -p build && cd build - cmake .. && sudo make install - -.. _nix package manager: https://nixos.org/nix -.. _cmake: https://cmake.org/ - -Development ------------ - -In order to develop the library, you will need to compile and run the -examples, tests and benchmarks. These require some additional tools. -The easiest way to install them is by using the `Nix package -manager`_. At the root of the repository just type:: - - nix-shell - -This will download all required dependencies and create an isolated -environment in which you can use these dependencies, without polluting -your system. - -Then you can proceed to generate a development project using `CMake`_:: - - mkdir build && cd build - cmake .. - -From then on, one may build and run all tests by doing:: - - make check - -In order to build and run all benchmarks when running ``make check``, -run ``cmake`` again with the option ``-DCHECK_BENCHMARKS=1``. The -results of running the benchmarks will be saved to a folder -``reports/`` in the project root. - -License -------- - -**This software is licensed under the Boost Software License 1.0**. - -.. image:: https://upload.wikimedia.org/wikipedia/commons/c/cd/Boost.png - :alt: Boost logo - :target: http://boost.org/LICENSE_1_0.txt - :align: right - -The full text of the license is can be accessed `via this link -<http://boost.org/LICENSE_1_0.txt>`_ and is also included -in the ``LICENSE`` file of this software package. diff --git a/third_party/immer/WORKSPACE b/third_party/immer/WORKSPACE deleted file mode 100644 index e69de29bb2d1..000000000000 --- a/third_party/immer/WORKSPACE +++ /dev/null diff --git a/third_party/immer/benchmark/CMakeLists.txt b/third_party/immer/benchmark/CMakeLists.txt deleted file mode 100644 index 0f9061aa3cd3..000000000000 --- a/third_party/immer/benchmark/CMakeLists.txt +++ /dev/null @@ -1,128 +0,0 @@ - -# Config -# ====== - -option(CHECK_BENCHMARKS "Run benchmarks on check target" off) -option(BENCHMARK_DISABLE_GC "Disable gc during a measurement") - -set(BENCHMARK_PARAM "N:1000" CACHE STRING "Benchmark parameters") -set(BENCHMARK_SAMPLES "20" CACHE STRING "Benchmark samples") - -# Dependencies -# ============ - -find_package(RRB) - -if (NOT RRB_FOUND) - message(STATUS "Disabling benchmarks") - return() -endif() - -# These are expected to be in the include path, the nix-shell -# environment installs them: -# -# https://github.com/marcusz/steady -# https://github.com/deepsea-inria/chunkedseq.git -# https://github.com/rsms/immutable-cpp.git - -# Targets -# ======= - -add_custom_target(benchmarks - COMMENT "Build all benchmarks.") - -execute_process( - COMMAND git log -1 --format=%h - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE immer_git_commit_hash - OUTPUT_STRIP_TRAILING_WHITESPACE) - -execute_process( - COMMAND git status --porcelain - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE immer_git_status - OUTPUT_STRIP_TRAILING_WHITESPACE) - -if (NOT immer_git_status STREQUAL "") - set(immer_git_commit_hash "${immer_git_commit_hash}+") -endif() - -site_name(immer_hostname) - -get_filename_component(immer_compiler_name "${CMAKE_CXX_COMPILER}" NAME) - -set(immer_benchmark_report_base_dir "${CMAKE_SOURCE_DIR}/reports") -set(immer_benchmark_report_dir "${immer_benchmark_report_base_dir}/report_\ -${immer_git_commit_hash}_\ -${immer_hostname}_\ -${immer_compiler_name}_\ -${BENCHMARK_PARAM}_\ -s${BENCHMARK_SAMPLES}") - -if(DISABLE_FREE_LIST) - set(immer_benchmark_report_dir "${immer_benchmark_report_dir}_nofl") -endif() - -if(DISABLE_THREAD_SAFETY) - set(immer_benchmark_report_dir "${immer_benchmark_report_dir}_nots") -endif() - -if(BENCHMARK_DISABLE_GC) - set(immer_benchmark_report_dir "${immer_benchmark_report_dir}_nogc") -endif() - -if(CHECK_BENCHMARKS) - add_dependencies(check benchmarks) -endif() - -add_custom_target(benchmark-report-dir - COMMAND ${CMAKE_COMMAND} - -E make_directory ${immer_benchmark_report_dir}) - -file(GLOB_RECURSE immer_benchmarks "*.cpp") -foreach(_file IN LISTS immer_benchmarks) - immer_target_name_for(_target _output "${_file}") - add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") - set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) - add_dependencies(benchmarks ${_target}) - add_dependencies(${_target} benchmark-report-dir) - target_compile_options(${_target} PUBLIC -Wno-unused-function) - target_compile_definitions(${_target} PUBLIC - NONIUS_RUNNER - IMMER_BENCHMARK_LIBRRB=1 - IMMER_BENCHMARK_STEADY=1 - IMMER_BENCHMARK_EXPERIMENTAL=0 - IMMER_BENCHMARK_DISABLE_GC=${BENCHMARK_DISABLE_GC} - IMMER_BENCHMARK_BOOST_COROUTINE=${ENABLE_BOOST_COROUTINE}) - target_link_libraries(${_target} PUBLIC - immer-dev - ${RRB_LIBRARIES}) - target_include_directories(${_target} SYSTEM PUBLIC - ${RRB_INCLUDE_DIR}) - if(CHECK_BENCHMARKS) - add_test("benchmark/${_output}" "${CMAKE_SOURCE_DIR}/tools/with-tee.bash" - ${immer_benchmark_report_dir}/${_target}.out - "${CMAKE_CURRENT_BINARY_DIR}/${_output}" -v - -t ${_target} - -r html - -s ${BENCHMARK_SAMPLES} - -p ${BENCHMARK_PARAM} - -o ${immer_benchmark_report_dir}/${_target}.html) - endif() -endforeach() - -set(immer_ssh_method - ssh -p 5488 - -o StrictHostKeyChecking=no - -i ${CMAKE_SOURCE_DIR}/tools/travis/ssh-key) - -add_custom_target(upload-benchmark-reports - COMMAND - rsync -av -e \"${immer_ssh_method}\" - ${immer_benchmark_report_base_dir} - raskolnikov@sinusoid.es:public/misc/immer/) - -add_custom_target(copy-benchmark-reports - COMMAND - rsync -av ${immer_benchmark_report_base_dir} - ~/public/misc/immer/) diff --git a/third_party/immer/benchmark/config.hpp b/third_party/immer/benchmark/config.hpp deleted file mode 100644 index c32ef5812ff8..000000000000 --- a/third_party/immer/benchmark/config.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <nonius.h++> - -#include <immer/heap/gc_heap.hpp> -#include <immer/memory_policy.hpp> - -namespace { - -NONIUS_PARAM(N, std::size_t{1000}) - -struct gc_disable -{ - gc_disable() - { -#if IMMER_BENCHMARK_DISABLE_GC - GC_disable(); -#else - GC_gcollect(); -#endif - } - ~gc_disable() - { -#if IMMER_BENCHMARK_DISABLE_GC - GC_enable(); - GC_gcollect(); -#endif - } - gc_disable(const gc_disable&) = delete; - gc_disable(gc_disable&&) = delete; -}; - -template <typename Meter, typename Fn> -void measure(Meter& m, Fn&& fn) -{ - gc_disable guard; - return m.measure(std::forward<Fn>(fn)); -} - -using def_memory = immer::default_memory_policy; -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy>; -using gcf_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, immer::no_refcount_policy, immer::gc_transience_policy, false>; -using basic_memory = immer::memory_policy<immer::heap_policy<immer::cpp_heap>, immer::refcount_policy>; -using safe_memory = immer::memory_policy<immer::free_list_heap_policy<immer::cpp_heap>, immer::refcount_policy>; -using unsafe_memory = immer::memory_policy<immer::unsafe_free_list_heap_policy<immer::cpp_heap>, immer::unsafe_refcount_policy>; - -} // anonymous namespace diff --git a/third_party/immer/benchmark/extra/refcounting.cpp b/third_party/immer/benchmark/extra/refcounting.cpp deleted file mode 100644 index c7c5183e6264..000000000000 --- a/third_party/immer/benchmark/extra/refcounting.cpp +++ /dev/null @@ -1,146 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/detail/ref_count_base.hpp> - -#include <nonius.h++> -#include <boost/intrusive_ptr.hpp> - -#include <atomic> -#include <cstdlib> -#include <iterator> -#include <memory> -#include <utility> -#include <array> -#include <vector> - -NONIUS_PARAM(N, std::size_t{1000}) - -constexpr auto benchmark_size = 32u; - -struct object_t : immer::detail::ref_count_base<object_t> -{}; - -auto make_data() -{ - auto objs = std::array<std::unique_ptr<object_t>, benchmark_size>(); - std::generate(objs.begin(), objs.end(), [] { - return std::make_unique<object_t>(); - }); - auto refs = std::array<object_t*, benchmark_size>(); - std::transform(objs.begin(), objs.end(), refs.begin(), [](auto& obj) { - return obj.get(); - }); - return make_pair(std::move(objs), - std::move(refs)); -} - -NONIUS_BENCHMARK("intrusive_ptr", [] (nonius::chronometer meter) -{ - auto arr = std::array<boost::intrusive_ptr<object_t>, benchmark_size>{}; - auto storage = std::vector< - nonius::storage_for< - std::array<boost::intrusive_ptr<object_t>, benchmark_size>>> ( - meter.runs()); - std::generate(arr.begin(), arr.end(), [] { - return new object_t{}; - }); - meter.measure([&] (int i) { - storage[i].construct(arr); - }); -}) - -NONIUS_BENCHMARK("generic", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - std::transform(refs.begin(), refs.end(), r, [] (auto& p) { - if (p) p->ref_count.fetch_add(1, std::memory_order_relaxed); - return p; - }); - return r; - }); -}) - -NONIUS_BENCHMARK("manual", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - for (auto& p : refs) - if (p) p->ref_count.fetch_add(1, std::memory_order_relaxed); - std::copy(refs.begin(), refs.end(), r); - return r; - }); -}) - -NONIUS_BENCHMARK("manual - unroll", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - auto e = refs.end(); - for (auto p = refs.begin(); p != e;) { - (*p++)->ref_count.fetch_add(1, std::memory_order_relaxed); - (*p++)->ref_count.fetch_add(1, std::memory_order_relaxed); - (*p++)->ref_count.fetch_add(1, std::memory_order_relaxed); - (*p++)->ref_count.fetch_add(1, std::memory_order_relaxed); - } - std::copy(refs.begin(), refs.end(), r); - return r; - }); -}) - -NONIUS_BENCHMARK("manual - nocheck", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - for (auto& p : refs) - p->ref_count.fetch_add(1, std::memory_order_relaxed); - std::copy(refs.begin(), refs.end(), r); - return r; - }); -}) - -NONIUS_BENCHMARK("manual - constant", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - for (auto i = 0u; i < benchmark_size; ++i) - refs[i]->ref_count.fetch_add(1, std::memory_order_relaxed); - std::copy(refs.begin(), refs.end(), r); - return r; - }); -}) - -NONIUS_BENCHMARK("manual - memcopy", [] (nonius::chronometer meter) -{ - auto data = make_data(); - auto& refs = data.second; - object_t* r[benchmark_size]; - - meter.measure([&] { - for (auto& p : refs) - if (p) p->ref_count.fetch_add(1, std::memory_order_relaxed); - std::memcpy(r, &refs[0], sizeof(object_t*) * benchmark_size); - return r; - }); -}) diff --git a/third_party/immer/benchmark/set/access.hpp b/third_party/immer/benchmark/set/access.hpp deleted file mode 100644 index 8605c0ff453c..000000000000 --- a/third_party/immer/benchmark/set/access.hpp +++ /dev/null @@ -1,175 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/config.hpp" - -#include <immer/set.hpp> -#include <hash_trie.hpp> // Phil Nash -#include <boost/container/flat_set.hpp> -#include <set> -#include <unordered_set> - -namespace { - -template <typename T=unsigned> -auto make_generator_ranged(std::size_t runs) -{ - assert(runs > 0); - auto engine = std::default_random_engine{13}; - auto dist = std::uniform_int_distribution<T>{0, (T)runs-1}; - auto r = std::vector<T>(runs); - std::generate_n(r.begin(), runs, std::bind(dist, engine)); - return r; -} - -template <typename Generator, typename Set> -auto benchmark_access_std() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g1 = Generator{}(n); - auto g2 = make_generator_ranged(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) - c += v.count(g1[g2[i]]); - volatile auto r = c; - return r; - }); - }; -} - -template <typename Generator, typename Set> -auto benchmark_access_hamt() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g1 = Generator{}(n); - auto g2 = make_generator_ranged(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) { - auto& x = g1[g2[i]]; - auto leaf = v.find(x).leaf(); - c += !!(leaf && leaf->find(x)); - } - volatile auto r = c; - return r; - }); - }; -} - - -template <typename Generator, typename Set> -auto benchmark_access() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g1 = Generator{}(n); - auto g2 = make_generator_ranged(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) - c += v.count(g1[g2[i]]); - volatile auto r = c; - return r; - }); - }; -} - -template <typename Generator, typename Set> -auto benchmark_bad_access_std() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g1 = Generator{}(n*2); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) - c += v.count(g1[n+i]); - volatile auto r = c; - return r; - }); - }; -} - -template <typename Generator, typename Set> -auto benchmark_bad_access_hamt() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g1 = Generator{}(n*2); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) { - auto& x = g1[n+i]; - auto leaf = v.find(x).leaf(); - c += !!(leaf && leaf->find(x)); - } - volatile auto r = c; - return r; - }); - }; -} - - -template <typename Generator, typename Set> -auto benchmark_bad_access() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g1 = Generator{}(n*2); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g1[i]); - - measure(meter, [&] { - auto c = 0u; - for (auto i = 0u; i < n; ++i) - c += v.count(g1[n+i]); - volatile auto r = c; - return r; - }); - }; -} - -} // namespace diff --git a/third_party/immer/benchmark/set/access.ipp b/third_party/immer/benchmark/set/access.ipp deleted file mode 100644 index f026d9cfa736..000000000000 --- a/third_party/immer/benchmark/set/access.ipp +++ /dev/null @@ -1,30 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "access.hpp" - -#ifndef GENERATOR_T -#error "you must define a GENERATOR_T" -#endif - -using generator__ = GENERATOR_T; -using t__ = typename decltype(generator__{}(0))::value_type; - -NONIUS_BENCHMARK("std::set", benchmark_access_std<generator__, std::set<t__>>()) -NONIUS_BENCHMARK("std::unordered_set", benchmark_access_std<generator__, std::unordered_set<t__>>()) -NONIUS_BENCHMARK("boost::flat_set", benchmark_access_std<generator__, boost::container::flat_set<t__>>()) -NONIUS_BENCHMARK("hamt::hash_trie", benchmark_access_hamt<generator__, hamt::hash_trie<t__>>()) -NONIUS_BENCHMARK("immer::set/5B", benchmark_access<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,5>>()) -NONIUS_BENCHMARK("immer::set/4B", benchmark_access<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,4>>()) - -NONIUS_BENCHMARK("bad/std::set", benchmark_bad_access_std<generator__, std::set<t__>>()) -NONIUS_BENCHMARK("bad/std::unordered_set", benchmark_bad_access_std<generator__, std::unordered_set<t__>>()) -NONIUS_BENCHMARK("bad/boost::flat_set", benchmark_bad_access_std<generator__, boost::container::flat_set<t__>>()) -NONIUS_BENCHMARK("bad/hamt::hash_trie", benchmark_bad_access_hamt<generator__, hamt::hash_trie<t__>>()) -NONIUS_BENCHMARK("bad/immer::set/5B", benchmark_bad_access<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,5>>()) -NONIUS_BENCHMARK("bad/immer::set/4B", benchmark_bad_access<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,4>>()) diff --git a/third_party/immer/benchmark/set/insert.hpp b/third_party/immer/benchmark/set/insert.hpp deleted file mode 100644 index be679b4de342..000000000000 --- a/third_party/immer/benchmark/set/insert.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/config.hpp" - -#include <immer/set.hpp> -#include <hash_trie.hpp> // Phil Nash -#include <boost/container/flat_set.hpp> -#include <set> -#include <unordered_set> - -namespace { - -template <typename Generator, typename Set> -auto benchmark_insert_mut_std() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g = Generator{}(n); - - measure(meter, [&] { - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g[i]); - return v; - }); - }; -} - -template <typename Generator, typename Set> -auto benchmark_insert() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g = Generator{}(n); - - measure(meter, [&] { - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g[i]); - return v; - }); - }; -} - -} // namespace diff --git a/third_party/immer/benchmark/set/insert.ipp b/third_party/immer/benchmark/set/insert.ipp deleted file mode 100644 index 6717ccd57ea7..000000000000 --- a/third_party/immer/benchmark/set/insert.ipp +++ /dev/null @@ -1,28 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "insert.hpp" - -#ifndef GENERATOR_T -#error "you must define a GENERATOR_T" -#endif - -using generator__ = GENERATOR_T; -using t__ = typename decltype(generator__{}(0))::value_type; - -NONIUS_BENCHMARK("std::set", benchmark_insert_mut_std<generator__, std::set<t__>>()) -NONIUS_BENCHMARK("std::unordered_set", benchmark_insert_mut_std<generator__, std::unordered_set<t__>>()) -NONIUS_BENCHMARK("boost::flat_set", benchmark_insert_mut_std<generator__, boost::container::flat_set<t__>>()) -NONIUS_BENCHMARK("hamt::hash_trie", benchmark_insert_mut_std<generator__, hamt::hash_trie<t__>>()) - -NONIUS_BENCHMARK("immer::set/5B", benchmark_insert<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,5>>()) -NONIUS_BENCHMARK("immer::set/4B", benchmark_insert<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,4>>()) -#ifndef DISABLE_GC_BENCHMARKS -NONIUS_BENCHMARK("immer::set/GC", benchmark_insert<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,gc_memory,5>>()) -#endif -NONIUS_BENCHMARK("immer::set/UN", benchmark_insert<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,unsafe_memory,5>>()) diff --git a/third_party/immer/benchmark/set/iter.hpp b/third_party/immer/benchmark/set/iter.hpp deleted file mode 100644 index 91dd48644367..000000000000 --- a/third_party/immer/benchmark/set/iter.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/config.hpp" - -#include <immer/set.hpp> -#include <immer/box.hpp> -#include <immer/algorithm.hpp> -#include <hash_trie.hpp> // Phil Nash -#include <boost/container/flat_set.hpp> -#include <set> -#include <unordered_set> -#include <numeric> - -namespace { - -template <typename T> -struct iter_step -{ - unsigned operator() (unsigned x, const T& y) const - { - return x + y; - } -}; - -template <> -struct iter_step<std::string> -{ - unsigned operator() (unsigned x, const std::string& y) const - { - return x + (unsigned) y.size(); - } -}; - -template <> -struct iter_step<immer::box<std::string>> -{ - unsigned operator() (unsigned x, const immer::box<std::string>& y) const - { - return x + (unsigned) y->size(); - } -}; - -template <typename Generator, typename Set> -auto benchmark_access_std_iter() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g1 = Generator{}(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v.insert(g1[i]); - - using step_t = iter_step<typename decltype(g1)::value_type>; - measure(meter, [&] { - volatile auto c = std::accumulate(v.begin(), v.end(), 0u, step_t{}); - return c; - }); - }; -} - -template <typename Generator, typename Set> -auto benchmark_access_reduce() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g1 = Generator{}(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g1[i]); - - using step_t = iter_step<typename decltype(g1)::value_type>; - measure(meter, [&] { - volatile auto c = immer::accumulate(v, 0u, step_t{}); - return c; - }); - }; -} - -template <typename Generator, typename Set> -auto benchmark_access_iter() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g1 = Generator{}(n); - - auto v = Set{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(g1[i]); - - using step_t = iter_step<typename decltype(g1)::value_type>; - measure(meter, [&] { - volatile auto c = std::accumulate(v.begin(), v.end(), 0u, step_t{}); - return c; - }); - }; -} - -} // namespace diff --git a/third_party/immer/benchmark/set/iter.ipp b/third_party/immer/benchmark/set/iter.ipp deleted file mode 100644 index f8c3cb9695cd..000000000000 --- a/third_party/immer/benchmark/set/iter.ipp +++ /dev/null @@ -1,25 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "iter.hpp" - -#ifndef GENERATOR_T -#error "you must define a GENERATOR_T" -#endif - -using generator__ = GENERATOR_T; -using t__ = typename decltype(generator__{}(0))::value_type; - -NONIUS_BENCHMARK("iter/std::set", benchmark_access_std_iter<generator__, std::set<t__>>()) -NONIUS_BENCHMARK("iter/std::unordered_set", benchmark_access_std_iter<generator__, std::unordered_set<t__>>()) -NONIUS_BENCHMARK("iter/boost::flat_set", benchmark_access_std_iter<generator__, boost::container::flat_set<t__>>()) -NONIUS_BENCHMARK("iter/hamt::hash_trie", benchmark_access_std_iter<generator__, hamt::hash_trie<t__>>()) -NONIUS_BENCHMARK("iter/immer::set/5B", benchmark_access_iter<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,5>>()) -NONIUS_BENCHMARK("iter/immer::set/4B", benchmark_access_iter<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,4>>()) -NONIUS_BENCHMARK("reduce/immer::set/5B", benchmark_access_reduce<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,5>>()) -NONIUS_BENCHMARK("reduce/immer::set/4B", benchmark_access_reduce<generator__, immer::set<t__, std::hash<t__>,std::equal_to<t__>,def_memory,4>>()) diff --git a/third_party/immer/benchmark/set/string-box/access.cpp b/third_party/immer/benchmark/set/string-box/access.cpp deleted file mode 100644 index c3deffbb0636..000000000000 --- a/third_party/immer/benchmark/set/string-box/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../access.ipp" diff --git a/third_party/immer/benchmark/set/string-box/generator.ipp b/third_party/immer/benchmark/set/string-box/generator.ipp deleted file mode 100644 index 9adc82e0bdc0..000000000000 --- a/third_party/immer/benchmark/set/string-box/generator.ipp +++ /dev/null @@ -1,46 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/box.hpp> - -#include <random> -#include <vector> -#include <cassert> -#include <functional> -#include <algorithm> - -#define GENERATOR_T generate_unsigned - -namespace { - -struct GENERATOR_T -{ - static constexpr auto char_set = "_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - static constexpr auto max_length = 64; - static constexpr auto min_length = 8; - - auto operator() (std::size_t runs) const - { - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution<unsigned>{}; - auto gen = std::bind(dist, engine); - auto r = std::vector<immer::box<std::string>>(runs); - std::generate_n(r.begin(), runs, [&] { - auto len = gen() % (max_length - min_length) + min_length; - auto str = std::string(len, ' '); - std::generate_n(str.begin(), len, [&] { - return char_set[gen() % sizeof(char_set)]; - }); - return str; - }); - return r; - } -}; - -} // namespace diff --git a/third_party/immer/benchmark/set/string-box/insert.cpp b/third_party/immer/benchmark/set/string-box/insert.cpp deleted file mode 100644 index c5762498c23c..000000000000 --- a/third_party/immer/benchmark/set/string-box/insert.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define DISABLE_GC_BENCHMARKS -#include "generator.ipp" -#include "../insert.ipp" diff --git a/third_party/immer/benchmark/set/string-box/iter.cpp b/third_party/immer/benchmark/set/string-box/iter.cpp deleted file mode 100644 index 83e57e7845d3..000000000000 --- a/third_party/immer/benchmark/set/string-box/iter.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../iter.ipp" diff --git a/third_party/immer/benchmark/set/string-long/access.cpp b/third_party/immer/benchmark/set/string-long/access.cpp deleted file mode 100644 index c3deffbb0636..000000000000 --- a/third_party/immer/benchmark/set/string-long/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../access.ipp" diff --git a/third_party/immer/benchmark/set/string-long/generator.ipp b/third_party/immer/benchmark/set/string-long/generator.ipp deleted file mode 100644 index 386364cc96fe..000000000000 --- a/third_party/immer/benchmark/set/string-long/generator.ipp +++ /dev/null @@ -1,44 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <random> -#include <vector> -#include <cassert> -#include <functional> -#include <algorithm> - -#define GENERATOR_T generate_unsigned - -namespace { - -struct GENERATOR_T -{ - static constexpr auto char_set = "_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - static constexpr auto max_length = 256; - static constexpr auto min_length = 32; - - auto operator() (std::size_t runs) const - { - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution<unsigned>{}; - auto gen = std::bind(dist, engine); - auto r = std::vector<std::string>(runs); - std::generate_n(r.begin(), runs, [&] { - auto len = gen() % (max_length - min_length) + min_length; - auto str = std::string(len, ' '); - std::generate_n(str.begin(), len, [&] { - return char_set[gen() % sizeof(char_set)]; - }); - return str; - }); - return r; - } -}; - -} // namespace diff --git a/third_party/immer/benchmark/set/string-long/insert.cpp b/third_party/immer/benchmark/set/string-long/insert.cpp deleted file mode 100644 index c5762498c23c..000000000000 --- a/third_party/immer/benchmark/set/string-long/insert.cpp +++ /dev/null @@ -1,11 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define DISABLE_GC_BENCHMARKS -#include "generator.ipp" -#include "../insert.ipp" diff --git a/third_party/immer/benchmark/set/string-long/iter.cpp b/third_party/immer/benchmark/set/string-long/iter.cpp deleted file mode 100644 index 83e57e7845d3..000000000000 --- a/third_party/immer/benchmark/set/string-long/iter.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../iter.ipp" diff --git a/third_party/immer/benchmark/set/string-short/access.cpp b/third_party/immer/benchmark/set/string-short/access.cpp deleted file mode 100644 index c3deffbb0636..000000000000 --- a/third_party/immer/benchmark/set/string-short/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../access.ipp" diff --git a/third_party/immer/benchmark/set/string-short/generator.ipp b/third_party/immer/benchmark/set/string-short/generator.ipp deleted file mode 100644 index bd40d2d639a8..000000000000 --- a/third_party/immer/benchmark/set/string-short/generator.ipp +++ /dev/null @@ -1,44 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <random> -#include <vector> -#include <cassert> -#include <functional> -#include <algorithm> - -#define GENERATOR_T generate_unsigned - -namespace { - -struct GENERATOR_T -{ - static constexpr auto char_set = "_-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - static constexpr auto max_length = 15; - static constexpr auto min_length = 4; - - auto operator() (std::size_t runs) const - { - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution<unsigned>{}; - auto gen = std::bind(dist, engine); - auto r = std::vector<std::string>(runs); - std::generate_n(r.begin(), runs, [&] { - auto len = gen() % (max_length - min_length) + min_length; - auto str = std::string(len, ' '); - std::generate_n(str.begin(), len, [&] { - return char_set[gen() % sizeof(char_set)]; - }); - return str; - }); - return r; - } -}; - -} // namespace diff --git a/third_party/immer/benchmark/set/string-short/insert.cpp b/third_party/immer/benchmark/set/string-short/insert.cpp deleted file mode 100644 index 26dfbce29204..000000000000 --- a/third_party/immer/benchmark/set/string-short/insert.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../insert.ipp" diff --git a/third_party/immer/benchmark/set/string-short/iter.cpp b/third_party/immer/benchmark/set/string-short/iter.cpp deleted file mode 100644 index 83e57e7845d3..000000000000 --- a/third_party/immer/benchmark/set/string-short/iter.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../iter.ipp" diff --git a/third_party/immer/benchmark/set/unsigned/access.cpp b/third_party/immer/benchmark/set/unsigned/access.cpp deleted file mode 100644 index c3deffbb0636..000000000000 --- a/third_party/immer/benchmark/set/unsigned/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../access.ipp" diff --git a/third_party/immer/benchmark/set/unsigned/generator.ipp b/third_party/immer/benchmark/set/unsigned/generator.ipp deleted file mode 100644 index 2a2a2a0fb627..000000000000 --- a/third_party/immer/benchmark/set/unsigned/generator.ipp +++ /dev/null @@ -1,32 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <random> -#include <vector> -#include <cassert> -#include <functional> -#include <algorithm> - -#define GENERATOR_T generate_unsigned - -namespace { - -struct GENERATOR_T -{ - auto operator() (std::size_t runs) const - { - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution<unsigned>{}; - auto r = std::vector<unsigned>(runs); - std::generate_n(r.begin(), runs, std::bind(dist, engine)); - return r; - } -}; - -} // namespace diff --git a/third_party/immer/benchmark/set/unsigned/insert.cpp b/third_party/immer/benchmark/set/unsigned/insert.cpp deleted file mode 100644 index 26dfbce29204..000000000000 --- a/third_party/immer/benchmark/set/unsigned/insert.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../insert.ipp" diff --git a/third_party/immer/benchmark/set/unsigned/iter.cpp b/third_party/immer/benchmark/set/unsigned/iter.cpp deleted file mode 100644 index 83e57e7845d3..000000000000 --- a/third_party/immer/benchmark/set/unsigned/iter.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "generator.ipp" -#include "../iter.ipp" diff --git a/third_party/immer/benchmark/vector/access.hpp b/third_party/immer/benchmark/vector/access.hpp deleted file mode 100644 index 4dff7a667f33..000000000000 --- a/third_party/immer/benchmark/vector/access.hpp +++ /dev/null @@ -1,261 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -#include <immer/algorithm.hpp> - -#if IMMER_BENCHMARK_BOOST_COROUTINE -#include <boost/coroutine2/all.hpp> -#endif - -namespace { - -template <typename Vektor> -auto benchmark_access_reduce_chunkedseq() -{ - return [] (nonius::parameters params) - { - auto n = params.get<N>(); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return [=] { - auto init = 0u; - v.for_each_segment([&] (auto first, auto last) { - init = std::accumulate(first, last, init); - }); - return init; - }; - }; -} - -template <typename Vektor> -auto benchmark_access_iter_std() -{ - return [] (nonius::parameters params) - { - auto n = params.get<N>(); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return [=] { - auto volatile x = std::accumulate(v.begin(), v.end(), 0u); - return x; - }; - }; -} - -template <typename Vektor> -auto benchmark_access_idx_std() -{ - return [] (nonius::parameters params) - { - auto n = params.get<N>(); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += v[i]; - volatile auto rr = r; - return rr; - }; - }; -} - -template <typename Vektor> -auto benchmark_access_random_std() -{ - return [] (nonius::parameters params) - { - auto n = params.get<N>(); - auto v = Vektor{}; - auto g = make_generator(n); - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += v[g[i]]; - volatile auto rr = r; - return rr; - }; - }; -} - -template <typename Vektor, typename PushFn=push_back_fn> -auto benchmark_access_iter() -{ - return [] (nonius::parameters params) - { - auto n = params.get<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto volatile x = std::accumulate(v.begin(), v.end(), 0u); - return x; - }; - }; -} - -#if IMMER_BENCHMARK_BOOST_COROUTINE -template <typename Vektor, typename PushFn=push_back_fn> -auto benchmark_access_coro() -{ - return [] (nonius::parameters params) - { - using coro_t = typename boost::coroutines2::coroutine<int>; - - auto n = params.get<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto c = coro_t::pull_type { [&](auto& sink) { - v.for_each_chunk([&](auto f, auto l) { - for (; f != l; ++f) - sink(*f); - }); - }}; - auto volatile x = std::accumulate(begin(c), end(c), 0u); - return x; - }; - }; -} -#endif - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_access_idx() -{ - return [] (nonius::parameters params) - { - auto n = params.get<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += v[i]; - volatile auto rr = r; - return rr; - }; - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_access_reduce() -{ - return [] (nonius::parameters params) - { - auto n = params.get<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto volatile x = immer::accumulate(v, 0u); - return x; - }; - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_access_reduce_range() -{ - return [] (nonius::parameters params) - { - auto n = params.get<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - return [=] { - auto volatile x = immer::accumulate(v.begin(), v.end(), 0u); - return x; - }; - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_access_random() -{ - return [] (nonius::parameters params) - { - auto n = params.get<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - auto g = make_generator(n); - - return [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += v[g[i]]; - volatile auto rr = r; - return rr; - }; - }; -} - -template <typename Fn> -auto benchmark_access_librrb(Fn maker) -{ - return - [=] (nonius::parameters params) { - auto n = params.get<N>(); - auto v = maker(n); - return - [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += reinterpret_cast<unsigned long>(rrb_nth(v, i)); - volatile auto rr = r; - return rr; - }; - }; -} - -template <typename Fn> -auto benchmark_access_random_librrb(Fn maker) -{ - return - [=] (nonius::parameters params) { - auto n = params.get<N>(); - auto v = maker(n); - auto g = make_generator(n); - return - [=] { - auto r = 0u; - for (auto i = 0u; i < n; ++i) - r += reinterpret_cast<unsigned long>(rrb_nth(v, g[i])); - volatile auto rr = r; - return rr; - }; - }; -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/assoc.hpp b/third_party/immer/benchmark/vector/assoc.hpp deleted file mode 100644 index 5619d7ee6936..000000000000 --- a/third_party/immer/benchmark/vector/assoc.hpp +++ /dev/null @@ -1,245 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template <typename Vektor> -auto benchmark_assoc_std() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto v = Vektor(n, 0); - std::iota(v.begin(), v.end(), 0u); - auto all = std::vector<Vektor>(meter.runs(), v); - meter.measure([&] (int iter) { - auto& r = all[iter]; - for (auto i = 0u; i < n; ++i) - r[i] = n - i; - return r; - }); - }; -} - -template <typename Vektor> -auto benchmark_assoc_random_std() -{ - return - [](nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto g = make_generator(n); - auto v = Vektor(n, 0); - std::iota(v.begin(), v.end(), 0u); - auto all = std::vector<Vektor>(meter.runs(), v); - meter.measure([&] (int iter) { - auto& r = all[iter]; - for (auto i = 0u; i < n; ++i) - r[g[i]] = n - i; - return r; - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn, - typename SetFn=set_fn> -auto benchmark_assoc() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - if (n > get_limit<Vektor>{}) - nonius::skip(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = SetFn{}(r, i, n - i); - return r; - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_assoc_move() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - if (n > get_limit<Vektor>{}) - nonius::skip(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = std::move(r).set(i, n - i); - return r; - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn, - typename SetFn=set_fn> -auto benchmark_assoc_random() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - if (n > get_limit<Vektor>{}) - nonius::skip(); - - auto g = make_generator(n); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = SetFn{}(r, g[i], i); - return r; - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_assoc_mut() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - if (n > get_limit<Vektor>{}) - nonius::skip(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v.transient(); - for (auto i = 0u; i < n; ++i) - r.set(i, n - i); - return r; - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_assoc_mut_random() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - if (n > get_limit<Vektor>{}) - nonius::skip(); - - auto g = make_generator(n); - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v.transient(); - for (auto i = 0u; i < n; ++i) - r.set(g[i], i); - return r; - }); - }; -} - -template <typename Fn> -auto benchmark_assoc_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param<N>(); - auto v = maker(n); - measure( - meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = rrb_update(r, i, reinterpret_cast<void*>(n - i)); - return r; - }); - }; -} - -template <typename Fn> -auto benchmark_assoc_random_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param<N>(); - auto v = maker(n); - auto g = make_generator(n); - measure( - meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = rrb_update(r, g[i], reinterpret_cast<void*>(i)); - return r; - }); - }; -} - -template <typename Fn> -auto benchmark_assoc_mut_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param<N>(); - auto v = maker(n); - measure( - meter, [&] { - auto r = rrb_to_transient(v); - for (auto i = 0u; i < n; ++i) - r = transient_rrb_update( - r, i, reinterpret_cast<void*>(i)); - return r; - }); - }; -} - -template <typename Fn> -auto benchmark_assoc_mut_random_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param<N>(); - auto v = maker(n); - auto g = make_generator(n); - measure( - meter, [&] { - auto r = rrb_to_transient(v); - for (auto i = 0u; i < n; ++i) - r = transient_rrb_update( - r, g[i], reinterpret_cast<void*>(i)); - return r; - }); - }; -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/branching/access.ipp b/third_party/immer/benchmark/vector/branching/access.ipp deleted file mode 100644 index bd7f985d4df0..000000000000 --- a/third_party/immer/benchmark/vector/branching/access.ipp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/access.hpp" -#include <immer/flex_vector.hpp> - -#ifndef MEMORY_T -#error "define the MEMORY_T" -#endif - -NONIUS_BENCHMARK("flex/3", benchmark_access_idx<immer::flex_vector<std::size_t,MEMORY_T,3>>()) -NONIUS_BENCHMARK("flex/4", benchmark_access_idx<immer::flex_vector<std::size_t,MEMORY_T,4>>()) -NONIUS_BENCHMARK("flex/5", benchmark_access_idx<immer::flex_vector<std::size_t,MEMORY_T,5>>()) -NONIUS_BENCHMARK("flex/6", benchmark_access_idx<immer::flex_vector<std::size_t,MEMORY_T,6>>()) -NONIUS_BENCHMARK("flex/7", benchmark_access_idx<immer::flex_vector<std::size_t,MEMORY_T,7>>()) diff --git a/third_party/immer/benchmark/vector/branching/assoc.ipp b/third_party/immer/benchmark/vector/branching/assoc.ipp deleted file mode 100644 index 4aa9984f9275..000000000000 --- a/third_party/immer/benchmark/vector/branching/assoc.ipp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/assoc.hpp" -#include <immer/flex_vector.hpp> - -#ifndef MEMORY_T -#error "define the MEMORY_T" -#endif - -NONIUS_BENCHMARK("flex/3", benchmark_assoc<immer::flex_vector<std::size_t,MEMORY_T,3>>()) -NONIUS_BENCHMARK("flex/4", benchmark_assoc<immer::flex_vector<std::size_t,MEMORY_T,4>>()) -NONIUS_BENCHMARK("flex/5", benchmark_assoc<immer::flex_vector<std::size_t,MEMORY_T,5>>()) -NONIUS_BENCHMARK("flex/6", benchmark_assoc<immer::flex_vector<std::size_t,MEMORY_T,6>>()) -NONIUS_BENCHMARK("flex/7", benchmark_assoc<immer::flex_vector<std::size_t,MEMORY_T,7>>()) diff --git a/third_party/immer/benchmark/vector/branching/basic/access.cpp b/third_party/immer/benchmark/vector/branching/basic/access.cpp deleted file mode 100644 index 23eb25565da0..000000000000 --- a/third_party/immer/benchmark/vector/branching/basic/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T basic_memory -#include "../access.ipp" diff --git a/third_party/immer/benchmark/vector/branching/basic/assoc.cpp b/third_party/immer/benchmark/vector/branching/basic/assoc.cpp deleted file mode 100644 index 210a432abab2..000000000000 --- a/third_party/immer/benchmark/vector/branching/basic/assoc.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T basic_memory -#include "../assoc.ipp" diff --git a/third_party/immer/benchmark/vector/branching/basic/concat.cpp b/third_party/immer/benchmark/vector/branching/basic/concat.cpp deleted file mode 100644 index 21163bdc0b94..000000000000 --- a/third_party/immer/benchmark/vector/branching/basic/concat.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T basic_memory -#include "../concat.ipp" diff --git a/third_party/immer/benchmark/vector/branching/basic/push.cpp b/third_party/immer/benchmark/vector/branching/basic/push.cpp deleted file mode 100644 index 6be28f9219f5..000000000000 --- a/third_party/immer/benchmark/vector/branching/basic/push.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T basic_memory -#include "../push.ipp" diff --git a/third_party/immer/benchmark/vector/branching/concat.ipp b/third_party/immer/benchmark/vector/branching/concat.ipp deleted file mode 100644 index 0e21ca0b111f..000000000000 --- a/third_party/immer/benchmark/vector/branching/concat.ipp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/concat.hpp" -#include <immer/flex_vector.hpp> - -#ifndef MEMORY_T -#error "define the MEMORY_T" -#endif - -NONIUS_BENCHMARK("flex/3", benchmark_concat<immer::flex_vector<std::size_t,MEMORY_T,3>>()) -NONIUS_BENCHMARK("flex/4", benchmark_concat<immer::flex_vector<std::size_t,MEMORY_T,4>>()) -NONIUS_BENCHMARK("flex/5", benchmark_concat<immer::flex_vector<std::size_t,MEMORY_T,5>>()) -NONIUS_BENCHMARK("flex/6", benchmark_concat<immer::flex_vector<std::size_t,MEMORY_T,6>>()) -NONIUS_BENCHMARK("flex/7", benchmark_concat<immer::flex_vector<std::size_t,MEMORY_T,7>>()) diff --git a/third_party/immer/benchmark/vector/branching/gc/access.cpp b/third_party/immer/benchmark/vector/branching/gc/access.cpp deleted file mode 100644 index cec060481c73..000000000000 --- a/third_party/immer/benchmark/vector/branching/gc/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T gc_memory -#include "../access.ipp" diff --git a/third_party/immer/benchmark/vector/branching/gc/assoc.cpp b/third_party/immer/benchmark/vector/branching/gc/assoc.cpp deleted file mode 100644 index 448b2fd2ff79..000000000000 --- a/third_party/immer/benchmark/vector/branching/gc/assoc.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T gc_memory -#include "../assoc.ipp" diff --git a/third_party/immer/benchmark/vector/branching/gc/concat.cpp b/third_party/immer/benchmark/vector/branching/gc/concat.cpp deleted file mode 100644 index 6c32ca821c8f..000000000000 --- a/third_party/immer/benchmark/vector/branching/gc/concat.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T gc_memory -#include "../concat.ipp" diff --git a/third_party/immer/benchmark/vector/branching/gc/push.cpp b/third_party/immer/benchmark/vector/branching/gc/push.cpp deleted file mode 100644 index f1d1e33b9243..000000000000 --- a/third_party/immer/benchmark/vector/branching/gc/push.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T gc_memory -#include "../push.ipp" diff --git a/third_party/immer/benchmark/vector/branching/push.ipp b/third_party/immer/benchmark/vector/branching/push.ipp deleted file mode 100644 index 2f92d6569220..000000000000 --- a/third_party/immer/benchmark/vector/branching/push.ipp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/push.hpp" -#include <immer/flex_vector.hpp> - -#ifndef MEMORY_T -#error "define the MEMORY_T" -#endif - -NONIUS_BENCHMARK("flex/3", benchmark_push<immer::flex_vector<std::size_t,MEMORY_T,3>>()) -NONIUS_BENCHMARK("flex/4", benchmark_push<immer::flex_vector<std::size_t,MEMORY_T,4>>()) -NONIUS_BENCHMARK("flex/5", benchmark_push<immer::flex_vector<std::size_t,MEMORY_T,5>>()) -NONIUS_BENCHMARK("flex/6", benchmark_push<immer::flex_vector<std::size_t,MEMORY_T,6>>()) -NONIUS_BENCHMARK("flex/7", benchmark_push<immer::flex_vector<std::size_t,MEMORY_T,7>>()) diff --git a/third_party/immer/benchmark/vector/branching/safe/access.cpp b/third_party/immer/benchmark/vector/branching/safe/access.cpp deleted file mode 100644 index 027aa1b7619e..000000000000 --- a/third_party/immer/benchmark/vector/branching/safe/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T safe_memory -#include "../access.ipp" diff --git a/third_party/immer/benchmark/vector/branching/safe/assoc.cpp b/third_party/immer/benchmark/vector/branching/safe/assoc.cpp deleted file mode 100644 index c2f5b0cc2034..000000000000 --- a/third_party/immer/benchmark/vector/branching/safe/assoc.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T safe_memory -#include "../assoc.ipp" diff --git a/third_party/immer/benchmark/vector/branching/safe/concat.cpp b/third_party/immer/benchmark/vector/branching/safe/concat.cpp deleted file mode 100644 index 3c5dbb8a70a2..000000000000 --- a/third_party/immer/benchmark/vector/branching/safe/concat.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T safe_memory -#include "../concat.ipp" diff --git a/third_party/immer/benchmark/vector/branching/safe/push.cpp b/third_party/immer/benchmark/vector/branching/safe/push.cpp deleted file mode 100644 index 19d5bbd254ea..000000000000 --- a/third_party/immer/benchmark/vector/branching/safe/push.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T safe_memory -#include "../push.ipp" diff --git a/third_party/immer/benchmark/vector/branching/unsafe/access.cpp b/third_party/immer/benchmark/vector/branching/unsafe/access.cpp deleted file mode 100644 index 156d84e71763..000000000000 --- a/third_party/immer/benchmark/vector/branching/unsafe/access.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T unsafe_memory -#include "../access.ipp" diff --git a/third_party/immer/benchmark/vector/branching/unsafe/assoc.cpp b/third_party/immer/benchmark/vector/branching/unsafe/assoc.cpp deleted file mode 100644 index ff1802c0bc76..000000000000 --- a/third_party/immer/benchmark/vector/branching/unsafe/assoc.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T unsafe_memory -#include "../assoc.ipp" diff --git a/third_party/immer/benchmark/vector/branching/unsafe/concat.cpp b/third_party/immer/benchmark/vector/branching/unsafe/concat.cpp deleted file mode 100644 index d6d401bd483d..000000000000 --- a/third_party/immer/benchmark/vector/branching/unsafe/concat.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T unsafe_memory -#include "../concat.ipp" diff --git a/third_party/immer/benchmark/vector/branching/unsafe/push.cpp b/third_party/immer/benchmark/vector/branching/unsafe/push.cpp deleted file mode 100644 index 09ba8d7a3759..000000000000 --- a/third_party/immer/benchmark/vector/branching/unsafe/push.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#define MEMORY_T unsafe_memory -#include "../push.ipp" diff --git a/third_party/immer/benchmark/vector/common.hpp b/third_party/immer/benchmark/vector/common.hpp deleted file mode 100644 index c96d6d017d9c..000000000000 --- a/third_party/immer/benchmark/vector/common.hpp +++ /dev/null @@ -1,212 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <utility> -#include <cstddef> -#include <limits> - -#include "benchmark/config.hpp" - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include <rrb.h> -#undef restrict -} -#include <immer/heap/gc_heap.hpp> -#endif - -namespace immer { -template <typename T, typename MP> class array; -} // namespace immer - -namespace { - -auto make_generator(std::size_t runs) -{ - assert(runs > 0); - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution<std::size_t>{0, runs-1}; - auto r = std::vector<std::size_t>(runs); - std::generate_n(r.begin(), runs, std::bind(dist, engine)); - return r; -} - -struct push_back_fn -{ - template <typename T, typename U> - auto operator() (T&& v, U&& x) - { return std::forward<T>(v).push_back(std::forward<U>(x)); } -}; - -struct push_front_fn -{ - template <typename T, typename U> - auto operator() (T&& v, U&& x) - { return std::forward<T>(v).push_front(std::forward<U>(x)); } -}; - -struct set_fn -{ - template <typename T, typename I, typename U> - decltype(auto) operator() (T&& v, I i, U&& x) - { return std::forward<T>(v).set(i, std::forward<U>(x)); } -}; - -struct store_fn -{ - template <typename T, typename I, typename U> - decltype(auto) operator() (T&& v, I i, U&& x) - { return std::forward<T>(v).store(i, std::forward<U>(x)); } -}; - -template <typename T> -struct get_limit : std::integral_constant< - std::size_t, std::numeric_limits<std::size_t>::max()> {}; - -template <typename T, typename MP> -struct get_limit<immer::array<T, MP>> : std::integral_constant< - std::size_t, 10000> {}; - -auto make_librrb_vector(std::size_t n) -{ - auto v = rrb_create(); - for (auto i = 0u; i < n; ++i) { - v = rrb_push(v, reinterpret_cast<void*>(i)); - } - return v; -} - -auto make_librrb_vector_f(std::size_t n) -{ - auto v = rrb_create(); - for (auto i = 0u; i < n; ++i) { - auto f = rrb_push(rrb_create(), - reinterpret_cast<void*>(i)); - v = rrb_concat(f, v); - } - return v; -} - - -// copied from: -// https://github.com/ivmai/bdwgc/blob/master/include/gc_allocator.h - -template <class GC_tp> -struct GC_type_traits -{ - std::false_type GC_is_ptr_free; -}; - -# define GC_DECLARE_PTRFREE(T) \ - template<> struct GC_type_traits<T> { \ - std::true_type GC_is_ptr_free; \ - } - -GC_DECLARE_PTRFREE(char); -GC_DECLARE_PTRFREE(signed char); -GC_DECLARE_PTRFREE(unsigned char); -GC_DECLARE_PTRFREE(signed short); -GC_DECLARE_PTRFREE(unsigned short); -GC_DECLARE_PTRFREE(signed int); -GC_DECLARE_PTRFREE(unsigned int); -GC_DECLARE_PTRFREE(signed long); -GC_DECLARE_PTRFREE(unsigned long); -GC_DECLARE_PTRFREE(float); -GC_DECLARE_PTRFREE(double); -GC_DECLARE_PTRFREE(long double); - -template <class IsPtrFree> -inline void* GC_selective_alloc(size_t n, IsPtrFree, bool ignore_off_page) -{ - return ignore_off_page - ? GC_MALLOC_IGNORE_OFF_PAGE(n) - : GC_MALLOC(n); -} - -template <> -inline void* GC_selective_alloc<std::true_type>(size_t n, - std::true_type, - bool ignore_off_page) -{ - return ignore_off_page - ? GC_MALLOC_ATOMIC_IGNORE_OFF_PAGE(n) - : GC_MALLOC_ATOMIC(n); -} - -template <class T> -class gc_allocator -{ -public: - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef T* pointer; - typedef const T* const_pointer; - typedef T& reference; - typedef const T& const_reference; - typedef T value_type; - - template <class T1> struct rebind { - typedef gc_allocator<T1> other; - }; - - gc_allocator() {} - gc_allocator(const gc_allocator&) throw() {} - template <class T1> - explicit gc_allocator(const gc_allocator<T1>&) throw() {} - ~gc_allocator() throw() {} - - pointer address(reference GC_x) const { return &GC_x; } - const_pointer address(const_reference GC_x) const { return &GC_x; } - - // GC_n is permitted to be 0. The C++ standard says nothing about what - // the return value is when GC_n == 0. - T* allocate(size_type GC_n, const void* = 0) - { - GC_type_traits<T> traits; - return static_cast<T *> - (GC_selective_alloc(GC_n * sizeof(T), - traits.GC_is_ptr_free, false)); - } - - // p is not permitted to be a null pointer. - void deallocate(pointer p, size_type /* GC_n */) - { GC_FREE(p); } - - size_type max_size() const throw() - { return size_t(-1) / sizeof(T); } - - void construct(pointer p, const T& __val) { new(p) T(__val); } - void destroy(pointer p) { p->~T(); } -}; - -template<> -class gc_allocator<void> -{ - typedef size_t size_type; - typedef ptrdiff_t difference_type; - typedef void* pointer; - typedef const void* const_pointer; - typedef void value_type; - - template <class T1> struct rebind { - typedef gc_allocator<T1> other; - }; -}; - -template <class T1, class T2> -inline bool operator==(const gc_allocator<T1>&, const gc_allocator<T2>&) -{ return true; } - -template <class T1, class T2> -inline bool operator!=(const gc_allocator<T1>&, const gc_allocator<T2>&) -{ return false; } - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/concat.hpp b/third_party/immer/benchmark/vector/concat.hpp deleted file mode 100644 index 8656587d5dbd..000000000000 --- a/third_party/immer/benchmark/vector/concat.hpp +++ /dev/null @@ -1,166 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -constexpr auto concat_steps = 10u; - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_concat() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - return v + v; - }); - }; -} - -template <typename Fn> -auto benchmark_concat_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param<N>(); - auto v = maker(n); - measure(meter, [&] { - return rrb_concat(v, v); - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_concat_incr() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n / concat_steps; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = Vektor{}; - for (auto i = 0u; i < concat_steps; ++i) - r = r + v; - return r; - }); - }; -} - -template <typename Vektor> -auto benchmark_concat_incr_mut() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto v = Vektor{}.transient(); - for (auto i = 0u; i < n / concat_steps; ++i) - v.push_back(i); - - measure(meter, [&] (int run) { - auto r = Vektor{}.transient(); - for (auto i = 0u; i < concat_steps; ++i) - r.append(v); - return r; - }); - }; -} - -template <typename Vektor> -auto benchmark_concat_incr_mut2() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - using transient_t = typename Vektor::transient_type; - using steps_t = std::vector<transient_t, gc_allocator<transient_t>>; - auto vs = std::vector<steps_t, gc_allocator<steps_t>>(meter.runs()); - for (auto k = 0u; k < vs.size(); ++k) { - vs[k].reserve(concat_steps); - for (auto j = 0u; j < concat_steps; ++j) { - auto vv = Vektor{}.transient(); - for (auto i = 0u; i < n / concat_steps; ++i) - vv.push_back(i); - vs[k].push_back(std::move(vv)); - } - } - measure(meter, [&] (int run) { - auto& vr = vs[run]; - auto r = Vektor{}.transient(); - assert(vr.size() == concat_steps); - for (auto i = 0u; i < concat_steps; ++i) - r.append(std::move(vr[i])); - return r; - }); - }; -} - -template <typename Vektor> -auto benchmark_concat_incr_chunkedseq() -{ - return - [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - using steps_t = std::vector<Vektor>; - auto vs = std::vector<steps_t>(meter.runs()); - for (auto k = 0u; k < vs.size(); ++k) { - for (auto j = 0u; j < concat_steps; ++j) { - auto vv = Vektor{}; - for (auto i = 0u; i < n / concat_steps; ++i) - vv.push_back(i); - vs[k].push_back(std::move(vv)); - } - } - measure(meter, [&] (int run) { - auto& vr = vs[run]; - auto r = Vektor{}; - for (auto i = 0u; i < concat_steps; ++i) - r.concat(vr[i]); - return r; - }); - }; -} - -template <typename Fn> -auto benchmark_concat_incr_librrb(Fn maker) -{ - return - [=] (nonius::chronometer meter) { - auto n = meter.param<N>(); - auto v = maker(n / concat_steps); - measure(meter, [&] { - auto r = rrb_create(); - for (auto i = 0ul; i < concat_steps; ++i) - r = rrb_concat(r, v); - return r; - }); - }; -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/drop.hpp b/third_party/immer/benchmark/vector/drop.hpp deleted file mode 100644 index 0a525f67a50a..000000000000 --- a/third_party/immer/benchmark/vector/drop.hpp +++ /dev/null @@ -1,142 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_drop() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - for (auto i = 0u; i < n; ++i) - (void) v.drop(i); - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_drop_lin() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = r.drop(1); - return r; - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_drop_move() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = std::move(r).drop(1); - return r; - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_drop_mut() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto vv = Vektor{}; - for (auto i = 0u; i < n; ++i) - vv = PushFn{}(std::move(vv), i); - - measure(meter, [&] { - auto v = vv.transient(); - for (auto i = 0u; i < n; ++i) - (void) v.drop(1); - }); - }; -} - -template <typename Fn> -auto benchmark_drop_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto v = make(n); - measure(meter, [&] { - for (auto i = 0u; i < n; ++i) - rrb_slice(v, i, n); - }); - }; -} - -template <typename Fn> -auto benchmark_drop_lin_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto v = make(n); - measure(meter, [&] { - auto r = v; - for (auto i = 0u; i < n; ++i) - r = rrb_slice(r, 1, n); - return r; - }); - }; -} - -template <typename Fn> -auto benchmark_drop_mut_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto v = make(n); - measure(meter, [&] { - auto r = rrb_to_transient(v); - for (auto i = 0u; i < n; ++i) - r = transient_rrb_slice(r, 1, n); - return r; - }); - }; -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/misc/access.cpp b/third_party/immer/benchmark/vector/misc/access.cpp deleted file mode 100644 index 9a00266a87d8..000000000000 --- a/third_party/immer/benchmark/vector/misc/access.cpp +++ /dev/null @@ -1,94 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/access.hpp" - -#include <immer/algorithm.hpp> -#include <immer/array.hpp> -#include <immer/flex_vector.hpp> -#include <immer/vector.hpp> - -#if IMMER_BENCHMARK_EXPERIMENTAL -#include <immer/experimental/dvektor.hpp> -#endif - -#if IMMER_BENCHMARK_STEADY -#define QUARK_ASSERT_ON 0 -#include <steady/steady_vector.h> -#endif - -#include <vector> -#include <list> -#include <numeric> - -NONIUS_BENCHMARK("std::vector", benchmark_access_iter_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("std::vector/idx", benchmark_access_idx_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("std::vector/random", benchmark_access_random_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("std::list", benchmark_access_iter_std<std::list<unsigned>>()) - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_access_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_access_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("librrb/random", benchmark_access_random_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F/random", benchmark_access_random_librrb(make_librrb_vector_f)) -#endif - -NONIUS_BENCHMARK("flex/5B", benchmark_access_iter<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("flex/F/5B", benchmark_access_iter<immer::flex_vector<unsigned,def_memory,5>,push_front_fn>()) -NONIUS_BENCHMARK("vector/4B", benchmark_access_iter<immer::vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("vector/5B", benchmark_access_iter<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/6B", benchmark_access_iter<immer::vector<unsigned,def_memory,6>>()) - -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B", benchmark_access_iter<immer::dvektor<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("dvektor/5B", benchmark_access_iter<immer::dvektor<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("dvektor/6B", benchmark_access_iter<immer::dvektor<unsigned,def_memory,6>>()) -#endif - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady/idx", benchmark_access_idx<steady::vector<unsigned>>()) -#endif - -NONIUS_BENCHMARK("flex/5B/idx", benchmark_access_idx<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("flex/F/5B/idx", benchmark_access_idx<immer::flex_vector<unsigned,def_memory,5>,push_front_fn>()) -NONIUS_BENCHMARK("vector/4B/idx", benchmark_access_idx<immer::vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("vector/5B/idx", benchmark_access_idx<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/6B/idx", benchmark_access_idx<immer::vector<unsigned,def_memory,6>>()) -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B/idx", benchmark_access_idx<immer::dvektor<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("dvektor/5B/idx", benchmark_access_idx<immer::dvektor<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("dvektor/6B/idx", benchmark_access_idx<immer::dvektor<unsigned,def_memory,6>>()) -#endif - -NONIUS_BENCHMARK("flex/5B/reduce_i", benchmark_access_reduce_range<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/5B/reduce_i", benchmark_access_reduce_range<immer::vector<unsigned,def_memory,5>>()) - -NONIUS_BENCHMARK("flex/5B/reduce", benchmark_access_reduce<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("flex/F/5B/reduce", benchmark_access_reduce<immer::flex_vector<unsigned,def_memory,5>,push_front_fn>()) -NONIUS_BENCHMARK("vector/4B/reduce", benchmark_access_reduce<immer::vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("vector/5B/reduce", benchmark_access_reduce<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/6B/reduce", benchmark_access_reduce<immer::vector<unsigned,def_memory,6>>()) - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady/random", benchmark_access_random<steady::vector<unsigned>>()) -#endif - -NONIUS_BENCHMARK("flex/5B/random", benchmark_access_random<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("flex/F/5B/random", benchmark_access_random<immer::flex_vector<unsigned,def_memory,5>, push_front_fn>()) -NONIUS_BENCHMARK("vector/4B/random", benchmark_access_random<immer::vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("vector/5B/random", benchmark_access_random<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/6B/random", benchmark_access_random<immer::vector<unsigned,def_memory,6>>()) -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B/random", benchmark_access_random<immer::dvektor<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("dvektor/5B/random", benchmark_access_random<immer::dvektor<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("dvektor/6B/random", benchmark_access_random<immer::dvektor<unsigned,def_memory,6>>()) -#endif - -#if IMMER_BENCHMARK_BOOST_COROUTINE -NONIUS_BENCHMARK("vector/5B/coro", benchmark_access_coro<immer::vector<unsigned,def_memory,5>>()) -#endif diff --git a/third_party/immer/benchmark/vector/misc/assoc.cpp b/third_party/immer/benchmark/vector/misc/assoc.cpp deleted file mode 100644 index 2b3d6d76b985..000000000000 --- a/third_party/immer/benchmark/vector/misc/assoc.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/assoc.hpp" - -#include <immer/array.hpp> -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -#if IMMER_BENCHMARK_EXPERIMENTAL -#include <immer/experimental/dvektor.hpp> -#endif - -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> - -#include <vector> -#include <list> - -#if IMMER_BENCHMARK_STEADY -#define QUARK_ASSERT_ON 0 -#include <steady/steady_vector.h> -#endif - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include <rrb.h> -#undef restrict -} -#endif - -NONIUS_BENCHMARK("std::vector", benchmark_assoc_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("std::vector/random", benchmark_assoc_random_std<std::vector<unsigned>>()) - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_assoc_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_assoc_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("librrb/random", benchmark_assoc_random_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("t/librrb", benchmark_assoc_mut_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("t/librrb/F", benchmark_assoc_mut_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("t/librrb/random", benchmark_assoc_mut_random_librrb(make_librrb_vector)) -#endif - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady", benchmark_assoc<steady::vector<unsigned>, push_back_fn, store_fn>()) -#endif - -NONIUS_BENCHMARK("flex/5B", benchmark_assoc<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("flex/F/5B", benchmark_assoc<immer::flex_vector<unsigned,def_memory,5>,push_front_fn>()) - -NONIUS_BENCHMARK("flex/GC", benchmark_assoc<immer::flex_vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("flex/F/GC", benchmark_assoc<immer::flex_vector<unsigned,gc_memory,5>,push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GCF", benchmark_assoc<immer::flex_vector<unsigned,gcf_memory,5>,push_front_fn>()) - -NONIUS_BENCHMARK("flex_s/GC", benchmark_assoc<immer::flex_vector<std::size_t,gc_memory,5>>()) -NONIUS_BENCHMARK("flex_s/F/GC",benchmark_assoc<immer::flex_vector<std::size_t,gc_memory,5>,push_front_fn>()) -NONIUS_BENCHMARK("flex_s/F/GCF",benchmark_assoc<immer::flex_vector<std::size_t,gcf_memory,5>,push_front_fn>()) - -NONIUS_BENCHMARK("vector/4B", benchmark_assoc<immer::vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("vector/5B", benchmark_assoc<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/6B", benchmark_assoc<immer::vector<unsigned,def_memory,6>>()) - -NONIUS_BENCHMARK("vector/GC", benchmark_assoc<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("vector/NO", benchmark_assoc<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("vector/UN", benchmark_assoc<immer::vector<unsigned,unsafe_memory,5>>()) - -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B", benchmark_assoc<immer::dvektor<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("dvektor/5B", benchmark_assoc<immer::dvektor<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("dvektor/6B", benchmark_assoc<immer::dvektor<unsigned,def_memory,6>>()) - -NONIUS_BENCHMARK("dvektor/GC", benchmark_assoc<immer::dvektor<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("dvektor/NO", benchmark_assoc<immer::dvektor<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("dvektor/UN", benchmark_assoc<immer::dvektor<unsigned,unsafe_memory,5>>()) -#endif - -NONIUS_BENCHMARK("array", benchmark_assoc<immer::array<unsigned>>()) - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady/random", benchmark_assoc_random<steady::vector<unsigned>, push_back_fn, store_fn>()) -#endif - -NONIUS_BENCHMARK("flex/5B/random", benchmark_assoc_random<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/4B/random", benchmark_assoc_random<immer::vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("vector/5B/random", benchmark_assoc_random<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/6B/random", benchmark_assoc_random<immer::vector<unsigned,def_memory,6>>()) -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B/random", benchmark_assoc_random<immer::dvektor<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("dvektor/5B/random", benchmark_assoc_random<immer::dvektor<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("dvektor/6B/random", benchmark_assoc_random<immer::dvektor<unsigned,def_memory,6>>()) -#endif -NONIUS_BENCHMARK("array/random", benchmark_assoc_random<immer::array<unsigned>>()) - -NONIUS_BENCHMARK("t/vector/5B", benchmark_assoc_mut<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("t/vector/GC", benchmark_assoc_mut<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("t/vector/NO", benchmark_assoc_mut<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("t/vector/UN", benchmark_assoc_mut<immer::vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("t/flex/F/5B", benchmark_assoc_mut<immer::flex_vector<unsigned,def_memory,5>,push_front_fn>()) - -NONIUS_BENCHMARK("m/vector/5B", benchmark_assoc_move<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("m/vector/GC", benchmark_assoc_move<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("m/vector/NO", benchmark_assoc_move<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("m/vector/UN", benchmark_assoc_move<immer::vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("m/flex/F/5B", benchmark_assoc_move<immer::flex_vector<unsigned,def_memory,5>,push_front_fn>()) - -NONIUS_BENCHMARK("t/vector/5B/random", benchmark_assoc_mut_random<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("t/vector/GC/random", benchmark_assoc_mut_random<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("t/vector/NO/random", benchmark_assoc_mut_random<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("t/vector/UN/random", benchmark_assoc_mut_random<immer::vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("t/flex/F/5B/random", benchmark_assoc_mut_random<immer::flex_vector<unsigned,def_memory,5>,push_front_fn>()) diff --git a/third_party/immer/benchmark/vector/misc/concat.cpp b/third_party/immer/benchmark/vector/misc/concat.cpp deleted file mode 100644 index 9bc10c5c2309..000000000000 --- a/third_party/immer/benchmark/vector/misc/concat.cpp +++ /dev/null @@ -1,49 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/concat.hpp" - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include <rrb.h> -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_concat_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_concat_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("i/librrb", benchmark_concat_incr_librrb(make_librrb_vector)) -#endif - -NONIUS_BENCHMARK("flex/4B", benchmark_concat<immer::flex_vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("flex/5B", benchmark_concat<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("flex/6B", benchmark_concat<immer::flex_vector<unsigned,def_memory,6>>()) -NONIUS_BENCHMARK("flex/GC", benchmark_concat<immer::flex_vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("flex_s/GC", benchmark_concat<immer::flex_vector<std::size_t,gc_memory,5>>()) -NONIUS_BENCHMARK("flex/NO", benchmark_concat<immer::flex_vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("flex/UN", benchmark_concat<immer::flex_vector<unsigned,unsafe_memory,5>>()) - -NONIUS_BENCHMARK("flex/F/5B", benchmark_concat<immer::flex_vector<unsigned,def_memory,5>,push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GC", benchmark_concat<immer::flex_vector<unsigned,gc_memory,5>,push_front_fn>()) -NONIUS_BENCHMARK("flex_s/F/GC", benchmark_concat<immer::flex_vector<std::size_t,gc_memory,5>,push_front_fn>()) - -NONIUS_BENCHMARK("i/flex/GC", benchmark_concat_incr<immer::flex_vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("i/flex_s/GC", benchmark_concat_incr<immer::flex_vector<std::size_t,gc_memory,5>>()) -NONIUS_BENCHMARK("i/flex/5B", benchmark_concat_incr<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("i/flex/UN", benchmark_concat_incr<immer::flex_vector<unsigned,unsafe_memory,5>>()) - -NONIUS_BENCHMARK("m/flex/GC", benchmark_concat_incr_mut<immer::flex_vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("m/flex_s/GC", benchmark_concat_incr_mut<immer::flex_vector<std::size_t,gc_memory,5>>()) diff --git a/third_party/immer/benchmark/vector/misc/drop.cpp b/third_party/immer/benchmark/vector/misc/drop.cpp deleted file mode 100644 index c2ca48390b13..000000000000 --- a/third_party/immer/benchmark/vector/misc/drop.cpp +++ /dev/null @@ -1,63 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/drop.hpp" - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include <rrb.h> -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_drop_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_drop_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("l/librrb", benchmark_drop_lin_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("l/librrb/F", benchmark_drop_lin_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("t/librrb", benchmark_drop_mut_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("t/librrb/F", benchmark_drop_mut_librrb(make_librrb_vector_f)) -#endif - -NONIUS_BENCHMARK("flex/4B", benchmark_drop<immer::flex_vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("flex/5B", benchmark_drop<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("flex/6B", benchmark_drop<immer::flex_vector<unsigned,def_memory,6>>()) -NONIUS_BENCHMARK("flex/GC", benchmark_drop<immer::flex_vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("flex/NO", benchmark_drop<immer::flex_vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("flex/UN", benchmark_drop<immer::flex_vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("flex_s/GC", benchmark_drop<immer::flex_vector<std::size_t,gc_memory,5>>()) - -NONIUS_BENCHMARK("flex/F/5B", benchmark_drop<immer::flex_vector<unsigned,def_memory,5>, push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GC", benchmark_drop<immer::flex_vector<unsigned,gc_memory,5>, push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GCF", benchmark_drop<immer::flex_vector<unsigned,gcf_memory,5>, push_front_fn>()) -NONIUS_BENCHMARK("flex_s/F/GC", benchmark_drop<immer::flex_vector<std::size_t,gc_memory,5>, push_front_fn>()) - -NONIUS_BENCHMARK("l/flex/5B", benchmark_drop_lin<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("l/flex/GC", benchmark_drop_lin<immer::flex_vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("l/flex/NO", benchmark_drop_lin<immer::flex_vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("l/flex/UN", benchmark_drop_lin<immer::flex_vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("l/flex/F/5B", benchmark_drop_lin<immer::flex_vector<unsigned,def_memory,5>, push_front_fn>()) - -NONIUS_BENCHMARK("m/flex/5B", benchmark_drop_move<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("m/flex/GC", benchmark_drop_move<immer::flex_vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("m/flex/NO", benchmark_drop_move<immer::flex_vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("m/flex/UN", benchmark_drop_move<immer::flex_vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("m/flex/F/5B", benchmark_drop_move<immer::flex_vector<unsigned,def_memory,5>, push_front_fn>()) - -NONIUS_BENCHMARK("t/flex/5B", benchmark_drop_mut<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("t/flex/GC", benchmark_drop_mut<immer::flex_vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("t/flex/NO", benchmark_drop_mut<immer::flex_vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("t/flex/UN", benchmark_drop_mut<immer::flex_vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("t/flex/F/5B", benchmark_drop_mut<immer::flex_vector<unsigned,def_memory,5>, push_front_fn>()) diff --git a/third_party/immer/benchmark/vector/misc/push-front.cpp b/third_party/immer/benchmark/vector/misc/push-front.cpp deleted file mode 100644 index 48b98c8ee9b1..000000000000 --- a/third_party/immer/benchmark/vector/misc/push-front.cpp +++ /dev/null @@ -1,30 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/push_front.hpp" - -#include <immer/flex_vector.hpp> - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include <rrb.h> -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_push_front_librrb) -#endif -NONIUS_BENCHMARK("flex/4B", bechmark_push_front<immer::flex_vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("flex/5B", bechmark_push_front<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("flex/6B", bechmark_push_front<immer::flex_vector<unsigned,def_memory,6>>()) -NONIUS_BENCHMARK("flex/GC", bechmark_push_front<immer::flex_vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("flex_s/GC", bechmark_push_front<immer::flex_vector<std::size_t,gc_memory,5>>()) -NONIUS_BENCHMARK("flex/NO", bechmark_push_front<immer::flex_vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("flex/UN", bechmark_push_front<immer::flex_vector<unsigned,unsafe_memory,5>>()) diff --git a/third_party/immer/benchmark/vector/misc/push.cpp b/third_party/immer/benchmark/vector/misc/push.cpp deleted file mode 100644 index 98f57600bd78..000000000000 --- a/third_party/immer/benchmark/vector/misc/push.cpp +++ /dev/null @@ -1,83 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/push.hpp" - -#include <immer/array.hpp> -#include <immer/flex_vector.hpp> -#include <immer/vector_transient.hpp> -#include <immer/vector.hpp> - -#if IMMER_BENCHMARK_EXPERIMENTAL -#include <immer/experimental/dvektor.hpp> -#endif - -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> - -#include <vector> -#include <list> -#include <numeric> - -#if IMMER_BENCHMARK_STEADY -#define QUARK_ASSERT_ON 0 -#include <steady/steady_vector.h> -#endif - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include <rrb.h> -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_push_librrb) -NONIUS_BENCHMARK("t/librrb", benchmark_push_mut_librrb) -#endif - -NONIUS_BENCHMARK("std::vector", benchmark_push_mut_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("std::list", benchmark_push_mut_std<std::list<unsigned>>()) - -NONIUS_BENCHMARK("m/vector/5B", benchmark_push_move<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("m/vector/GC", benchmark_push_move<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("m/vector/NO", benchmark_push_move<immer::vector<unsigned,basic_memory,5>>()) - -NONIUS_BENCHMARK("t/vector/5B", benchmark_push_mut<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("t/vector/GC", benchmark_push_mut<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("t/vector/NO", benchmark_push_mut<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("t/vector/UN", benchmark_push_mut<immer::vector<unsigned,unsafe_memory,5>>()) - -NONIUS_BENCHMARK("flex/5B", benchmark_push<immer::flex_vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("flex_s/GC", benchmark_push<immer::flex_vector<std::size_t,gc_memory,5>>()) - -NONIUS_BENCHMARK("vector/4B", benchmark_push<immer::vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("vector/5B", benchmark_push<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/6B", benchmark_push<immer::vector<unsigned,def_memory,6>>()) - -NONIUS_BENCHMARK("vector/GC", benchmark_push<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("vector/NO", benchmark_push<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("vector/UN", benchmark_push<immer::vector<unsigned,unsafe_memory,5>>()) - -#if IMMER_BENCHMARK_EXPERIMENTAL -NONIUS_BENCHMARK("dvektor/4B", benchmark_push<immer::dvektor<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("dvektor/5B", benchmark_push<immer::dvektor<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("dvektor/6B", benchmark_push<immer::dvektor<unsigned,def_memory,6>>()) - -NONIUS_BENCHMARK("dvektor/GC", benchmark_push<immer::dvektor<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("dvektor/NO", benchmark_push<immer::dvektor<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("dvektor/UN", benchmark_push<immer::dvektor<unsigned,unsafe_memory,5>>()) -#endif - -NONIUS_BENCHMARK("array", benchmark_push<immer::array<unsigned>>()) - -#if IMMER_BENCHMARK_STEADY -NONIUS_BENCHMARK("steady", benchmark_push<steady::vector<unsigned>>()) -#endif diff --git a/third_party/immer/benchmark/vector/misc/take.cpp b/third_party/immer/benchmark/vector/misc/take.cpp deleted file mode 100644 index 78f0e958db4c..000000000000 --- a/third_party/immer/benchmark/vector/misc/take.cpp +++ /dev/null @@ -1,65 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/take.hpp" - -#include <immer/vector.hpp> -#include <immer/flex_vector.hpp> -#include <immer/vector_transient.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> - -#if IMMER_BENCHMARK_LIBRRB -extern "C" { -#define restrict __restrict__ -#include <rrb.h> -#undef restrict -} -#endif - -#if IMMER_BENCHMARK_LIBRRB -NONIUS_BENCHMARK("librrb", benchmark_take_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("librrb/F", benchmark_take_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("l/librrb", benchmark_take_lin_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("l/librrb/F", benchmark_take_lin_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("t/librrb", benchmark_take_mut_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("t/librrb/F", benchmark_take_mut_librrb(make_librrb_vector_f)) -#endif - -NONIUS_BENCHMARK("vector/4B", benchmark_take<immer::vector<unsigned,def_memory,4>>()) -NONIUS_BENCHMARK("vector/5B", benchmark_take<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("vector/6B", benchmark_take<immer::vector<unsigned,def_memory,6>>()) -NONIUS_BENCHMARK("vector/GC", benchmark_take<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("vector/NO", benchmark_take<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("vector/UN", benchmark_take<immer::vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("vector_s/GC", benchmark_take<immer::vector<std::size_t,gc_memory,5>>()) - -NONIUS_BENCHMARK("flex/F/5B", benchmark_take<immer::flex_vector<unsigned,def_memory,5>, push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GC", benchmark_take<immer::flex_vector<unsigned,gc_memory,5>, push_front_fn>()) -NONIUS_BENCHMARK("flex/F/GCF", benchmark_take<immer::flex_vector<unsigned,gcf_memory,5>, push_front_fn>()) -NONIUS_BENCHMARK("flex_s/F/GC", benchmark_take<immer::flex_vector<std::size_t,gc_memory,5>, push_front_fn>()) - -NONIUS_BENCHMARK("l/vector/5B", benchmark_take_lin<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("l/vector/GC", benchmark_take_lin<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("l/vector/NO", benchmark_take_lin<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("l/vector/UN", benchmark_take_lin<immer::vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("l/flex/F/5B", benchmark_take_lin<immer::flex_vector<unsigned,def_memory,5>, push_front_fn>()) - -NONIUS_BENCHMARK("m/vector/5B", benchmark_take_move<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("m/vector/GC", benchmark_take_move<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("m/vector/NO", benchmark_take_move<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("m/vector/UN", benchmark_take_move<immer::vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("m/flex/F/5B", benchmark_take_move<immer::flex_vector<unsigned,def_memory,5>, push_front_fn>()) - -NONIUS_BENCHMARK("t/vector/5B", benchmark_take_mut<immer::vector<unsigned,def_memory,5>>()) -NONIUS_BENCHMARK("t/vector/GC", benchmark_take_mut<immer::vector<unsigned,gc_memory,5>>()) -NONIUS_BENCHMARK("t/vector/NO", benchmark_take_mut<immer::vector<unsigned,basic_memory,5>>()) -NONIUS_BENCHMARK("t/vector/UN", benchmark_take_mut<immer::vector<unsigned,unsafe_memory,5>>()) -NONIUS_BENCHMARK("t/flex/F/5B", benchmark_take_mut<immer::flex_vector<unsigned,def_memory,5>, push_front_fn>()) diff --git a/third_party/immer/benchmark/vector/paper/access.cpp b/third_party/immer/benchmark/vector/paper/access.cpp deleted file mode 100644 index db677a1adb80..000000000000 --- a/third_party/immer/benchmark/vector/paper/access.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/access.hpp" -#include <immer/flex_vector.hpp> -#include <chunkedseq/chunkedseq.hpp> - -NONIUS_BENCHMARK("idx owrs", benchmark_access_idx<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("idx librrb", benchmark_access_librrb(make_librrb_vector)) -NONIUS_BENCHMARK("idx relaxed owrs", benchmark_access_idx<immer::flex_vector<unsigned,def_memory>,push_front_fn>()) -NONIUS_BENCHMARK("idx relaxed librrb", benchmark_access_librrb(make_librrb_vector_f)) -NONIUS_BENCHMARK("idx std::vector", benchmark_access_idx_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("idx chunkedseq32", benchmark_access_idx_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned, 32>>()) -NONIUS_BENCHMARK("idx chunkedseq", benchmark_access_idx_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned>>()) - -NONIUS_BENCHMARK("iter orws", benchmark_access_iter<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("iter relaxed orws", benchmark_access_iter<immer::flex_vector<unsigned,def_memory>,push_front_fn>()) -NONIUS_BENCHMARK("iter chunkedseq32", benchmark_access_iter_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned, 32>>()) -NONIUS_BENCHMARK("iter chunkedseq", benchmark_access_iter_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned>>()) - -NONIUS_BENCHMARK("reduce owrs", benchmark_access_reduce<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("reduce relaxed owrs", benchmark_access_reduce<immer::flex_vector<unsigned,def_memory>,push_front_fn>()) -NONIUS_BENCHMARK("reduce chunkedseq32", benchmark_access_reduce_chunkedseq<pasl::data::chunkedseq::bootstrapped::deque<unsigned, 32>>()) -NONIUS_BENCHMARK("reduce chunkedseq", benchmark_access_reduce_chunkedseq<pasl::data::chunkedseq::bootstrapped::deque<unsigned>>()) -NONIUS_BENCHMARK("reduce std::vector", benchmark_access_iter_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("reduce std::list", benchmark_access_iter_std<std::list<unsigned>>()) diff --git a/third_party/immer/benchmark/vector/paper/assoc-random.cpp b/third_party/immer/benchmark/vector/paper/assoc-random.cpp deleted file mode 100644 index becd4dc0c5b4..000000000000 --- a/third_party/immer/benchmark/vector/paper/assoc-random.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/assoc.hpp" -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <chunkedseq/chunkedseq.hpp> - -NONIUS_BENCHMARK("ours/basic", benchmark_assoc_random<immer::flex_vector<unsigned,basic_memory>>()) -NONIUS_BENCHMARK("ours/safe", benchmark_assoc_random<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("ours/unsafe", benchmark_assoc_random<immer::flex_vector<unsigned,unsafe_memory>>()) -NONIUS_BENCHMARK("ours/gc", benchmark_assoc_random<immer::flex_vector<unsigned,gc_memory>>()) -NONIUS_BENCHMARK("librrb", benchmark_assoc_random_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("relaxed ours/basic", benchmark_assoc_random<immer::flex_vector<unsigned,basic_memory>,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/safe", benchmark_assoc_random<immer::flex_vector<unsigned,def_memory>,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/unsafe", benchmark_assoc_random<immer::flex_vector<unsigned,unsafe_memory>,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/gc", benchmark_assoc_random<immer::flex_vector<unsigned,gc_memory>,push_front_fn>()) -NONIUS_BENCHMARK("relaxed librrb", benchmark_assoc_random_librrb(make_librrb_vector_f)) - -NONIUS_BENCHMARK("transient ours/basic", benchmark_assoc_mut_random<immer::flex_vector<unsigned,basic_memory>>()) -NONIUS_BENCHMARK("transient ours/safe", benchmark_assoc_mut_random<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("transient ours/unsafe", benchmark_assoc_mut_random<immer::flex_vector<unsigned,unsafe_memory>>()) -NONIUS_BENCHMARK("transient ours/gc", benchmark_assoc_mut_random<immer::flex_vector<unsigned,gc_memory>>()) -NONIUS_BENCHMARK("transient librrb", benchmark_assoc_mut_random_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("transient relaxed ours/basic", benchmark_assoc_mut_random<immer::flex_vector<unsigned,basic_memory>,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/safe", benchmark_assoc_mut_random<immer::flex_vector<unsigned,def_memory>,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/unsafe", benchmark_assoc_mut_random<immer::flex_vector<unsigned,unsafe_memory>,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/gc", benchmark_assoc_mut_random<immer::flex_vector<unsigned,gc_memory>,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed librrb", benchmark_assoc_mut_random_librrb(make_librrb_vector_f)) - -NONIUS_BENCHMARK("transient std::vector", benchmark_assoc_random_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("transient chunkedseq32", benchmark_assoc_random_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned>>()) -NONIUS_BENCHMARK("transient chunkedseq", benchmark_assoc_random_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned, 32>>()) diff --git a/third_party/immer/benchmark/vector/paper/assoc.cpp b/third_party/immer/benchmark/vector/paper/assoc.cpp deleted file mode 100644 index fe682ce74934..000000000000 --- a/third_party/immer/benchmark/vector/paper/assoc.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/assoc.hpp" -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <chunkedseq/chunkedseq.hpp> - -NONIUS_BENCHMARK("ours/basic", benchmark_assoc<immer::flex_vector<unsigned,basic_memory>>()) -NONIUS_BENCHMARK("ours/safe", benchmark_assoc<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("ours/unsafe", benchmark_assoc<immer::flex_vector<unsigned,unsafe_memory>>()) -NONIUS_BENCHMARK("ours/gc", benchmark_assoc<immer::flex_vector<unsigned,gc_memory>>()) -NONIUS_BENCHMARK("librrb", benchmark_assoc_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("relaxed ours/basic", benchmark_assoc<immer::flex_vector<unsigned,basic_memory>,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/safe", benchmark_assoc<immer::flex_vector<unsigned,def_memory>,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/unsafe", benchmark_assoc<immer::flex_vector<unsigned,unsafe_memory>,push_front_fn>()) -NONIUS_BENCHMARK("relaxed ours/gc", benchmark_assoc<immer::flex_vector<unsigned,gc_memory>,push_front_fn>()) -NONIUS_BENCHMARK("relaxed librrb", benchmark_assoc_librrb(make_librrb_vector_f)) - -NONIUS_BENCHMARK("transient ours/basic", benchmark_assoc_mut<immer::flex_vector<unsigned,basic_memory>>()) -NONIUS_BENCHMARK("transient ours/safe", benchmark_assoc_mut<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("transient ours/unsafe", benchmark_assoc_mut<immer::flex_vector<unsigned,unsafe_memory>>()) -NONIUS_BENCHMARK("transient ours/gc", benchmark_assoc_mut<immer::flex_vector<unsigned,gc_memory>>()) -NONIUS_BENCHMARK("transient librrb", benchmark_assoc_mut_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("transient relaxed ours/basic", benchmark_assoc_mut<immer::flex_vector<unsigned,basic_memory>,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/safe", benchmark_assoc_mut<immer::flex_vector<unsigned,def_memory>,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/unsafe", benchmark_assoc_mut<immer::flex_vector<unsigned,unsafe_memory>,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed ours/gc", benchmark_assoc_mut<immer::flex_vector<unsigned,gc_memory>,push_back_fn>()) -NONIUS_BENCHMARK("transient relaxed librrb", benchmark_assoc_mut_librrb(make_librrb_vector_f)) - -NONIUS_BENCHMARK("transient std::vector", benchmark_assoc_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("transient chunkedseq32", benchmark_assoc_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned, 32>>()) -NONIUS_BENCHMARK("transient chunkedseq", benchmark_assoc_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned>>()) diff --git a/third_party/immer/benchmark/vector/paper/concat.cpp b/third_party/immer/benchmark/vector/paper/concat.cpp deleted file mode 100644 index af9b3d20eda5..000000000000 --- a/third_party/immer/benchmark/vector/paper/concat.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/concat.hpp" -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <chunkedseq/chunkedseq.hpp> - -NONIUS_BENCHMARK("ours/basic", benchmark_concat_incr<immer::flex_vector<unsigned,basic_memory>>()) -NONIUS_BENCHMARK("ours/safe", benchmark_concat_incr<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("ours/unsafe", benchmark_concat_incr<immer::flex_vector<unsigned,unsafe_memory>>()) -NONIUS_BENCHMARK("ours/gc", benchmark_concat_incr<immer::flex_vector<unsigned,gc_memory>>()) -NONIUS_BENCHMARK("librrb", benchmark_concat_incr_librrb(make_librrb_vector)) - -NONIUS_BENCHMARK("transient ours/gc", benchmark_concat_incr_mut<immer::flex_vector<unsigned,gc_memory>>()) -NONIUS_BENCHMARK("transient chunkedseq32", benchmark_concat_incr_chunkedseq<pasl::data::chunkedseq::bootstrapped::deque<unsigned, 32>>()) -NONIUS_BENCHMARK("transient chunkedseq", benchmark_concat_incr_chunkedseq<pasl::data::chunkedseq::bootstrapped::deque<unsigned>>()) diff --git a/third_party/immer/benchmark/vector/paper/push.cpp b/third_party/immer/benchmark/vector/paper/push.cpp deleted file mode 100644 index 7c467985bb3b..000000000000 --- a/third_party/immer/benchmark/vector/paper/push.cpp +++ /dev/null @@ -1,28 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "benchmark/vector/push.hpp" -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <chunkedseq/chunkedseq.hpp> - -NONIUS_BENCHMARK("ours/basic", benchmark_push<immer::flex_vector<unsigned,basic_memory>>()) -NONIUS_BENCHMARK("ours/safe", benchmark_push<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("ours/unsafe", benchmark_push<immer::flex_vector<unsigned,unsafe_memory>>()) -NONIUS_BENCHMARK("ours/gc", benchmark_push<immer::flex_vector<unsigned,gc_memory>>()) -NONIUS_BENCHMARK("librrb", benchmark_push_librrb) - -NONIUS_BENCHMARK("transient ours/basic", benchmark_push_mut<immer::flex_vector<unsigned,basic_memory>>()) -NONIUS_BENCHMARK("transient ours/safe", benchmark_push_mut<immer::flex_vector<unsigned,def_memory>>()) -NONIUS_BENCHMARK("transient ours/unsafe", benchmark_push_mut<immer::flex_vector<unsigned,unsafe_memory>>()) -NONIUS_BENCHMARK("transient ours/gc", benchmark_push_mut<immer::flex_vector<unsigned,gc_memory>>()) -NONIUS_BENCHMARK("transient librrb", benchmark_push_mut_librrb) -NONIUS_BENCHMARK("transient std::vector", benchmark_push_mut_std<std::vector<unsigned>>()) -NONIUS_BENCHMARK("transient std::list", benchmark_push_mut_std<std::list<unsigned>>()) -NONIUS_BENCHMARK("transient chunkedseq32", benchmark_push_mut_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned, 32>>()) -NONIUS_BENCHMARK("transient chunkedseq", benchmark_push_mut_std<pasl::data::chunkedseq::bootstrapped::deque<unsigned>>()) diff --git a/third_party/immer/benchmark/vector/push.hpp b/third_party/immer/benchmark/vector/push.hpp deleted file mode 100644 index 83f128c8fcc6..000000000000 --- a/third_party/immer/benchmark/vector/push.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template <typename Vektor> -auto benchmark_push_mut_std() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - if (n > get_limit<Vektor>{}) - nonius::skip(); - - measure(meter, [&] { - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return v; - }); - }; -} - -template <typename Vektor> -auto benchmark_push_mut() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - if (n > get_limit<Vektor>{}) - nonius::skip(); - - measure(meter, [&] { - auto v = Vektor{}.transient(); - for (auto i = 0u; i < n; ++i) - v.push_back(i); - return v; - }); - }; -} - -template <typename Vektor> -auto benchmark_push_move() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - if (n > get_limit<Vektor>{}) - nonius::skip(); - - measure(meter, [&] { - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = std::move(v).push_back(i); - return v; - }); - }; -} - -template <typename Vektor> -auto benchmark_push() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - if (n > get_limit<Vektor>{}) - nonius::skip(); - - measure(meter, [&] { - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = v.push_back(i); - return v; - }); - }; -} - -auto benchmark_push_librrb(nonius::chronometer meter) -{ - auto n = meter.param<N>(); - - measure(meter, [&] { - auto v = rrb_create(); - for (auto i = 0u; i < n; ++i) - v = rrb_push(v, reinterpret_cast<void*>(i)); - return v; - }); -} - -auto benchmark_push_mut_librrb(nonius::chronometer meter) -{ - auto n = meter.param<N>(); - - measure(meter, [&] { - auto v = rrb_to_transient(rrb_create()); - for (auto i = 0u; i < n; ++i) - v = transient_rrb_push(v, reinterpret_cast<void*>(i)); - return v; - }); -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/push_front.hpp b/third_party/immer/benchmark/vector/push_front.hpp deleted file mode 100644 index 25ccbab0f9a6..000000000000 --- a/third_party/immer/benchmark/vector/push_front.hpp +++ /dev/null @@ -1,46 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template <typename Vektor> -auto bechmark_push_front() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - measure(meter, [&] { - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = v.push_front(i); - return v; - }); - }; -} - -auto benchmark_push_front_librrb(nonius::chronometer meter) -{ - auto n = meter.param<N>(); - - measure(meter, [&] { - auto v = rrb_create(); - for (auto i = 0u; i < n; ++i) { - auto f = rrb_push(rrb_create(), - reinterpret_cast<void*>(i)); - v = rrb_concat(f, v); - } - return v; - }); -} - -} // anonymous namespace diff --git a/third_party/immer/benchmark/vector/take.hpp b/third_party/immer/benchmark/vector/take.hpp deleted file mode 100644 index bce5aceb0072..000000000000 --- a/third_party/immer/benchmark/vector/take.hpp +++ /dev/null @@ -1,144 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "benchmark/vector/common.hpp" - -namespace { - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_take() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - for (auto i = 0u; i < n; ++i) - (void) v.take(i); - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_take_lin() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = n; i > 0; --i) - r = r.take(i); - return r; - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_take_move() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto v = Vektor{}; - for (auto i = 0u; i < n; ++i) - v = PushFn{}(std::move(v), i); - - measure(meter, [&] { - auto r = v; - for (auto i = n; i > 0; --i) - r = std::move(r).take(i); - return r; - }); - }; -} - -template <typename Vektor, - typename PushFn=push_back_fn> -auto benchmark_take_mut() -{ - return [] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - - auto vv = Vektor{}; - for (auto i = 0u; i < n; ++i) - vv = PushFn{}(std::move(vv), i); - - measure(meter, [&] { - auto v = vv.transient(); - for (auto i = n; i > 0; --i) - (void) v.take(i); - }); - }; -} - -template <typename Fn> -auto benchmark_take_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto v = make(n); - measure(meter, [&] { - for (auto i = 0u; i < n; ++i) - rrb_slice(v, 0, i); - }); - }; -} - -template <typename Fn> -auto benchmark_take_lin_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto v = make(n); - measure( - meter, [&] { - auto r = v; - for (auto i = n; i > 0; --i) - r = rrb_slice(r, 0, i); - return r; - }); - }; -} - -template <typename Fn> -auto benchmark_take_mut_librrb(Fn make) -{ - return [=] (nonius::chronometer meter) - { - auto n = meter.param<N>(); - auto v = make(n); - measure( - meter, [&] { - auto r = rrb_to_transient(v); - for (auto i = n; i > 0; --i) - r = transient_rrb_slice(r, 0, i); - return r; - }); - }; -} - -} // anonymous namespace diff --git a/third_party/immer/cmake/FindBoehmGC.cmake b/third_party/immer/cmake/FindBoehmGC.cmake deleted file mode 100644 index bdb7240e6d8c..000000000000 --- a/third_party/immer/cmake/FindBoehmGC.cmake +++ /dev/null @@ -1,108 +0,0 @@ -# - Try to find Boehm GC -# Once done, this will define -# -# BOEHM_GC_FOUND - system has Boehm GC -# BOEHM_GC_INCLUDE_DIR - the Boehm GC include directories -# BOEHM_GC_LIBRARIES - link these to use Boehm GC -# -# Copyright (c) 2010-2015 Takashi Kato <ktakashi@ymail.com> -# -# 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. -# -# 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 -# OWNER 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. -# -# $Id: $ -# - -# CMake module to find Boehm GC - -# use pkg-config if available -FIND_PACKAGE(PkgConfig) -PKG_CHECK_MODULES(PC_BDW_GC QUIET bdw-gc) - -# try newer one first in case of gc.h is overwritten. -FIND_PATH(BOEHM_GC_INCLUDE_DIR gc/gc.h - HINTS ${PC_BDW_GC_INCLUDEDIR} ${PC_BDW_GC_INCLUDE_DIRS}) - -IF (NOT BOEHM_GC_INCLUDE_DIR) - FIND_PATH(BOEHM_GC_INCLUDE_DIR gc.h - HINTS ${PC_BDW_GC_INCLUDEDIR} ${PC_BDW_GC_INCLUDE_DIRS}) - IF (BOEHM_GC_INCLUDE_DIR) - SET(HAVE_GC_H TRUE) - ENDIF() -ELSE() - SET(HAVE_GC_GC_H TRUE) -ENDIF() - -# For FreeBSD we need to use gc-threaded -IF (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") - # checks if 'gc' supports 'GC_get_parallel' and if it does - # then use it - INCLUDE(${CMAKE_ROOT}/Modules/CheckCSourceCompiles.cmake) - # not sure if this links properly... - FIND_LIBRARY(BOEHM_GC_LIBRARIES NAMES gc - HINTS ${PC_BDW_GC_LIBDIR} ${PC_BDW_GC_LIBRARY_DIRS}) - MESSAGE(STATUS "GC library ${BOEHM_GC_LIBRARIES}") - SET(CMAKE_REQUIRED_LIBRARIES "gc") - SET(CMAKE_REQUIRED_DEFINITIONS "-DGC_THREADS") - SET(CMAKE_REQUIRED_INCLUDES "${BOEHM_GC_INCLUDE_DIR}") - SET(CMAKE_REQUIRED_FLAGS "-L${PC_BDW_GC_LIBRARY_DIRS}") - MESSAGE(STATUS "Boehm GC include dir: ${CMAKE_REQUIRED_INCLUDES}") - CHECK_C_SOURCE_RUNS( - "#include <gc.h> -int main() { -int i= GC_get_parallel(); -return 0; -} -" GC_GET_PARALLEL_WORKS) - IF (NOT GC_GET_PARALLEL_WORKS) - MESSAGE(STATUS "Try gc-threaded") - - # bdw-gc-threaded is the proper name for FreeBSD pkg-config - PKG_CHECK_MODULES(PC_BDW_GC_THREADED bdw-gc-threaded) - FIND_LIBRARY(BOEHM_GC_THREADED_LIBRARIES NAMES gc-threaded - HINTS ${PC_BDW_GC_THREADED_LIBDIR} ${PC_BDW_GC_THREADED_THREADED_DIRS}) - - MESSAGE(STATUS "GC threaded library ${BOEHM_GC_THREADED_LIBRARIES}") - IF (BOEHM_GC_THREADED_LIBRARIES) - # OK just use it - SET(BOEHM_GC_LIBRARIES "${BOEHM_GC_THREADED_LIBRARIES}") - ENDIF() - ENDIF() -ELSE() - FIND_LIBRARY(BOEHM_GC_LIBRARIES NAMES gc - HINTS ${PC_BDW_GC_LIBDIR} ${PC_BDW_GC_LIBRARY_DIRS}) - # OpenSolaris uses bgc as Boehm GC runtime in its package manager. - # so try it - IF (NOT BOEHM_GC_LIBRARIES) - FIND_LIBRARY(BOEHM_GC_LIBRARIES NAMES bgc - HINTS ${PC_BDW_GC_LIBDIR} ${PC_BDW_GC_LIBRARY_DIRS}) - ENDIF() -ENDIF() - -MESSAGE(STATUS "Found GC library: ${BOEHM_GC_LIBRARIES}") - -INCLUDE(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(Boehm_GC DEFAULT_MSG - BOEHM_GC_LIBRARIES BOEHM_GC_INCLUDE_DIR) - -MARK_AS_ADVANCED(BOEHM_GC_LIBRARIES BOEHM_GC_INCLUDE_DIR) diff --git a/third_party/immer/cmake/FindGuile.cmake b/third_party/immer/cmake/FindGuile.cmake deleted file mode 100644 index 2b8781c48f48..000000000000 --- a/third_party/immer/cmake/FindGuile.cmake +++ /dev/null @@ -1,326 +0,0 @@ -#[[.rst -# -# FindGuile -# --------- -# Find the development libraries for Guile. -# -# Exported Vars -# ~~~~~~~~~~~~~ -# -# .. variable:: Guile_FOUND -# -# Set to *true* if Guile was found. -# -# .. variable:: Guile_INCLUDE_DIRS -# -# A list of include directories. -# -# .. variable:: Guile_LIBRARIES -# -# A list of libraries needed to build you project. -# -# .. variable:: Guile_VERSION_STRING -# -# Guile full version. -# -# .. variable:: Guile_VERSION_MAJOR -# -# Guile major version. -# -# .. variable:: Guile_VERSION_MINOR -# -# Guile minor version. -# -# .. variable:: Guile_VERSION_PATCH -# -# Guile patch version. -# -# .. variable:: Guile_EXECUTABLE -# -# Guile executable (optional). -# -# .. variable:: Guile_CONFIG_EXECUTABLE -# -# Guile configuration executable (optional). -# -# .. variable:: Guile_ROOT_DIR -# -# Guile installation root dir (optional). -# -# .. variable:: Guile_SITE_DIR -# -# Guile installation module site dir (optional). -# -# .. variable:: Guile_EXTENSION_DIR -# -# Guile installation extension dir (optional). -# -# Control VARS -# ~~~~~~~~~~~~ -# :envvar:`Guile_ROOT_DIR` -# -# Use this variable to provide hints to :filename:`find_{*}` commands, -# you may pass it to :command:`cmake` or set the environtment variable. -# -# .. code-block:: cmake -# -# % cmake . -Bbuild -DGuile_ROOT_DIR=<extra-path> -# -# # or -# % export Guile_ROOT_DIR=<extra-path>; -# % cmake . -Bbuild -# -# # or -# % Guile_ROOT_DIR=<extra-path> cmake . -Bbuild -# -# -#]] - - -#[[.rst -# -# Copyright ยฉ 2016, Edelcides Gonรงalves <eatg75 |0x40| gmail> -# -# Permission to use, copy, modify, and/or distribute this software for -# any purpose with or without fee is hereby granted, provided that the -# above copyright notice and this permission notice appear in all -# copies. -# -# *THE SOFTWARE IS PROVIDED* **AS IS** *AND ISC DISCLAIMS ALL -# WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE -# LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES -# OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR -# PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -# TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -# PERFORMANCE OF THIS SOFTWARE*. -# -# This file is not part of CMake -# -#]] - - -include (SelectLibraryConfigurations) -include (FindPackageHandleStandardArgs) - -function (_guile_find_component_include_dir component header) - find_path ("${component}_INCLUDE_DIR" - ${header} - HINTS - "${GUile_ROOT_DIR}" - ENV Guile_ROOT_DIR - PATH_SUFFIXES - Guile guile Guile-2.0 guile-2.0 Guile/2.0 guile/2.0 GC - gc) - - set ("${component}_INCLUDE_DIR" "${${component}_INCLUDE_DIR}" - PARENT_SCOPE) -endfunction () - -function (_guile_find_component_library component_name component) - - find_library ("${component_name}_LIBRARY_RELEASE" - NAMES "${component}" "${component}-2.0" - HINTS - "${GUile_ROOT_DIR}" - ENV Guile_ROOT_DIR - PATHS - /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE} - /usr/lib64/${CMAKE_LIBRARY_ARCHITECTURE} - /usr/lib32/${CMAKE_LIBRARY_ARCHITECTURE}) - - if (${component_name}_LIBRARY_RELEASE) - select_library_configurations (${component_name}) - set ("${component_name}_LIBRARY_RELEASE" - "${${component_name}_LIBRARY_RELEASE}" PARENT_SCOPE) - set ("${component_name}_LIBRARY" - "${${component_name}_LIBRARY}" PARENT_SCOPE) - set ("${component_name}_LIBRARIES" - "${${component_name}_LIBRARIES}" PARENT_SCOPE) - endif () -endfunction () - -function (_guile_find_version_2 header_file macro_name) - file (STRINGS "${header_file}" _VERSION - REGEX "#define[\t ]+${macro_name}[\t ]+[0-9]+") - - if (_VERSION) - string (REGEX REPLACE - ".*#define[\t ]+${macro_name}[\t ]+([0-9]+).*" - "\\1" _VERSION_VALUE "${_VERSION}") - if ("${_VERSION}" STREQUAL "${_VERSION_VALUE}") - set (_VERSION_FOUND 0 PARENT_SCOPE) - else () - set (_VERSION_FOUND 1 PARENT_SCOPE) - set (_VERSION "${_VERSION_VALUE}" PARENT_SCOPE) - endif () - else () - set (_VERSION_FOUND 0 PARENT_SCOPE) - endif () -endfunction () - - -##### Entry Point ##### - -set (Guile_FOUND) -set (Guile_INCLUDE_DIRS) -set (Guile_LIBRARIES) -set (Guile_VERSION_STRING) -set (Guile_VERSION_MAJOR) -set (Guile_VERSION_MINOR) -set (Guile_VERSION_PATCH) -set (Guile_EXECUTABLE) - -_guile_find_component_include_dir (Guile "libguile.h") -if (Guile_INCLUDE_DIR) - _guile_find_version_2 ("${Guile_INCLUDE_DIR}/libguile/version.h" - SCM_MAJOR_VERSION) - if (_VERSION_FOUND) - set (Guile_VERSION_MAJOR "${_VERSION}") - else () - message (FATAL_ERROR "FindGuile: Failed to find Guile_MAJOR_VERSION.") - endif () - - _guile_find_version_2 ("${Guile_INCLUDE_DIR}/libguile/version.h" - SCM_MINOR_VERSION) - if (_VERSION_FOUND) - set (Guile_VERSION_MINOR "${_VERSION}") - else () - message (FATAL_ERROR "FindGuile: Failed to find Guile_MINOR_VERSION.") - endif () - - _guile_find_version_2 ("${Guile_INCLUDE_DIR}/libguile/version.h" - SCM_MICRO_VERSION) - if (_VERSION_FOUND) - set (Guile_VERSION_PATCH "${_VERSION}") - else () - message (FATAL_ERROR "FindGuile: Failed to find Guile_MICRO_VERSION.") - endif () - set (Guile_VERSION_STRING "${Guile_VERSION_MAJOR}.${Guile_VERSION_MINOR}.${Guile_VERSION_PATCH}") - - unset (_VERSION_FOUND) - unset (_VERSION) -endif () - -_guile_find_component_include_dir (Guile_GC "gc.h") -_guile_find_component_library (Guile guile) -_guile_find_component_library (Guile_GC gc) - -find_program (Guile_EXECUTABLE - guile - DOC "Guile executable.") - -if (Guile_EXECUTABLE) - execute_process (COMMAND ${Guile_EXECUTABLE} --version - RESULT_VARIABLE _status - OUTPUT_VARIABLE _output - OUTPUT_STRIP_TRAILING_WHITESPACE) - - string (REGEX REPLACE ".*\\(GNU Guile\\)[\t ]+([0-9]+)\\..*" "\\1" - _guile_ver_major "${_output}") - - string (REGEX REPLACE ".*\\(GNU Guile\\)[\t ]+[0-9]+\\.([0-9]+).*" "\\1" - _guile_ver_minor "${_output}") - - string (REGEX REPLACE ".*\\(GNU Guile\\)[\t ]+[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" - _guile_ver_patch "${_output}") - - set (_version "${_guile_ver_major}.${_guile_ver_minor}.${_guile_ver_patch}") - - if (NOT Guile_FIND_QUIETLY) - if (NOT Guile_VERSION_STRING STREQUAL _version) - message (WARNING "FindGuile: Versions provided by library differs from the one provided by executable.") - endif () - - if (NOT _status STREQUAL "0") - message (WARNING "FindGuile: guile (1) process exited abnormally.") - endif () - endif () - - unset (_version) - unset (_status) - unset (_version) - unset (_guile_ver_major) - unset (_guile_ver_minor) - unset (_guile_ver_patch) -endif () - -find_package_handle_standard_args (GC - "FindGuile: Failed to find dependency GC." - Guile_GC_INCLUDE_DIR - Guile_GC_LIBRARY - Guile_GC_LIBRARIES - Guile_GC_LIBRARY_RELEASE) - -find_package_handle_standard_args (Guile - REQUIRED_VARS - Guile_INCLUDE_DIR - Guile_LIBRARY - Guile_LIBRARIES - Guile_LIBRARY_RELEASE - GC_FOUND - VERSION_VAR Guile_VERSION_STRING) - -if (Guile_FOUND) - list (APPEND Guile_INCLUDE_DIRS "${Guile_INCLUDE_DIR}" - "${Guile_GC_INCLUDE_DIR}") - - if (NOT TARGET Guile::Library AND NOT TARGET GC::Library) - add_library (Guile::GC::Library UNKNOWN IMPORTED) - set_property (TARGET Guile::GC::Library APPEND - PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - - set_target_properties (Guile::GC::Library - PROPERTIES - INTERFACE_INCLUDE_DIRS - "${Guile_GC_INCLUDE_DIR}" - IMPORTED_LOCATION - "${Guile_GC_LIBRARY}" - IMPORTED_LOCATION_RELEASE - "${Guile_GC_LIBRARY_RELEASE}") - - add_library (Guile::Library UNKNOWN IMPORTED) - set_property (TARGET Guile::Library APPEND - PROPERTY IMPORTED_CONFIGURATIONS RELEASE) - set_property (TARGET Guile::Library APPEND - PROPERTY - INTERFACE_LINK_LIBRARIES - Guile::GC::Library) - - set_target_properties (Guile::Library - PROPERTIES - INTERFACE_INCLUDE_DIRSr - "${Guile_INCLUDE_DIR}" - IMPORTED_LOCATION "${Guile_LIBRARY}" - IMPORTED_LOCATION_RELEASE - "${Guile_LIBRARY_RELEASE}") - - set (Guile_LIBRARIES Guile::Library Guile::GC::Library) - endif () -endif () - -find_program(Guile_CONFIG_EXECUTABLE - NAMES guile-config - DOC "Guile configutration binary") - -if (Guile_CONFIG_EXECUTABLE) - execute_process (COMMAND ${Guile_CONFIG_EXECUTABLE} info prefix - OUTPUT_VARIABLE Guile_ROOT_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) - - execute_process (COMMAND ${Guile_CONFIG_EXECUTABLE} info sitedir - OUTPUT_VARIABLE Guile_SITE_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) - - execute_process (COMMAND ${Guile_CONFIG_EXECUTABLE} info extensiondir - OUTPUT_VARIABLE Guile_EXTENSION_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE) -endif () - -mark_as_advanced (Guile_EXECUTABLE - Guile_INCLUDE_DIR - Guile_LIBRARY - Guile_LIBRARY_RELEASE - Guile_GC_INCLUDE_DIR - Guile_GC_LIBRARY - Guile_GC_LIBRARY_RELEASE) diff --git a/third_party/immer/cmake/FindRRB.cmake b/third_party/immer/cmake/FindRRB.cmake deleted file mode 100644 index 86b552f86e43..000000000000 --- a/third_party/immer/cmake/FindRRB.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# - Try to find c-rrb -# Once done, this will define -# -# RRB_FOUND - system has RRB -# RRB_INCLUDE_DIR - the RRB include directories -# RRB_LIBRARIES - link these to use RRB - -find_path(RRB_INCLUDE_DIR rrb.h) -find_library(RRB_LIBRARIES NAMES rrb librrb) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args( - RRB DEFAULT_MSG RRB_LIBRARIES RRB_INCLUDE_DIR) - -mark_as_advanced(RRB_INCLUDE_DIR RRB_LIBRARIES) diff --git a/third_party/immer/cmake/ImmerUtils.cmake b/third_party/immer/cmake/ImmerUtils.cmake deleted file mode 100644 index 2af63ff6061d..000000000000 --- a/third_party/immer/cmake/ImmerUtils.cmake +++ /dev/null @@ -1,24 +0,0 @@ - -function(immer_target_name_for out_target out_file file) - get_filename_component(_extension ${_file} EXT) - - file(RELATIVE_PATH _relative ${PROJECT_SOURCE_DIR} ${file}) - string(REPLACE "${_extension}" "" _name ${_relative}) - string(REGEX REPLACE "/" "-" _name ${_name}) - set(${out_target} "${_name}" PARENT_SCOPE) - - file(RELATIVE_PATH _relative ${CMAKE_CURRENT_LIST_DIR} ${file}) - string(REPLACE "${_extension}" "" _name ${_relative}) - string(REGEX REPLACE "/" "-" _name ${_name}) - set(${out_file} "${_name}" PARENT_SCOPE) -endfunction() - -function(immer_canonicalize_cmake_booleans) - foreach(var ${ARGN}) - if(${var}) - set(${var} 1 PARENT_SCOPE) - else() - set(${var} 0 PARENT_SCOPE) - endif() - endforeach() -endfunction() diff --git a/third_party/immer/codecov.yml b/third_party/immer/codecov.yml deleted file mode 100644 index ab21ebea5d98..000000000000 --- a/third_party/immer/codecov.yml +++ /dev/null @@ -1,2 +0,0 @@ -ignore: - - tools diff --git a/third_party/immer/default.nix b/third_party/immer/default.nix deleted file mode 100644 index f9225f9fd713..000000000000 --- a/third_party/immer/default.nix +++ /dev/null @@ -1,14 +0,0 @@ -{ pkgs, lib, ... }: - -pkgs.llvmPackages.libcxxStdenv.mkDerivation rec { - name = "immer-git"; - version = "git"; - src = ./.; - nativeBuildInputs = [ pkgs.cmake ]; - dontBuild = true; - meta = with lib; { - homepage = "https://github.com/arximboldi/immer"; - description = "Postmodern immutable data structures for C++"; - license = licenses.boost; - }; -} diff --git a/third_party/immer/doc/CMakeLists.txt b/third_party/immer/doc/CMakeLists.txt deleted file mode 100644 index 0b3d85c6ac1a..000000000000 --- a/third_party/immer/doc/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ - -# Targets -# ======= - -add_custom_target(doxygen - COMMAND doxygen doxygen.config - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/doc") - -add_custom_target(docs - COMMAND make html - WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/doc") -add_dependencies(docs doxygen) - -set(immer_ssh_method - ssh -p 5488 - -o StrictHostKeyChecking=no - -i ${CMAKE_SOURCE_DIR}/tools/travis/ssh-key) - -add_custom_target(upload-docs - COMMAND - rsync -av -e \"${immer_ssh_method}\" - ${CMAKE_SOURCE_DIR}/doc/_build/html/* - raskolnikov@sinusoid.es:public/immer/) diff --git a/third_party/immer/doc/Makefile b/third_party/immer/doc/Makefile deleted file mode 100644 index 101addd4ef25..000000000000 --- a/third_party/immer/doc/Makefile +++ /dev/null @@ -1,226 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help -help: - @echo "Please use \`make <target>' where <target> is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " epub3 to make an epub3" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - @echo " dummy to check syntax errors of document sources" - -.PHONY: clean -clean: - rm -rf $(BUILDDIR)/* - -.PHONY: html -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - bash sphinx-html-hack.bash - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -.PHONY: dirhtml -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -.PHONY: singlehtml -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -.PHONY: pickle -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -.PHONY: json -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -.PHONY: htmlhelp -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -.PHONY: qthelp -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/immer.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/immer.qhc" - -.PHONY: applehelp -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -.PHONY: devhelp -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/immer" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/immer" - @echo "# devhelp" - -.PHONY: epub -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -.PHONY: epub3 -epub3: - $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 - @echo - @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." - -.PHONY: latex -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -.PHONY: latexpdf -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: latexpdfja -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: text -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -.PHONY: man -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -.PHONY: texinfo -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -.PHONY: info -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -.PHONY: gettext -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -.PHONY: changes -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -.PHONY: linkcheck -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -.PHONY: doctest -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -.PHONY: coverage -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -.PHONY: xml -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -.PHONY: pseudoxml -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." - -.PHONY: dummy -dummy: - $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy - @echo - @echo "Build finished. Dummy builder generates no files." diff --git a/third_party/immer/doc/_static/logo-black.svg b/third_party/immer/doc/_static/logo-black.svg deleted file mode 100644 index 370e047c4b30..000000000000 --- a/third_party/immer/doc/_static/logo-black.svg +++ /dev/null @@ -1,100 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="437.76035" - height="141.89464" - viewBox="0 0 115.8241 37.542956" - version="1.1" - id="svg5447" - inkscape:version="0.92.1 r15371" - sodipodi:docname="logo-black.svg"> - <defs - id="defs5441" /> - <sodipodi:namedview - id="base" - pagecolor="#000000" - bordercolor="#8b8384" - borderopacity="1" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:zoom="0.35" - inkscape:cx="335.15011" - inkscape:cy="98.353481" - inkscape:document-units="mm" - inkscape:current-layer="g4502" - showgrid="false" - fit-margin-top="0" - fit-margin-left="0" - fit-margin-right="0" - fit-margin-bottom="0" - inkscape:window-width="1152" - inkscape:window-height="1080" - inkscape:window-x="1920" - inkscape:window-y="0" - inkscape:window-maximized="0" - units="px" /> - <metadata - id="metadata5444"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(6.8182189,-70.341619)"> - <g - id="g4502" - transform="matrix(0.45286986,0,0,0.45286986,18.570763,48.756461)"> - <g - id="g5321" - transform="matrix(0.28222223,0,0,0.28222223,263.62161,572.00923)" - style="fill:none;stroke:#ffffff"> - <g - style="fill:none;stroke:#ffffff;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none" - transform="translate(303.46093,-4.9296877)" - id="g5317"> - <path - id="rect5315" - style="opacity:1;fill:none;fill-opacity:1;stroke:#ffffff;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="m -1334.1996,-1796.9898 h 179.7406 v 179.7405 h -179.7406 z m -92,0 h 179.7406 v 179.7405 h -179.7406 z m 46,48 h 179.7406 v 179.7405 h -179.7406 z m 0,-94 h 179.7406 v 179.7405 h -179.7406 z m 0,48 h 179.7406 v 179.7405 h -179.7406 z" - inkscape:connector-curvature="0" /> - </g> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:3.62277412px;line-height:0%;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Heavy';letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.30189785px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="43.067963" - y="112.13454" - id="text5338"><tspan - sodipodi:role="line" - id="tspan5336" - x="43.067963" - y="112.13454" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:53.88218689px;line-height:1.25;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Bold';fill:#ffffff;stroke-width:0.30189785px">immer</tspan></text> - <rect - ry="0" - y="66.38237" - x="-37.756119" - height="7.9375" - width="7.9375" - id="rect5425" - style="opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:3.35253906;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - </g> -</svg> diff --git a/third_party/immer/doc/_static/logo-front.svg b/third_party/immer/doc/_static/logo-front.svg deleted file mode 100644 index b56393b9b1e1..000000000000 --- a/third_party/immer/doc/_static/logo-front.svg +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="1037.7604" - height="441.89462" - viewBox="0 0 274.57411 116.91795" - version="1.1" - id="svg5447" - inkscape:version="0.92.1 r15371" - sodipodi:docname="logo-front.svg"> - <defs - id="defs5441" /> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="0.35" - inkscape:cx="172.29297" - inkscape:cy="385.49612" - inkscape:document-units="mm" - inkscape:current-layer="layer1" - showgrid="false" - fit-margin-top="150" - fit-margin-left="300" - fit-margin-right="300" - fit-margin-bottom="150" - inkscape:window-width="1440" - inkscape:window-height="1080" - inkscape:window-x="1920" - inkscape:window-y="0" - inkscape:window-maximized="0" - units="px" /> - <metadata - id="metadata5444"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(86.193219,-30.654119)"> - <g - id="g4502" - transform="matrix(0.45286986,0,0,0.45286986,18.570763,48.756461)"> - <g - id="g5321" - transform="matrix(0.28222223,0,0,0.28222223,263.62161,572.00923)"> - <g - style="stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none" - transform="translate(303.46093,-4.9296877)" - id="g5317"> - <path - id="rect5315" - style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="m -1334.1996,-1796.9898 h 179.7406 v 179.7405 h -179.7406 z m -92,0 h 179.7406 v 179.7405 h -179.7406 z m 46,48 h 179.7406 v 179.7405 h -179.7406 z m 0,-94 h 179.7406 v 179.7405 h -179.7406 z m 0,48 h 179.7406 v 179.7405 h -179.7406 z" - inkscape:connector-curvature="0" /> - </g> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:3.62277412px;line-height:0%;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Heavy';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.30189785px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="43.067963" - y="112.13454" - id="text5338"><tspan - sodipodi:role="line" - id="tspan5336" - x="43.067963" - y="112.13454" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:53.88218689px;line-height:1.25;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Bold';stroke-width:0.30189785px">immer</tspan></text> - <rect - ry="0" - y="66.38237" - x="-37.756119" - height="7.9375" - width="7.9375" - id="rect5425" - style="opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:3.35253906;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - </g> -</svg> diff --git a/third_party/immer/doc/_static/logo.svg b/third_party/immer/doc/_static/logo.svg deleted file mode 100644 index 64bff0dde807..000000000000 --- a/third_party/immer/doc/_static/logo.svg +++ /dev/null @@ -1,99 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Created with Inkscape (http://www.inkscape.org/) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="437.76035" - height="141.89464" - viewBox="0 0 115.8241 37.542956" - version="1.1" - id="svg5447" - inkscape:version="0.92.1 r15371" - sodipodi:docname="logo.svg"> - <defs - id="defs5441" /> - <sodipodi:namedview - id="base" - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1.0" - inkscape:pageopacity="0.0" - inkscape:pageshadow="2" - inkscape:zoom="0.35" - inkscape:cx="-127.70703" - inkscape:cy="235.49612" - inkscape:document-units="mm" - inkscape:current-layer="layer1" - showgrid="false" - fit-margin-top="0" - fit-margin-left="0" - fit-margin-right="0" - fit-margin-bottom="0" - inkscape:window-width="1440" - inkscape:window-height="1080" - inkscape:window-x="1920" - inkscape:window-y="0" - inkscape:window-maximized="0" - units="px" /> - <metadata - id="metadata5444"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <g - inkscape:label="Layer 1" - inkscape:groupmode="layer" - id="layer1" - transform="translate(6.8182189,-70.341619)"> - <g - id="g4502" - transform="matrix(0.45286986,0,0,0.45286986,18.570763,48.756461)"> - <g - id="g5321" - transform="matrix(0.28222223,0,0,0.28222223,263.62161,572.00923)"> - <g - style="stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none" - transform="translate(303.46093,-4.9296877)" - id="g5317"> - <path - id="rect5315" - style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:20;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - d="m -1334.1996,-1796.9898 h 179.7406 v 179.7405 h -179.7406 z m -92,0 h 179.7406 v 179.7405 h -179.7406 z m 46,48 h 179.7406 v 179.7405 h -179.7406 z m 0,-94 h 179.7406 v 179.7405 h -179.7406 z m 0,48 h 179.7406 v 179.7405 h -179.7406 z" - inkscape:connector-curvature="0" /> - </g> - </g> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:900;font-stretch:normal;font-size:3.62277412px;line-height:0%;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Heavy';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.30189785px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" - x="43.067963" - y="112.13454" - id="text5338"><tspan - sodipodi:role="line" - id="tspan5336" - x="43.067963" - y="112.13454" - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:53.88218689px;line-height:1.25;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Bold';stroke-width:0.30189785px">immer</tspan></text> - <rect - ry="0" - y="66.38237" - x="-37.756119" - height="7.9375" - width="7.9375" - id="rect5425" - style="opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:3.35253906;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - </g> -</svg> diff --git a/third_party/immer/doc/_static/patreon.svg b/third_party/immer/doc/_static/patreon.svg deleted file mode 100644 index a8cc33975b21..000000000000 --- a/third_party/immer/doc/_static/patreon.svg +++ /dev/null @@ -1,120 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> - -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - version="1.1" - id="Layer_1" - x="0px" - y="0px" - viewBox="0 0 175.20599 88.309158" - xml:space="preserve" - sodipodi:docname="patreon.svg" - inkscape:version="0.92.2pre0 (973e216, 2017-07-25)" - width="175.20599" - height="88.309158"><metadata - id="metadata53"><rdf:RDF><cc:Work - rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title>support</dc:title></cc:Work></rdf:RDF></metadata><defs - id="defs51" /><sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1267" - inkscape:window-height="1054" - id="namedview49" - showgrid="false" - inkscape:zoom="1.672" - inkscape:cx="-2.5899259" - inkscape:cy="100.34184" - inkscape:window-x="0" - inkscape:window-y="26" - inkscape:window-maximized="0" - inkscape:current-layer="Layer_1" - fit-margin-left="16" - fit-margin-right="16" - fit-margin-bottom="16" - fit-margin-top="16" - showborder="true" /><style - type="text/css" - id="style2"> - .st0{fill:#E64825;} - .st1{fill:#FFFFFF;} - .st2{enable-background:new ;} -</style><title - id="title4">support</title><g - id="g4591" - transform="matrix(1.1623322,0,0,1.1623322,4.376678,-18.86997)"><rect - ry="5.3968496" - y="30.000004" - x="10" - height="48.444977" - width="123.20574" - id="rect4576" - style="opacity:1;vector-effect:none;fill:#f96854;fill-opacity:1;stroke:none;stroke-width:1.95915079;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /><g - transform="translate(9.401915,29.145936)" - id="g4574"><g - id="g4557" - transform="translate(-120.21531,7.9502949)"><path - id="path8" - d="m 143.8,12.9 h 0.7 c 6.4,0.2 11.5,5.6 11.3,12 -0.2,6.2 -5.1,11.1 -11.3,11.3 h -5.7 c 0,-3.9 0,-7.8 0,-11.7 0.1,-2.9 2.5,-5.3 5.4,-5.2 2.9,0.1 5.3,2.5 5.2,5.4 -0.1,2.9 -2.5,5.3 -5.4,5.2 -0.8,0 -1.7,-0.2 -2.4,-0.6 0,1.3 0,2.5 0,3.8 1.7,0.5 3.6,0.5 5.3,-0.1 4.7,-1.5 7.2,-6.6 5.6,-11.2 -1.5,-4.7 -6.6,-7.2 -11.2,-5.6 -3.6,1.2 -6,4.5 -6.1,8.3 0,3.9 0,7.8 0,11.7 h -2.8 v -12 c 0.1,-4 2.3,-7.6 5.6,-9.6 1.9,-1.1 3.8,-1.7 5.8,-1.7 z" - class="st1" - inkscape:connector-curvature="0" - style="fill:#ffffff" /><path - id="path10" - d="m 186.5,13.9 h 1.9 c 0,1.4 0,2.9 0,4.3 h 2.8 c 0,0.6 0,1.3 0,1.9 h -2.8 c 0,3.1 0,6.2 0,9.3 h -1.9 c 0,-3.1 0,-6.2 0,-9.3 h -1.1 c 0,-0.6 0,-1.3 0,-1.9 h 1.1 c 0,-1.4 -0.1,-2.9 0,-4.3 z" - class="st1" - inkscape:connector-curvature="0" - style="fill:#ffffff" /><path - id="path12" - d="m 177.5,17.8 c 3.3,-0.7 6.5,1.5 7.2,4.8 0,0.1 0,0.2 0,0.2 0.1,0.6 0.1,1.2 0.1,1.8 0,1.6 0,3.2 0,4.8 h -1.9 c 0,-0.4 0,-0.8 0,-1.2 -2.4,2.3 -6.3,2.2 -8.6,-0.2 -2.3,-2.4 -2.2,-6.3 0.2,-8.6 0.8,-0.9 1.9,-1.4 3,-1.6 z m 0.8,1.7 c -2.3,0.2 -4,2.3 -3.8,4.6 0,0.3 0.1,0.5 0.2,0.8 0.2,0.8 0.7,1.5 1.3,2 0.7,0.6 1.6,1 2.6,1 0.8,0 1.6,-0.1 2.3,-0.5 2,-1.2 2.7,-3.7 1.6,-5.8 -1,-1.4 -2.5,-2.2 -4.2,-2.1 z" - class="st1" - inkscape:connector-curvature="0" - style="fill:#ffffff" /><path - id="path14" - d="m 203.3,17.7 c 2,-0.3 4,0.5 5.3,1.9 l -7.9,6.6 c 1.4,1.9 4,2.3 5.9,0.9 1.3,-0.9 1.9,-2.5 1.7,-4 h 1.9 c 0.1,1.3 -0.2,2.6 -0.9,3.8 -0.5,0.9 -1.2,1.6 -2.1,2.1 -2.9,1.7 -6.6,0.8 -8.4,-2.1 -0.7,-1.1 -1,-2.4 -0.9,-3.6 0.1,-1 0.4,-2 1,-2.8 1.1,-1.5 2.6,-2.5 4.4,-2.8 z m -2.8,3.8 c -0.6,0.9 -0.8,2 -0.6,3 l 5.6,-4.7 c -0.3,-0.1 -0.7,-0.2 -1,-0.2 -1.6,-0.2 -3.1,0.6 -4,1.9 z" - class="st1" - inkscape:connector-curvature="0" - style="fill:#ffffff" /><path - id="path16" - d="m 216.6,17.7 c 1.3,-0.1 2.6,0.2 3.6,0.9 2.9,1.8 3.7,5.5 1.9,8.4 -1.8,2.9 -5.5,3.7 -8.4,1.9 -2.9,-1.8 -3.7,-5.5 -1.9,-8.4 0.5,-0.8 1.2,-1.5 2,-2 0.9,-0.5 1.8,-0.8 2.8,-0.8 z m 0.1,1.8 c -2.3,0.2 -4.1,2.2 -3.9,4.5 0.2,2.3 2.2,4.1 4.5,3.9 2.3,-0.2 4.1,-2.2 3.9,-4.5 -0.1,-1.2 -0.7,-2.4 -1.7,-3.1 -0.8,-0.6 -1.8,-0.8 -2.8,-0.8 z" - class="st1" - inkscape:connector-curvature="0" - style="fill:#ffffff" /><path - id="path18" - d="m 226,18.9 c 1.2,-1.1 2.8,-1.5 4.3,-1.1 1.2,0.3 2.2,1 2.9,1.9 0.6,0.8 1,1.8 1,2.8 0,1.5 0,3 0,4.6 v 2.2 h -1.9 c 0,-2.2 0,-4.5 0,-6.7 0,-1.1 -0.6,-2.1 -1.5,-2.6 -0.8,-0.5 -1.8,-0.6 -2.7,-0.3 -1.1,0.4 -1.9,1.5 -2.1,2.7 0,0.5 0,1 0,1.6 0,1.8 0,3.6 0,5.4 h -1.9 c 0,-3.7 0,-7.4 0,-11.1 h 1.9 c 0,0.1 0,0.3 0,0.6 z" - class="st1" - inkscape:connector-curvature="0" - style="fill:#ffffff" /><path - id="path20" - d="m 161.1,20 c 2.1,-2.6 5.9,-3.1 8.6,-1 2.6,2.1 3.1,5.9 1,8.6 -1.1,1.3 -2.6,2.2 -4.3,2.3 -1,0.1 -2,-0.1 -2.8,-0.6 -0.7,-0.3 -1.3,-0.8 -1.8,-1.3 0,1.9 0,3.8 0,5.7 h -1.9 c 0,-3.3 0,-6.6 0,-9.9 -0.1,-1.4 0.4,-2.7 1.2,-3.8 z m 4,-0.4 c -2.3,0.4 -3.8,2.6 -3.4,4.9 0.4,2.3 2.6,3.8 4.9,3.4 2.3,-0.4 3.8,-2.6 3.4,-4.9 -0.2,-1.2 -1,-2.3 -2,-2.9 -0.9,-0.5 -1.9,-0.7 -2.9,-0.5 z" - class="st1" - inkscape:connector-curvature="0" - style="fill:#ffffff" /><path - id="path22" - d="m 192,18.2 h 1.8 c 0,0.6 0,1.1 0,1.7 1.2,-1.1 2.8,-1.8 4.4,-1.7 0,0.6 0,1.3 0,1.9 -2.3,-0.1 -4.3,1.7 -4.4,4.1 0,0 0,0.1 0,0.1 0,1.7 0,3.4 0,5.1 H 192 c 0.1,-3.8 0,-7.5 0,-11.2 z" - class="st1" - inkscape:connector-curvature="0" - style="fill:#ffffff" /></g><text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.8520174px;line-height:4.5em;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro';text-align:end;letter-spacing:0px;word-spacing:0px;text-anchor:end;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.73991024" - x="114.89897" - y="14.870183" - id="text4561"><tspan - sodipodi:role="line" - id="tspan4559" - x="114.89897" - y="14.870183" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro';fill:#ffffff;stroke-width:0.73991024">support us on</tspan></text> -</g></g></svg> \ No newline at end of file diff --git a/third_party/immer/doc/_static/sinusoidal-badge.svg b/third_party/immer/doc/_static/sinusoidal-badge.svg deleted file mode 100644 index 0282a2f7a41f..000000000000 --- a/third_party/immer/doc/_static/sinusoidal-badge.svg +++ /dev/null @@ -1,166 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<svg - xmlns:dc="http://purl.org/dc/elements/1.1/" - xmlns:cc="http://creativecommons.org/ns#" - xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" - xmlns:svg="http://www.w3.org/2000/svg" - xmlns="http://www.w3.org/2000/svg" - xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" - xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" - width="350" - height="20" - version="1.1" - id="svg28" - sodipodi:docname="sinusoidal-badge.svg" - inkscape:version="0.92.2pre0 (973e216, 2017-07-25)"> - <metadata - id="metadata34"> - <rdf:RDF> - <cc:Work - rdf:about=""> - <dc:format>image/svg+xml</dc:format> - <dc:type - rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> - <dc:title></dc:title> - </cc:Work> - </rdf:RDF> - </metadata> - <defs - id="defs32"> - <marker - inkscape:isstock="true" - style="overflow:visible" - id="Arrow1Lstart" - refX="0" - refY="0" - orient="auto" - inkscape:stockid="Arrow1Lstart"> - <path - inkscape:connector-curvature="0" - transform="matrix(0.8,0,0,0.8,10,0)" - style="fill:#444444;fill-opacity:1;fill-rule:evenodd;stroke:#444444;stroke-width:1.00000003pt;stroke-opacity:1" - d="M 0,0 5,-5 -12.5,0 5,5 Z" - id="path10186" /> - </marker> - </defs> - <sodipodi:namedview - pagecolor="#ffffff" - bordercolor="#666666" - borderopacity="1" - objecttolerance="10" - gridtolerance="10" - guidetolerance="10" - inkscape:pageopacity="0" - inkscape:pageshadow="2" - inkscape:window-width="1267" - inkscape:window-height="1054" - id="namedview30" - showgrid="false" - inkscape:zoom="1" - inkscape:cx="89.411561" - inkscape:cy="-177.54677" - inkscape:window-x="0" - inkscape:window-y="26" - inkscape:window-maximized="0" - inkscape:current-layer="g26" /> - <linearGradient - id="b" - x2="0" - y2="1"> - <stop - offset="0" - stop-color="#bbb" - stop-opacity=".1" - id="stop2" /> - <stop - offset="1" - stop-opacity=".1" - id="stop4" /> - </linearGradient> - <mask - id="a"> - <rect - width="96" - height="20" - rx="3" - id="rect7" - x="0" - y="0" - style="fill:#ffffff" /> - </mask> - <g - font-size="11" - id="g26" - style="font-size:11px;font-family:'DejaVu Sans', Verdana, Geneva, sans-serif;text-anchor:middle;fill:#000000"> - <text - x="30" - y="15" - id="text18" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro';fill:#000000;fill-opacity:0.3" /> - <text - xml:space="preserve" - style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:14.66666698px;line-height:4.5em;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro';text-align:start;letter-spacing:0px;word-spacing:0px;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none" - x="52.626465" - y="14.072" - id="text843"><tspan - sodipodi:role="line" - id="tspan841" - x="52.626465" - y="14.072" - style="font-size:13.33333397px"><tspan - style="font-style:normal;font-variant:normal;font-weight:300;font-stretch:normal;font-size:13.33333397px;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Light'" - id="tspan859">quality libre software by</tspan><tspan - style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:13.33333397px;font-family:'Source Sans Pro';-inkscape-font-specification:'Source Sans Pro Bold'" - id="tspan4711"> </tspan><tspan - style="font-weight:bold;font-size:13.33333397px" - id="tspan849">sinusoidal engineering</tspan></tspan></text> - <g - transform="matrix(4.4383113,0,0,4.4383113,-73.95876,-379.69787)" - id="layer1" - inkscape:label="Layer 1"> - <g - id="g10518" - transform="matrix(0.07290361,0,0,0.07290361,90.22887,85.474692)"> - <g - id="g906" - transform="matrix(0.8913912,0,0,0.8913912,6.4029255,3.518587)"> - <g - transform="translate(2.9886077,2.3730299)" - style="stroke-width:6;stroke-miterlimit:4;stroke-dasharray:none" - id="g10505"> - <g - transform="matrix(0.28222223,0,0,0.28222223,237.85811,-1729.1481)" - style="stroke:#444444;stroke-width:32.14861298;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - id="g6292"> - <rect - y="6129.2646" - x="-842.80432" - height="206.24994" - width="206.25005" - id="rect6290" - style="opacity:1;fill:none;fill-opacity:1;stroke:#444444;stroke-width:32.14861298;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - </g> - <path - id="path6294" - title="sin(x/2)" - d="m 55.5625,0.66666667 c -0.928371,0 -1.856705,0.13319437 -2.785079,0.39715343 -0.928371,0.2636873 -1.856744,0.6592201 -2.785077,1.1798418 -0.928372,0.5208916 -1.856743,1.1674139 -2.785116,1.9309205 -0.928334,0.7632369 -1.856705,1.6439988 -2.785078,2.6290465 -0.928372,0.9850477 -1.856743,2.0754629 -2.785077,3.2555751 -0.928372,1.180112 -1.856744,2.450461 -2.785115,3.793218 -0.928336,1.342755 -1.856706,2.758458 -2.785077,4.227385 -0.928374,1.469197 -1.856708,2.991617 -2.785079,4.546459 -0.928372,1.555111 -1.856744,3.142642 -2.785115,4.741252 -0.928334,1.598609 -1.856707,3.208295 -2.785078,4.806905 -0.928371,1.598608 -1.856705,3.18614 -2.785079,4.741251 -0.928371,1.555112 -1.856705,3.077263 -2.785077,4.546188 -0.928408,1.469197 -1.856743,2.88463 -2.785079,4.227655 -0.928407,1.342757 -1.856742,2.612837 -2.785115,3.793218 -0.928334,1.180113 -1.856705,2.270258 -2.785077,3.255575 -0.928372,0.985319 -1.856742,1.86554 -2.785113,2.629047 -0.928337,0.763506 -1.8567441,1.409758 -2.785079,1.93092 C 7.2876175,57.819171 6.3592466,58.214164 5.4308755,58.478121 4.5025393,58.742347 3.5742044,58.875 2.6458333,58.875" - style="opacity:1;fill:none;fill-opacity:1;stroke:#444444;stroke-width:9.07305336;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - inkscape:connector-curvature="0" /> - </g> - <circle - r="7.2447839" - cy="2.9294415" - cx="61.518147" - id="ellipse10510" - style="opacity:1;fill:#f0544c;fill-opacity:1;stroke:#ffffff;stroke-width:5.44383192;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /> - <circle - style="opacity:1;fill:#444444;fill-opacity:1;stroke:#ffffff;stroke-width:5.44383192;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" - id="circle898" - cx="2.0896502" - cy="61.450638" - r="7.2447839" /> - </g> - </g> - </g> - </g> -</svg> diff --git a/third_party/immer/doc/algorithms.rst b/third_party/immer/doc/algorithms.rst deleted file mode 100644 index f7de519c05d9..000000000000 --- a/third_party/immer/doc/algorithms.rst +++ /dev/null @@ -1,28 +0,0 @@ - -Algorithms -========== - -This module provides overloads of standard algorithms that leverage -the internal structure of the immutable containers to provide faster -iteration. These are drop-in replacements of the respective STL -algorithms that can be a few times faster when applied on immutable -sequences. - -For further convenience they can be passed in just a container where -the standard library algorithms require being passed in two iterators. - -.. note:: - - They are a similar idea to `structure-aware iterators`_ - but implemented using higher order functions in order to support - structures of any depth. The downside is that this sometimes - causes the compiler to generate bigger executable files. - -.. _structure-aware iterators: https://www.youtube.com/watch?v=T3oA3zAMH9M - - ------ - -.. doxygengroup:: algorithm - :project: immer - :content-only: diff --git a/third_party/immer/doc/conf.py b/third_party/immer/doc/conf.py deleted file mode 100644 index 3c32cc505ba3..000000000000 --- a/third_party/immer/doc/conf.py +++ /dev/null @@ -1,452 +0,0 @@ -# -*- coding: utf-8 -*- -# -# immer documentation build configuration file, created by -# sphinx-quickstart on Thu Oct 27 18:10:24 2016. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# -# needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx.ext.mathjax', - 'breathe', -] - -breathe_projects = { "immer": "_doxygen/xml" } -breathe_default_project = "immer" - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -from recommonmark.parser import CommonMarkParser -from recommonmark.transform import AutoStructify -source_parsers = { '.md': CommonMarkParser, } -source_suffix = ['.rst', '.md'] - -def setup(app): - app.add_config_value('recommonmark_config', { - 'enable_eval_rst': True, - }, True) - app.add_transform(AutoStructify) - -# The encoding of source files. -# -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'immer' -copyright = u'2016, 2017 Juan Pedro Bolivar Puente' -author = u'Juan Pedro Bolivar Puente' - -raw_enabled = True - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = u'0.0.0' -# The full version, including alpha/beta/rc tags. -release = u'0.0.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# -# This is also used if you do content translation via gettext catalogs. -# Usually you set "language" from the command line for these cases. -language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# -# today = '' -# -# Else, today_fmt is used as the format for a strftime call. -# -# today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This patterns also effect to html_static_path and html_extra_path -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -# modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -# keep_warnings = False - -# If true, `todo` and `todoList` produce output, else they produce nothing. -todo_include_todos = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# - -import sys -import os.path -sys.path.append(os.path.join(os.path.dirname(__file__), - '../tools/sinusoidal-sphinx-theme')) - -import sinusoidal_sphinx_theme -html_theme_path = sinusoidal_sphinx_theme.html_theme_path() -html_theme = 'sinusoidal_sphinx_theme' -extensions.append("sinusoidal_sphinx_theme") -html_theme_options = { - "project_nav_name": "immer", - "github_link" : "https://github.com/arximboldi/immer", -} - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -# html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. -# "<project> v<release> documentation" by default. -# -# html_title = u'immer v0.0.0' - -# A shorter title for the navigation bar. Default is the same as html_title. -# -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# -html_logo = '_static/logo-black.svg' - -# The name of an image file (relative to this directory) to use as a favicon of -# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# -# html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# -# html_extra_path = [] - -# If not None, a 'Last updated on:' timestamp is inserted at every page -# bottom, using the given strftime format. -# The empty string is equivalent to '%b %d, %Y'. -# -# html_last_updated_fmt = None - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# -# html_additional_pages = {} - -# If false, no module index is generated. -# -# html_domain_indices = True - -# If false, no index is generated. -# -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a <link> tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Language to be used for generating the HTML full-text search index. -# Sphinx supports the following languages: -# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' -# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' -# -# html_search_language = 'en' - -# A dictionary with options for the search language support, empty by default. -# 'ja' uses this config value. -# 'zh' user can custom change `jieba` dictionary path. -# -# html_search_options = {'type': 'default'} - -# The name of a javascript file (relative to the configuration directory) that -# implements a search results scorer. If empty, the default will be used. -# -# html_search_scorer = 'scorer.js' - -# Output file base name for HTML help builder. -htmlhelp_basename = 'immerdoc' - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # - # 'papersize': 'letterpaper', - - # The font size ('10pt', '11pt' or '12pt'). - # - # 'pointsize': '10pt', - - # Additional stuff for the LaTeX preamble. - # - # 'preamble': '', - - # Latex figure (float) alignment - # - # 'figure_align': 'htbp', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - (master_doc, 'immer.tex', u'immer Documentation', - u'Juan Pedro Bolivar Puente', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# -# latex_use_parts = False - -# If true, show page references after internal links. -# -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# -# latex_appendices = [] - -# It false, will not define \strong, \code, itleref, \crossref ... but only -# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added -# packages. -# -# latex_keep_old_macro_names = True - -# If false, no module index is generated. -# -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - (master_doc, 'immer', u'immer Documentation', - [author], 1) -] - -# If true, show URL addresses after external links. -# -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - (master_doc, 'immer', u'immer Documentation', - author, 'immer', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -# -# texinfo_appendices = [] - -# If false, no module index is generated. -# -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# -# texinfo_no_detailmenu = False - - -# -- Options for Epub output ---------------------------------------------- - -# Bibliographic Dublin Core info. -epub_title = project -epub_author = author -epub_publisher = author -epub_copyright = copyright - -# The basename for the epub file. It defaults to the project name. -# epub_basename = project - -# The HTML theme for the epub output. Since the default themes are not -# optimized for small screen space, using the same theme for HTML and epub -# output is usually not wise. This defaults to 'epub', a theme designed to save -# visual space. -# -# epub_theme = 'epub' - -# The language of the text. It defaults to the language option -# or 'en' if the language is not set. -# -# epub_language = '' - -# The scheme of the identifier. Typical schemes are ISBN or URL. -# epub_scheme = '' - -# The unique identifier of the text. This can be a ISBN number -# or the project homepage. -# -# epub_identifier = '' - -# A unique identification for the text. -# -# epub_uid = '' - -# A tuple containing the cover image and cover page html template filenames. -# -# epub_cover = () - -# A sequence of (type, uri, title) tuples for the guide element of content.opf. -# -# epub_guide = () - -# HTML files that should be inserted before the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# -# epub_pre_files = [] - -# HTML files that should be inserted after the pages created by sphinx. -# The format is a list of tuples containing the path and title. -# -# epub_post_files = [] - -# A list of files that should not be packed into the epub file. -epub_exclude_files = ['search.html'] - -# The depth of the table of contents in toc.ncx. -# -# epub_tocdepth = 3 - -# Allow duplicate toc entries. -# -# epub_tocdup = True - -# Choose between 'default' and 'includehidden'. -# -# epub_tocscope = 'default' - -# Fix unsupported image types using the Pillow. -# -# epub_fix_images = False - -# Scale large images. -# -# epub_max_image_width = 0 - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# -# epub_show_urls = 'inline' - -# If false, no index is generated. -# -# epub_use_index = True diff --git a/third_party/immer/doc/containers.rst b/third_party/immer/doc/containers.rst deleted file mode 100644 index c6913ba4a5e5..000000000000 --- a/third_party/immer/doc/containers.rst +++ /dev/null @@ -1,50 +0,0 @@ -.. highlight:: c++ - -Containers -========== - -This section describes all the containers provided by the library. -Check the :ref:`design` section for a general discussion of these -containers and how to use them. - -box ---- - -.. doxygenclass:: immer::box - :members: - :undoc-members: - -array ------ - -.. doxygenclass:: immer::array - :members: - :undoc-members: - -vector ------- - -.. doxygenclass:: immer::vector - :members: - :undoc-members: - -flex_vector ------------ - -.. doxygenclass:: immer::flex_vector - :members: - :undoc-members: - -set ---- - -.. doxygenclass:: immer::set - :members: - :undoc-members: - -map ---- - -.. doxygenclass:: immer::map - :members: - :undoc-members: diff --git a/third_party/immer/doc/design.rst b/third_party/immer/doc/design.rst deleted file mode 100644 index 27d29e9e617a..000000000000 --- a/third_party/immer/doc/design.rst +++ /dev/null @@ -1,268 +0,0 @@ -.. _design: - -Design -====== - -This is a library of **immutable containers**. - -These containers have all their methods marked ``const``. Instead of -mutating them *in place*, they provide manipulation functions that -*return a new transformed value*, leaving the original value -unaltered. In the context of data-structures, this property of -preserving old values is called **persistence**. - -Most of these containers use data-structures in which these operations -can be done *efficiently*. In particular, not all data is copied when -a new value is produced. Instead, the new values may share, -internally, common data with other objects. We sometimes refer to -this property as **structural sharing**. This behaviour is -transparent to the user. - -Assigment ---------- - -We are sorry, we lied. These containers provide *one mutating -operation*: **assignment** --- i.e. ``operator=``. - -There is a good reason: without ``operator=`` everything becomes -complicated in C++. For example, one may not contain non-assignable -types in many standard containers, assignment would also be disabled -from your custom types holding immutable containers, and so on and so -forth. - -C++ is a multi-paradigm language with an imperative core. Thus, it is -built on the foundation that *variables* can be mutated --- -i.e. assigned to. We don't want to ride against this tide. What we -want to prevent is in-place *object* manipulation. Because of C++ -semantics, *variable* assignment is defined in terms of *object -mutation*, so we have to provide *this very particular mutating -operation*, but nothing else. Of course, you are free to mark your -variables ``const`` to completely forbid assignment. - -.. warning:: - - **Assignment is not thread safe**. When a *mutable* variable is - shared across multiple threads, protect access using some other - mechanism. - - For obvious reasons, all other methods, which are ``const``, are - thread-safe. It is safe to share *immutable* state across multiple - threads. - -To ``const`` or not to ``const`` --------------------------------- - -Many C++ programmers, influenced by functional programming, are trying -to escape the evils of mutability by using ``const`` whenever -possible. We also do it ourselves in many of our examples to -reinforce the property of immutability. - -While in general this is a good practice backed up with very good -intentions, it has one caveat: *it disables moveability*. It does so -even when ``std::move()`` is used. This makes sense, since moving from -an object may mutate it, and ``const``, my friends, prevents *all* -mutations. For example: - -.. literalinclude:: ../example/vector/move.cpp - :language: c++ - :start-after: move-bad/start - :end-before: move-bad/end - -One may think that the variable ``v`` is moved into the -``push_back()`` call. This is not the case, because the variable -``v`` is marked ``const``. Of course, one may enable the move by -removing it, as in: - -.. literalinclude:: ../example/vector/move.cpp - :language: c++ - :start-after: move-good/start - :end-before: move-good/end - -So, is it bad style then to use ``const`` as much as possible? I -wouldn't say so and it is advisable when ``std::move()`` is not used. -An alternative style is to not use ``const`` but adopt an `AAA-style -<aaa>`_ (*Almost Always use Auto*). This way, it is easy to look for -mutations by looking for lines that contain ``=`` but no ``auto``. -Remember that when using our immutable containers ``operator=`` is the -only way to mutate a variable. - -.. _aaa: https://herbsutter.com/2013/08/12/gotw-94-solution-aaa-style-almost-always-auto/ - -.. admonition:: Why does ``const`` prevent move semantics? - - For those adventurous into the grainy details C++, here is why. - ``std::move()`` does not move anything, it is just *a cast* from - normal *l-value* references (``T&``) to *r-value* reference - (``T&&``). This is, you pass it a variable, and it returns a - reference to its object disguised as an intermediate result. In - exchange, you promise not to do anything with this variable later - [#f1]_. It is the role of the thing that *receives the moved-from - value* (in the previous example, ``push_back``) to actually do - anything interesting with it --- for example, steal its contents - ๐. - - So if you pass a ``T&`` to ``std::move()`` you get a ``T&&`` and, - unsurprisingly, if you pass a ``const T&`` you get a ``const T&&``. - But the receivers of the moved-from value (like constructors or our - ``push_back()``) maybe be moved-into because they provide an - overload that expects ``T&&`` --- without the ``const``! Since a - ``const T&&`` can not be converted into a ``T&&``, the compiler - looks up for you another viable overload, and most often finds a - copy constructor or something alike that expects a ``const T&`` or - just ``T``, to which a ``const T&&`` can be converted. The code - compiles and works correctly, but it is less efficient than we - expected. Our call to ``std::move()`` was fruitless. - - .. [#f1] For the sake of completeness: it is actually allowed to do stuff - with the variable *after another value is assigned to it*. - -.. _move-semantics: - -Leveraging move semantics -------------------------- - -When using :ref:`reference counting<rc>` (which is the default) -mutating operations can often be faster when operating on *r-value -references* (temporaries and moved-from values). Note that this -removes *persistence*, since one can not access the moved-from value -anymore! However, this may be a good idea when doing a chain of -operations where the intermediate values are not important to us. - -For example, let's say we want to write a function that inserts all -integers in the range :math:`[first, last)` into an immutable vector. -From the point of view of the caller of the function, this function is -a *transaction*. Whatever intermediate vectors are generated inside -of it can be discarded since the caller can only see the initial -vector (the one passed in as argument) and the vector with *all* the -elements. We may write such function like this: - -.. literalinclude:: ../example/vector/iota-move.cpp - :language: c++ - :start-after: myiota/start - :end-before: myiota/end - -The intermediate values are *moved* into the next ``push_back()`` -call. They are going to be discarded anyways, this little -``std::move`` just makes the whole thing faster, letting ``push_back`` -mutate part of the internal data structure in place when possible. - -If you don't like this syntax, :doc:`transients<transients>` may be -used to obtain similar performance benefits. - -.. admonition:: Assigment guarantees - - From the language point of view, the only requirement on moved from - values is that they should still be destructible. We provide the - following two additional guarantees: - - - **It is valid to assign to a moved-from variable**. The variable - gets the assigned value and becomes usable again. This is the - behaviour of standard types. - - - **It is valid to assign a moved-from variable to itself**. For - most standard types this is *undefined behaviour*. However, for our - immutable containers types, expressions of the form ``v = - std::move(v)`` are well-defined. - -Recursive types ---------------- - -Most containers will fail to be instantiated with a type of unknown -size, this is, an *incomplete type*. This prevents using them for -building recursive types. The following code fails to compile: - -.. code-block:: c++ - - struct my_type - { - int data; - immer::vector<my_type> children; - }; - -However, we can easily workaround this by using an ``immer::box`` to wrap -the elements in the vector, as in: - -.. code-block:: c++ - - struct my_type - { - int data; - immer::vector<immer::box<my_type>> children; - }; - -.. admonition:: Standard containers and incomplete types - - While the first example might seem to compile when using some - implementations of ``std::vector`` instead of ``immer::vector``, such - use is actually forbidden by the standard: - - **17.6.4.8** *Other functions (...)* 2. the effects are undefined in - the following cases: (...) In particular---if an incomplete type (3.9) - is used as a template argument when instantiating a template - component, unless specifically allowed for that component. - -.. _batch-update: -Efficient batch manipulations ------------------------------ - -Sometimes you may write a function that needs to do multiple changes -to a container. Like most code you write with this library, this -function is *pure*: it takes one container value in, and produces a -new container value out, no side-effects. - -Let's say we want to write a function that inserts all integers in the -range :math:`[first, last)` into an immutable vector: - -.. literalinclude:: ../example/vector/iota-slow.cpp - :language: c++ - :start-after: include:myiota/start - :end-before: include:myiota/end - -This function works as expected, but it is slower than necessary. -On every loop iteration, a new value is produced, just to be -forgotten in the next iteration. - -Instead, we can grab a mutable view on the value, a :ref:`transient`. -Then, we manipulate it *in-place*. When we are done with it, we -extract back an immutable value from it. The code now looks like -this: - -.. _iota-transient: - -.. literalinclude:: ../example/vector/iota-transient.cpp - :language: c++ - :start-after: include:myiota/start - :end-before: include:myiota/end - -Both conversions are :math:`O(1)`. Note that calling ``transient()`` -does not break the immutability of the variable it is called on. The -new mutable object will adopt its contents, but when a mutation is -performed, it will copy the data necessary using *copy on write*. -Subsequent manipulations may hit parts that have already been copied, -and these changes are done in-place. Because of this, it does not -make sense to use transients to do only one change. - -.. tip:: - - Note that :ref:`move semantics<move-semantics>` can be used instead to - support a similar use-case. However, transients optimise updates - even when reference counting is disabled. - -.. _std-compat: -Standard library compatibility ------------------------------- - -While the immutable containers provide an interface that follows a -functional style, this is incompatible with what the standard library -algorithms sometimes expect. :ref:`transients` try to provide an -interface as similar as possible to similar standard library -containers. Thus, can also be used to interoperate with standard -library components. - -For example the :ref:`myiota() function above<iota-transient>` may as -well be written using standard library tools: - -.. literalinclude:: ../example/vector/iota-transient-std.cpp - :language: c++ - :start-after: include:myiota/start - :end-before: include:myiota/end diff --git a/third_party/immer/doc/doxygen.config b/third_party/immer/doc/doxygen.config deleted file mode 100644 index b6002b8d8f07..000000000000 --- a/third_party/immer/doc/doxygen.config +++ /dev/null @@ -1,23 +0,0 @@ -PROJECT_NAME = "immer" -OUTPUT_DIRECTORY = _doxygen -GENERATE_LATEX = NO -GENERATE_MAN = NO -GENERATE_RTF = NO -GENERATE_HTML = NO -GENERATE_XML = YES -INPUT = \ - ../immer \ - ../immer/heap \ - ../immer/refcount \ - ../immer/transience -INCLUDE_PATH = .. -QUIET = YES - -JAVADOC_AUTOBRIEF = YES -ENABLE_PREPROCESSING = YES -MARKDOWN_SUPPORT = YES -MACRO_EXPANSION = YES - -ALIASES = "rst=\verbatim embed:rst:leading-asterisk\n" -ALIASES += "endrst=\n\endverbatim" -ALIASES += "rst{1}=\rst\1\endrst" diff --git a/third_party/immer/doc/guile.rst b/third_party/immer/doc/guile.rst deleted file mode 120000 index dfda6df878f4..000000000000 --- a/third_party/immer/doc/guile.rst +++ /dev/null @@ -1 +0,0 @@ -../extra/guile/README.rst \ No newline at end of file diff --git a/third_party/immer/doc/implementation.rst b/third_party/immer/doc/implementation.rst deleted file mode 100644 index 3bfdd9c2b812..000000000000 --- a/third_party/immer/doc/implementation.rst +++ /dev/null @@ -1,6 +0,0 @@ -Implementation overview -======================= - -.. image:: https://upload.wikimedia.org/wikipedia/commons/e/e6/%22Work_in_progress%22%2C_animated.gif - :alt: Work in Progress - :align: center diff --git a/third_party/immer/doc/index.rst b/third_party/immer/doc/index.rst deleted file mode 100644 index 311549c74bcd..000000000000 --- a/third_party/immer/doc/index.rst +++ /dev/null @@ -1,31 +0,0 @@ - -.. include:: ../README.rst - :end-before: include:index/end - -Contents --------- - -.. toctree:: - :caption: User Manual - :maxdepth: 3 - - introduction - design - containers - transients - algorithms - utilities - memory - -.. toctree:: - :caption: Experimental - :maxdepth: 3 - - python - guile - ----- - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` diff --git a/third_party/immer/doc/introduction.rst b/third_party/immer/doc/introduction.rst deleted file mode 100644 index 2445cf9df823..000000000000 --- a/third_party/immer/doc/introduction.rst +++ /dev/null @@ -1,6 +0,0 @@ - -Introduction -============ - -.. include:: ../README.rst - :start-after: include:introduction/start diff --git a/third_party/immer/doc/memory.rst b/third_party/immer/doc/memory.rst deleted file mode 100644 index 3138b249f3f3..000000000000 --- a/third_party/immer/doc/memory.rst +++ /dev/null @@ -1,204 +0,0 @@ -Memory management -================= - -Memory management is specially important for immutable data -structures. This is mainly due to: - -#. In order to preserve the old value, new memory has to be allocated - to store the new data whenever a container is manipulated. Thus, - more allocations are performed *when changing* than with traditional - mutable data structures. - -#. In order to support *structural sharing* transparently, some kind - of garbage collection mechanism is required. Passing immutable - data structures around is, internally, just passing references, - thus the system needs to figure out somehow when old values are not - referenced anymore and should be deallocated. - -Thus, most containers in this library can be customized via policies_ -in order to use different *allocation* and *garbage collection* -strategies. - -.. doxygentypedef:: immer::default_memory_policy -.. doxygentypedef:: immer::default_heap_policy -.. doxygentypedef:: immer::default_refcount_policy - -.. _policies: https://en.wikipedia.org/wiki/Policy-based_design - -.. _memory policy: - -Memory policy -------------- - -.. doxygenstruct:: immer::memory_policy - :members: - :undoc-members: - -.. _gc: - -Example: tracing garbage collection -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -It is note worthy that all aspects of a -:cpp:class:`immer::memory_policy` are not completely orthogonal. - -Let's say you want to use a `tracing garbage collector`_. Actually, we -already provide :cpp:class:`a heap <immer::gc_heap>` that interfaces -with the `Boehm's conservative garbage collector`_. Chunks of memory -allocated with this heap do not need to be deallocated, instead, after -a certain number of allocations, the heap itself will scan the stack -and all allocated memory to find references to other blocks of memory. -The memory that is not referenced anymore is automatically *freed*. -Thus, no reference counting mechanism is needed, and it makes no sense -to use this heap with anything else than the -:cpp:class:`immer::no_refcount_policy`. Also, a big object can be -separated in parts that contain pointers and parts that do not, which -make scanning references faster. So it makes most sense to use -``prefer_fewer_bigger_objects = false``. - -.. note:: There are few considerations to note when using - :cpp:class:`gc_heap` with containers. Please make sure to - read :cpp:class:`its documentation section <immer::gc_heap>` - before using it. - -.. literalinclude:: ../example/vector/gc.cpp - :language: c++ - :start-after: example/start - :end-before: example/end - - -.. _boehm's conservative garbage collector: https://github.com/ivmai/bdwgc -.. _tracing garbage collector: https://en.wikipedia.org/wiki/Tracing_garbage_collection - -Heaps ------ - -A **heap policy** is a `metafunction class`_ that given the sizes of -the objects that we want to allocate, it *returns* a heap that can -allocate objects of those sizes. - -.. _metafunction class: http://www.boost.org/doc/libs/1_62_0/libs/mpl/doc/refmanual/metafunction-class.html - -A **heap** is a type with a methods ``void* allocate(std::size_t)`` -and ``void deallocate(void*)`` that return and release raw memory. -For a canonical model of this concept check the -:cpp:class:`immer::cpp_heap`. - -.. note:: Currently, *heaps* can only have **global state**. Having - internal state poses conceptual problems for immutable data - structures: should a `const` method of a container modify - its internal allocator state? Should every immutable - container object have its own internal state, or new objects - made from another one just keep a reference to the allocator - of the parent? - - On the other hand, having some **scoped state** does make - sense for some use-cases of immutable data structures. For - example, we might want to support variations of `region - based allocation`_. This interface might evolve to evolve - to support some kind of non-global state to accommodate - these use cases. - -.. _region based allocation: https://en.wikipedia.org/wiki/Region-based_memory_management - -.. admonition:: Why not use the standard allocator interface? - - The standard allocator API was not designed to support different - allocation strategies, but to abstract over the underlying memory - model instead. In C++11 the situation improves, but the new API is - *stateful*, posing various challenges as described in the previous - note. So far it was easier to provide our own allocation - interface. In the future, we will provide adaptors so - standard-compatible allocators can also be used with ``immer``. - -Heap policies -~~~~~~~~~~~~~ - -.. doxygenstruct:: immer::heap_policy - :members: - :undoc-members: - -.. doxygenstruct:: immer::free_list_heap_policy - -Standard heap -~~~~~~~~~~~~~ - -.. doxygenstruct:: immer::cpp_heap - :members: - -Malloc heap -~~~~~~~~~~~ - -.. doxygenstruct:: immer::malloc_heap - :members: - -Garbage collected heap -~~~~~~~~~~~~~~~~~~~~~~ - -.. doxygenclass:: immer::gc_heap - -Heap adaptors -~~~~~~~~~~~~~ - -Inspired by `Andrei Alexandrescu's talk on allocators <allocation -vexation>`_ and `Emery Berger's heap layers <heap layers>`_ we provide -allocator adaptors that can be combined using C++ mixins. These -enable building more complex allocator out of simpler strategies, or -provide application specific optimizations on top of general -allocators. - -.. _allocation vexation: https://www.youtube.com/watch?v=LIb3L4vKZ7U -.. _heap layers: https://github.com/emeryberger/Heap-Layers - -.. doxygenstruct:: immer::with_data - -.. doxygenstruct:: immer::free_list_heap - -.. doxygenstruct:: immer::thread_local_free_list_heap - -.. doxygenstruct:: immer::unsafe_free_list_heap - -.. doxygenstruct:: immer::identity_heap - -.. doxygenstruct:: immer::debug_size_heap - -.. doxygenstruct:: immer::split_heap - -.. _rc: - -Reference counting ------------------- - -`Reference counting`_ is the most commonly used garbage collection -strategy for C++. It can be implemented non-intrusively, in a way -orthogonal to the allocation strategy. It is deterministic, playing -well with RAII_. - -A `memory policy`_ can provide a reference counting strategy that -containers can use to track their contents. - -.. _reference counting: https://en.wikipedia.org/wiki/Reference_counting -.. _raii: https://en.wikipedia.org/wiki/Resource_acquisition_is_initialization - -.. doxygenstruct:: immer::refcount_policy - -.. doxygenstruct:: immer::unsafe_refcount_policy - -.. doxygenstruct:: immer::no_refcount_policy - -Transience ----------- - -In order to support `transients`, it is needed to provide a mechanism -to track the ownership of the data allocated inside the container. -This concept is encapsulated in *transience policies*. - -Note that when :ref:`reference counting <rc>` is available, no such mechanism is -needed. However, when :ref:`tracing garbage collection<gc>` is used instead, -a special policy has to be provided. Otherwise, the transient API is -still available, but it will perform poorly, since it won't be able to -mutate any data in place. - -.. doxygenstruct:: immer::no_transience_policy - -.. doxygenstruct:: immer::gc_transience_policy diff --git a/third_party/immer/doc/python.rst b/third_party/immer/doc/python.rst deleted file mode 120000 index 4266420dfb5b..000000000000 --- a/third_party/immer/doc/python.rst +++ /dev/null @@ -1 +0,0 @@ -../extra/python/README.rst \ No newline at end of file diff --git a/third_party/immer/doc/requirements.txt b/third_party/immer/doc/requirements.txt deleted file mode 100644 index 4d0744feec58..000000000000 --- a/third_party/immer/doc/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -git+https://github.com/arximboldi/sphinx.git -git+https://github.com/arximboldi/breathe.git -recommonmark diff --git a/third_party/immer/doc/sphinx-html-hack.bash b/third_party/immer/doc/sphinx-html-hack.bash deleted file mode 100755 index 1dccb9265dd0..000000000000 --- a/third_party/immer/doc/sphinx-html-hack.bash +++ /dev/null @@ -1,101 +0,0 @@ -#!/bin/bash - -location=`dirname $0` - -echo "Running $0 at $location" - -# Fixes issues described here among others -# https://github.com/michaeljones/breathe/issues/284 - -fix-missing-class-name() -{ - src='<span id="\([^"]*\)"></span>\(.*\)<em class="property">class </em>' - dst='<span id=""></span>\2<em class="property">class</em><tt class="descname">\1</tt>' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-missing-struct-name() -{ - src='<span id="\([^"]*\)"></span>\(.*\)<em class="property">struct </em>' - dst='<span id=""></span>\2<em class="property">struct</em><tt class="descname">\1</tt>' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-double-using-keyword() -{ - src='<em class="property">using</em><em class="property">using </em>' - dst='<em class="property">using </em>' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-do-not-repeat-type-in-member-using-declaration() -{ - src='<em class="property">using </em><code class="descname">\(\([^:]*::\)*\)\([^ ]*\) = \([^<]*\)</code>' - dst='<em class="property">using </em><code class="descname">\3 = \4</code>' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} -fix-do-not-repeat-type-in-member-using-declaration - -fix-remove-double-class-name() -{ - # src='<code class="descclassname">\([^&]*\)<\([^&]*\)>::</code>' - # dst='<code class="descclassname">\1::</code>' - src='<code class="descclassname">\([^<]*\)</code>' - dst='' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-remove-straneous-typedefs() -{ - src='typedef ' - dst='' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-remove-straneous-typedefs-2() -{ - src='= typedef ' - dst='= ' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} -fix-remove-straneous-typedefs-2 - -fix-remove-straneous-using-declarations() -{ - src='<em class="property">using </em>template<><br />' - dst='' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} - -fix-remove-straneous-template-in-using-declarations-1() -{ - src='\(<dl class="type">\n<dt[^>]*>\)\ntemplate<><br />' - dst='\1' - pre=':a;N;$!ba;' - sed -i "$pre;s@$src@$dst@g" $location/_build/html/*.html -} -fix-remove-straneous-template-in-using-declarations-1 - -fix-remove-straneous-template-in-using-declarations-2() -{ - src='></span>template<><br /><span ' - dst='></span><span ' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} -fix-remove-straneous-template-in-using-declarations-2 - -fix-remove-countainer-css-class-in-member-definitions-causing-overflow() -{ - src='breathe-sectiondef\([[:alnum:] _-]*\)container' - dst='breathe-sectiondef' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} -fix-remove-countainer-css-class-in-member-definitions-causing-overflow - -fix-remove-inherits-from() -{ - src='<p>Inherits from [^/]*</p>' - dst='' - sed -i "s@$src@$dst@g" $location/_build/html/*.html -} -fix-remove-inherits-from diff --git a/third_party/immer/doc/transients.rst b/third_party/immer/doc/transients.rst deleted file mode 100644 index 9b385d4db5c6..000000000000 --- a/third_party/immer/doc/transients.rst +++ /dev/null @@ -1,51 +0,0 @@ -.. _transient: - -Transients -========== - -*Transients* is a concept borrowed `from Clojure -<clojure-transients>`_, with some twists to turn make more idiomatic -in C++. Essentially, they are a mutable interface built on top of the -same data structures the implements the immutable containers under the -hood. - -These can be useful for :ref:`performing efficient batch -updates<batch-update>` or :ref:`interfacing with standard -algorithms<std-compat>`. - -.. _clojure-transients: https://clojure.org/reference/transients - -array_transient ---------------- - -.. doxygenclass:: immer::array_transient - :members: - :undoc-members: - -vector_transient ----------------- - -.. doxygenclass:: immer::vector_transient - :members: - :undoc-members: - -flex_vector_transient ---------------------- - -.. doxygenclass:: immer::flex_vector_transient - :members: - :undoc-members: - -set_transient -------------- - -.. doxygenclass:: immer::set_transient - :members: - :undoc-members: - -map_transient -------------- - -.. doxygenclass:: immer::map_transient - :members: - :undoc-members: diff --git a/third_party/immer/doc/utilities.rst b/third_party/immer/doc/utilities.rst deleted file mode 100644 index eaeea475c263..000000000000 --- a/third_party/immer/doc/utilities.rst +++ /dev/null @@ -1,15 +0,0 @@ -.. highlight:: c++ - -Utilities -========= - -The library provides also some types that, while they are not exactly -immutable data-structures, they are very useful when using immutable -data-structures and value-oriented design in practice. - -atom ----- - -.. doxygenclass:: immer::atom - :members: - :undoc-members: diff --git a/third_party/immer/example/CMakeLists.txt b/third_party/immer/example/CMakeLists.txt deleted file mode 100644 index 2aa0f554279d..000000000000 --- a/third_party/immer/example/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ - -# Targets -# ======= - -add_custom_target(examples - COMMENT "Build all examples.") -add_dependencies(check examples) - -file(GLOB_RECURSE immer_examples "*.cpp") -foreach(_file IN LISTS immer_examples) - immer_target_name_for(_target _output "${_file}") - add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") - add_dependencies(examples ${_target}) - set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) - target_link_libraries(${_target} PUBLIC immer-dev) - add_test("example/${_output}" ${_output}) -endforeach() diff --git a/third_party/immer/example/array/array.cpp b/third_party/immer/example/array/array.cpp deleted file mode 100644 index 43972ad61a21..000000000000 --- a/third_party/immer/example/array/array.cpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/array.hpp> - -#include <cassert> - -int main() -{ - { - // include:push-back/start - auto v1 = immer::array<int>{1}; - auto v2 = v1.push_back(8); - - assert((v1 == immer::array<int>{1})); - assert((v2 == immer::array<int>{1, 8})); - // include:push-back/end - } - - { - // include:set/start - auto v1 = immer::array<int>{1, 2, 3}; - auto v2 = v1.set(0, 5); - - assert((v1 == immer::array<int>{1, 2, 3})); - assert((v2 == immer::array<int>{5, 2, 3})); - // include:set/end - } - - { - // include:update/start - auto v1 = immer::array<int>{1, 2, 3, 4}; - auto v2 = v1.update(2, [&](auto l) { return ++l; }); - - assert((v1 == immer::array<int>{1, 2, 3, 4})); - assert((v2 == immer::array<int>{1, 2, 4, 4})); - // include:update/end - } - - { - // include:take/start - auto v1 = immer::array<int>{1, 2, 3, 4, 5, 6}; - auto v2 = v1.take(3); - - assert((v1 == immer::array<int>{1, 2, 3, 4, 5, 6})); - assert((v2 == immer::array<int>{1, 2, 3})); - // include:take/end - } -} diff --git a/third_party/immer/example/box/box.cpp b/third_party/immer/example/box/box.cpp deleted file mode 100644 index 8f045e8876ec..000000000000 --- a/third_party/immer/example/box/box.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/box.hpp> - -#include <cassert> -#include <string> - -int main() -{ - { - // include:update/start - auto v1 = immer::box<std::string>{"hello"}; - auto v2 = v1.update([&](auto l) { return l + ", world!"; }); - - assert((v1 == immer::box<std::string>{"hello"})); - assert((v2 == immer::box<std::string>{"hello, world!"})); - // include:update/end - } -} diff --git a/third_party/immer/example/flex-vector/flex-vector.cpp b/third_party/immer/example/flex-vector/flex-vector.cpp deleted file mode 100644 index 7c8a7793393c..000000000000 --- a/third_party/immer/example/flex-vector/flex-vector.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> - -#include <cassert> - -int main() -{ - { - // include:push-back/start - auto v1 = immer::flex_vector<int>{1}; - auto v2 = v1.push_back(8); - - assert((v1 == immer::flex_vector<int>{1})); - assert((v2 == immer::flex_vector<int>{1, 8})); - // include:push-back/end - } - { - // include:push-front/start - auto v1 = immer::flex_vector<int>{1}; - auto v2 = v1.push_front(8); - - assert((v1 == immer::flex_vector<int>{1})); - assert((v2 == immer::flex_vector<int>{8, 1})); - // include:push-front/end - } - - { - // include:set/start - auto v1 = immer::flex_vector<int>{1, 2, 3}; - auto v2 = v1.set(0, 5); - - assert((v1 == immer::flex_vector<int>{1, 2, 3})); - assert((v2 == immer::flex_vector<int>{5, 2, 3})); - // include:set/end - } - - { - // include:update/start - auto v1 = immer::flex_vector<int>{1, 2, 3, 4}; - auto v2 = v1.update(2, [&](auto l) { return ++l; }); - - assert((v1 == immer::flex_vector<int>{1, 2, 3, 4})); - assert((v2 == immer::flex_vector<int>{1, 2, 4, 4})); - // include:update/end - } - - { - // include:take/start - auto v1 = immer::flex_vector<int>{1, 2, 3, 4, 5, 6}; - auto v2 = v1.take(3); - - assert((v1 == immer::flex_vector<int>{1, 2, 3, 4, 5, 6})); - assert((v2 == immer::flex_vector<int>{1, 2, 3})); - // include:take/end - } - - { - // include:drop/start - auto v1 = immer::flex_vector<int>{1, 2, 3, 4, 5, 6}; - auto v2 = v1.drop(3); - - assert((v1 == immer::flex_vector<int>{1, 2, 3, 4, 5, 6})); - assert((v2 == immer::flex_vector<int>{4, 5, 6})); - // include:drop/end - } - - { - // include:insert/start - auto v1 = immer::flex_vector<int>{1, 2, 3}; - auto v2 = v1.insert(0, 0); - - assert((v1 == immer::flex_vector<int>{1, 2, 3})); - assert((v2 == immer::flex_vector<int>{0, 1, 2, 3})); - // include:insert/end - } - - { - // include:erase/start - auto v1 = immer::flex_vector<int>{1, 2, 3, 4, 5}; - auto v2 = v1.erase(2); - - assert((v1 == immer::flex_vector<int>{1, 2, 3, 4, 5})); - assert((v2 == immer::flex_vector<int>{1, 2, 4, 5})); - // include:erase/end - } - - { - // include:concat/start - auto v1 = immer::flex_vector<int>{1, 2, 3}; - auto v2 = v1 + v1; - - assert((v1 == immer::flex_vector<int>{1, 2, 3})); - assert((v2 == immer::flex_vector<int>{1, 2, 3, 1, 2, 3})); - // include:concat/end - } -} diff --git a/third_party/immer/example/map/intro.cpp b/third_party/immer/example/map/intro.cpp deleted file mode 100644 index 94222f99b31b..000000000000 --- a/third_party/immer/example/map/intro.cpp +++ /dev/null @@ -1,23 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <string> -// include:intro/start -#include <immer/map.hpp> -int main() -{ - const auto v0 = immer::map<std::string, int>{}; - const auto v1 = v0.set("hello", 42); - assert(v0["hello"] == 0); - assert(v1["hello"] == 42); - - const auto v2 = v1.erase("hello"); - assert(*v1.find("hello") == 42); - assert(!v2.find("hello")); -} -// include:intro/end diff --git a/third_party/immer/example/set/intro.cpp b/third_party/immer/example/set/intro.cpp deleted file mode 100644 index be932ce65475..000000000000 --- a/third_party/immer/example/set/intro.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// include:intro/start -#include <immer/set.hpp> -int main() -{ - const auto v0 = immer::set<int>{}; - const auto v1 = v0.insert(42); - assert(v0.count(42) == 0); - assert(v1.count(42) == 1); - - const auto v2 = v1.erase(42); - assert(v1.count(42) == 1); - assert(v2.count(42) == 0); -} -// include:intro/end diff --git a/third_party/immer/example/vector/fizzbuzz.cpp b/third_party/immer/example/vector/fizzbuzz.cpp deleted file mode 100644 index c7765a6200a0..000000000000 --- a/third_party/immer/example/vector/fizzbuzz.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> - -#include <iostream> -#include <string> - -// include:fizzbuzz/start -immer::vector<std::string> -fizzbuzz(immer::vector<std::string> v, int first, int last) -{ - for (auto i = first; i < last; ++i) - v = std::move(v).push_back( - i % 15 == 0 ? "FizzBuzz" - : i % 5 == 0 ? "Bizz" - : i % 3 == 0 ? "Fizz" : - /* else */ std::to_string(i)); - return v; -} -// include:fizzbuzz/end - -int main() -{ - auto v = fizzbuzz({}, 0, 100); - std::copy(v.begin(), - v.end(), - std::ostream_iterator<std::string>{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/gc.cpp b/third_party/immer/example/vector/gc.cpp deleted file mode 100644 index 2bc4d5116f42..000000000000 --- a/third_party/immer/example/vector/gc.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// include:example/start -#include <immer/heap/gc_heap.hpp> -#include <immer/heap/heap_policy.hpp> -#include <immer/memory_policy.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/vector.hpp> - -#include <iostream> - -// declare a memory policy for using a tracing garbage collector -using gc_policy = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -// alias the vector type so we are not concerned about memory policies -// in the places where we actually use it -template <typename T> -using my_vector = immer::vector<T, gc_policy>; - -int main() -{ - auto v = - my_vector<const char*>().push_back("hello, ").push_back("world!\n"); - - for (auto s : v) - std::cout << s; -} -// include:example/end diff --git a/third_party/immer/example/vector/intro.cpp b/third_party/immer/example/vector/intro.cpp deleted file mode 100644 index ca832e606552..000000000000 --- a/third_party/immer/example/vector/intro.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// include:intro/start -#include <immer/vector.hpp> -int main() -{ - const auto v0 = immer::vector<int>{}; - const auto v1 = v0.push_back(13); - assert((v0 == immer::vector<int>{})); - assert((v1 == immer::vector<int>{13})); - - const auto v2 = v1.set(0, 42); - assert(v1[0] == 13); - assert(v2[0] == 42); -} -// include:intro/end diff --git a/third_party/immer/example/vector/iota-move.cpp b/third_party/immer/example/vector/iota-move.cpp deleted file mode 100644 index 3d03ba5307f5..000000000000 --- a/third_party/immer/example/vector/iota-move.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> -#include <iostream> - -// include:myiota/start -immer::vector<int> myiota(immer::vector<int> v, int first, int last) -{ - for (auto i = first; i < last; ++i) - v = std::move(v).push_back(i); - return v; -} -// include:myiota/end - -int main() -{ - auto v = myiota({}, 0, 100); - std::copy(v.begin(), v.end(), std::ostream_iterator<int>{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/iota-slow.cpp b/third_party/immer/example/vector/iota-slow.cpp deleted file mode 100644 index a311b7a7ff08..000000000000 --- a/third_party/immer/example/vector/iota-slow.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> -#include <iostream> - -// include:myiota/start -immer::vector<int> myiota(immer::vector<int> v, int first, int last) -{ - for (auto i = first; i < last; ++i) - v = v.push_back(i); - return v; -} -// include:myiota/end - -int main() -{ - auto v = myiota({}, 0, 100); - std::copy(v.begin(), v.end(), std::ostream_iterator<int>{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/iota-transient-std.cpp b/third_party/immer/example/vector/iota-transient-std.cpp deleted file mode 100644 index 451f44a10306..000000000000 --- a/third_party/immer/example/vector/iota-transient-std.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -#include <algorithm> -#include <iostream> - -// include:myiota/start -immer::vector<int> myiota(immer::vector<int> v, int first, int last) -{ - auto t = v.transient(); - std::generate_n( - std::back_inserter(t), last - first, [&] { return first++; }); - return t.persistent(); -} -// include:myiota/end - -int main() -{ - auto v = myiota({}, 0, 100); - std::copy(v.begin(), v.end(), std::ostream_iterator<int>{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/iota-transient.cpp b/third_party/immer/example/vector/iota-transient.cpp deleted file mode 100644 index d49b14e5798d..000000000000 --- a/third_party/immer/example/vector/iota-transient.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> -#include <iostream> - -// include:myiota/start -immer::vector<int> myiota(immer::vector<int> v, int first, int last) -{ - auto t = v.transient(); - for (auto i = first; i < last; ++i) - t.push_back(i); - return t.persistent(); -} -// include:myiota/end - -int main() -{ - auto v = myiota({}, 0, 100); - std::copy(v.begin(), v.end(), std::ostream_iterator<int>{std::cout, "\n"}); -} diff --git a/third_party/immer/example/vector/move.cpp b/third_party/immer/example/vector/move.cpp deleted file mode 100644 index 7eb815b62a6e..000000000000 --- a/third_party/immer/example/vector/move.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <cassert> -#include <immer/vector.hpp> - -// include:move-bad/start -immer::vector<int> do_stuff(const immer::vector<int> v) -{ - return std::move(v).push_back(42); -} -// include:move-bad/end - -// include:move-good/start -immer::vector<int> do_stuff_better(immer::vector<int> v) -{ - return std::move(v).push_back(42); -} -// include:move-good/end - -int main() -{ - auto v = immer::vector<int>{}; - auto v1 = do_stuff(v); - auto v2 = do_stuff_better(v); - assert(v1.size() == 1); - assert(v2.size() == 1); - assert(v1[0] == 42); - assert(v2[0] == 42); -} diff --git a/third_party/immer/example/vector/vector.cpp b/third_party/immer/example/vector/vector.cpp deleted file mode 100644 index c59c2d1d170b..000000000000 --- a/third_party/immer/example/vector/vector.cpp +++ /dev/null @@ -1,53 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <cassert> -#include <immer/vector.hpp> - -int main() -{ - { - // include:push-back/start - auto v1 = immer::vector<int>{1}; - auto v2 = v1.push_back(8); - - assert((v1 == immer::vector<int>{1})); - assert((v2 == immer::vector<int>{1, 8})); - // include:push-back/end - } - - { - // include:set/start - auto v1 = immer::vector<int>{1, 2, 3}; - auto v2 = v1.set(0, 5); - - assert((v1 == immer::vector<int>{1, 2, 3})); - assert((v2 == immer::vector<int>{5, 2, 3})); - // include:set/end - } - - { - // include:update/start - auto v1 = immer::vector<int>{1, 2, 3, 4}; - auto v2 = v1.update(2, [&](auto l) { return ++l; }); - - assert((v1 == immer::vector<int>{1, 2, 3, 4})); - assert((v2 == immer::vector<int>{1, 2, 4, 4})); - // include:update/end - } - - { - // include:take/start - auto v1 = immer::vector<int>{1, 2, 3, 4, 5, 6}; - auto v2 = v1.take(3); - - assert((v1 == immer::vector<int>{1, 2, 3, 4, 5, 6})); - assert((v2 == immer::vector<int>{1, 2, 3})); - // include:take/end - } -} diff --git a/third_party/immer/extra/fuzzer/CMakeLists.txt b/third_party/immer/extra/fuzzer/CMakeLists.txt deleted file mode 100644 index 777289f8a12d..000000000000 --- a/third_party/immer/extra/fuzzer/CMakeLists.txt +++ /dev/null @@ -1,29 +0,0 @@ - -add_custom_target(fuzzers - COMMENT "Build all fuzzers.") - -if (CHECK_FUZZERS) - add_dependencies(tests fuzzers) -endif() - -# LIB_FUZZING_ENGINE is set by the Google OSS-Fuzz -# infrastructure. Otherwise we use Clang's LibFuzzer -if (DEFINED ENV{LIB_FUZZING_ENGINE}) - set(immer_fuzzing_engine $ENV{LIB_FUZZING_ENGINE}) -else() - set(immer_fuzzing_engine "-fsanitize=fuzzer") -endif() - -file(GLOB_RECURSE immer_fuzzers "*.cpp") -foreach(_file IN LISTS immer_fuzzers) - immer_target_name_for(_target _output "${_file}") - add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") - set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) - target_compile_options(${_target} PUBLIC ${immer_fuzzing_engine}) - target_link_libraries(${_target} PUBLIC ${immer_fuzzing_engine} - immer-dev) - add_dependencies(fuzzers ${_target}) - if (CHECK_FUZZERS) - add_test("fuzzer/${_output}" ${_output} -max_total_time=1) - endif() -endforeach() diff --git a/third_party/immer/extra/fuzzer/array-gc.cpp b/third_party/immer/extra/fuzzer/array-gc.cpp deleted file mode 100644 index b93721225288..000000000000 --- a/third_party/immer/extra/fuzzer/array-gc.cpp +++ /dev/null @@ -1,103 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/array.hpp> -#include <immer/array_transient.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -#include <array> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using array_t = immer::array<int, gc_memory>; - using transient_t = typename array_t::transient_type; - using size_t = std::uint8_t; - - auto vs = std::array<array_t, var_count>{}; - auto ts = std::array<transient_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_transient, - op_persistent, - op_push_back, - op_update, - op_take, - op_push_back_mut, - op_update_mut, - op_take_mut, - }; - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_transient: { - auto src = read<char>(in, is_valid_var); - ts[dst] = vs[src].transient(); - break; - } - case op_persistent: { - auto src = read<char>(in, is_valid_var); - vs[dst] = ts[src].persistent(); - break; - } - case op_push_back: { - auto src = read<char>(in, is_valid_var); - vs[dst] = vs[src].push_back(42); - break; - } - case op_update: { - auto src = read<char>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_index(vs[src])); - vs[dst] = vs[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto src = read<char>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_size(vs[src])); - vs[dst] = vs[src].take(idx); - break; - } - case op_push_back_mut: { - ts[dst].push_back(13); - break; - } - case op_update_mut: { - auto idx = read<size_t>(in, is_valid_index(ts[dst])); - ts[dst].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_mut: { - auto idx = read<size_t>(in, is_valid_size(ts[dst])); - ts[dst].take(idx); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/array.cpp b/third_party/immer/extra/fuzzer/array.cpp deleted file mode 100644 index 094d97b7f425..000000000000 --- a/third_party/immer/extra/fuzzer/array.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/array.hpp> - -#include <array> - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using array_t = immer::array<int, immer::default_memory_policy>; - using size_t = std::uint8_t; - - auto vars = std::array<array_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_push_back_move, - op_update_move, - op_take_move, - }; - auto src = read<char>(in, is_valid_var); - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_push_back: { - vars[dst] = vars[src].push_back(42); - break; - } - case op_update: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - vars[dst] = vars[src].take(idx); - break; - } - case op_push_back_move: { - vars[dst] = std::move(vars[src]).push_back(12); - break; - } - case op_update_move: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - vars[dst] = - std::move(vars[src]).update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_move: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - vars[dst] = std::move(vars[src]).take(idx); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/flex-vector-gc.cpp b/third_party/immer/extra/fuzzer/flex-vector-gc.cpp deleted file mode 100644 index 00c302898675..000000000000 --- a/third_party/immer/extra/fuzzer/flex-vector-gc.cpp +++ /dev/null @@ -1,162 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -#include <array> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - constexpr auto bits = 2; - - using vector_t = immer::flex_vector<int, gc_memory, bits, bits>; - using transient_t = typename vector_t::transient_type; - using size_t = std::uint8_t; - - auto vs = std::array<vector_t, var_count>{}; - auto ts = std::array<transient_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_var_neq = [](auto other) { - return [=](auto idx) { - return idx >= 0 && idx < var_count && idx != other; - }; - }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - auto can_concat = [](auto&& v1, auto&& v2) { - using size_type = decltype(v1.size()); - auto max = std::numeric_limits<size_type>::max() >> (bits * 4); - return v1.size() < max && v2.size() < max; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_transient, - op_persistent, - op_push_back, - op_update, - op_take, - op_drop, - op_concat, - op_push_back_mut, - op_update_mut, - op_take_mut, - op_drop_mut, - op_prepend_mut, - op_prepend_mut_move, - op_append_mut, - op_append_mut_move, - }; - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_transient: { - auto src = read<char>(in, is_valid_var); - ts[dst] = vs[src].transient(); - break; - } - case op_persistent: { - auto src = read<char>(in, is_valid_var); - vs[dst] = ts[src].persistent(); - break; - } - case op_push_back: { - auto src = read<char>(in, is_valid_var); - vs[dst] = vs[src].push_back(42); - break; - } - case op_update: { - auto src = read<char>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_index(vs[src])); - vs[dst] = vs[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto src = read<char>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_size(vs[src])); - vs[dst] = vs[src].take(idx); - break; - } - case op_drop: { - auto src = read<char>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_size(vs[src])); - vs[dst] = vs[src].drop(idx); - break; - } - case op_concat: { - auto src = read<char>(in, is_valid_var); - auto src2 = read<char>(in, is_valid_var); - if (can_concat(vs[src], vs[src2])) - vs[dst] = vs[src] + vs[src2]; - break; - } - case op_push_back_mut: { - ts[dst].push_back(13); - break; - } - case op_update_mut: { - auto idx = read<size_t>(in, is_valid_index(ts[dst])); - ts[dst].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_mut: { - auto idx = read<size_t>(in, is_valid_size(ts[dst])); - ts[dst].take(idx); - break; - } - case op_prepend_mut: { - auto src = read<char>(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) - ts[dst].prepend(ts[src]); - break; - } - case op_prepend_mut_move: { - auto src = read<char>(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) { - ts[dst].prepend(std::move(ts[src])); - ts[src] = {}; - } - break; - } - case op_append_mut: { - auto src = read<char>(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) - ts[dst].append(ts[src]); - break; - } - case op_append_mut_move: { - auto src = read<char>(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) { - ts[dst].append(std::move(ts[src])); - ts[src] = {}; - } - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/flex-vector.cpp b/third_party/immer/extra/fuzzer/flex-vector.cpp deleted file mode 100644 index 14395de1d5ae..000000000000 --- a/third_party/immer/extra/fuzzer/flex-vector.cpp +++ /dev/null @@ -1,150 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/box.hpp> -#include <immer/flex_vector.hpp> - -#include <array> - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 8; - constexpr auto bits = 2; - - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, bits, bits>; - using size_t = std::uint8_t; - - auto vars = std::array<vector_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_var_neq = [](auto other) { - return [=](auto idx) { - return idx >= 0 && idx < var_count && idx != other; - }; - }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - auto can_concat = [](auto&& v1, auto&& v2) { - using size_type = decltype(v1.size()); - auto max = std::numeric_limits<size_type>::max() >> (bits * 4); - return v1.size() < max && v2.size() < max; - }; - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_drop, - op_concat, - op_push_back_move, - op_update_move, - op_take_move, - op_drop_move, - op_concat_move_l, - op_concat_move_r, - op_concat_move_lr, - op_insert, - op_erase, - op_compare, - }; - auto src = read<char>(in, is_valid_var); - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_push_back: { - vars[dst] = vars[src].push_back(42); - break; - } - case op_update: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - vars[dst] = vars[src].take(idx); - break; - } - case op_drop: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - vars[dst] = vars[src].drop(idx); - break; - } - case op_concat: { - auto src2 = read<char>(in, is_valid_var); - if (can_concat(vars[src], vars[src2])) - vars[dst] = vars[src] + vars[src2]; - break; - } - case op_push_back_move: { - vars[dst] = std::move(vars[src]).push_back(21); - break; - } - case op_update_move: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - vars[dst] = - std::move(vars[src]).update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_move: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - vars[dst] = std::move(vars[src]).take(idx); - break; - } - case op_drop_move: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - vars[dst] = std::move(vars[src]).drop(idx); - break; - } - case op_concat_move_l: { - auto src2 = read<char>(in, is_valid_var_neq(src)); - if (can_concat(vars[src], vars[src2])) - vars[dst] = std::move(vars[src]) + vars[src2]; - break; - } - case op_concat_move_r: { - auto src2 = read<char>(in, is_valid_var_neq(src)); - if (can_concat(vars[src], vars[src2])) - vars[dst] = vars[src] + std::move(vars[src2]); - break; - } - case op_concat_move_lr: { - auto src2 = read<char>(in, is_valid_var_neq(src)); - if (can_concat(vars[src], vars[src2])) - vars[dst] = std::move(vars[src]) + std::move(vars[src2]); - } - case op_compare: { - using std::swap; - if (vars[src] == vars[dst]) - swap(vars[src], vars[dst]); - break; - } - case op_erase: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - vars[dst] = vars[src].erase(idx); - break; - } - case op_insert: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - vars[dst] = vars[src].insert(idx, immer::box<int>{42}); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/fuzzer_input.hpp b/third_party/immer/extra/fuzzer/fuzzer_input.hpp deleted file mode 100644 index 485b7dc72b44..000000000000 --- a/third_party/immer/extra/fuzzer/fuzzer_input.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <cstdint> -#include <stdexcept> - -struct no_more_input : std::exception -{}; - -struct fuzzer_input -{ - const std::uint8_t* data_; - std::size_t size_; - - const std::uint8_t* next(std::size_t size) - { - if (size_ < size) - throw no_more_input{}; - auto r = data_; - data_ += size; - size_ -= size; - return r; - } - - const std::uint8_t* next(std::size_t size, std::size_t align) - { - auto rem = size % align; - if (rem) - next(align - rem); - return next(size); - } - - template <typename Fn> - int run(Fn step) - { - try { - while (step(*this)) - continue; - } catch (const no_more_input&) {}; - return 0; - } -}; - -template <typename T> -const T& read(fuzzer_input& fz) -{ - return *reinterpret_cast<const T*>(fz.next(sizeof(T), alignof(T))); -} - -template <typename T, typename Cond> -T read(fuzzer_input& fz, Cond cond) -{ - auto x = read<T>(fz); - return cond(x) ? x : read<T>(fz, cond); -} diff --git a/third_party/immer/extra/fuzzer/map-gc.cpp b/third_party/immer/extra/fuzzer/map-gc.cpp deleted file mode 100644 index 835f37a05897..000000000000 --- a/third_party/immer/extra/fuzzer/map-gc.cpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/heap/gc_heap.hpp> -#include <immer/map.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -#include <array> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using map_t = - immer::map<char, int, std::hash<char>, std::equal_to<char>, gc_memory>; - - auto vars = std::array<map_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_set, - op_erase, - op_set_move, - op_erase_move, - op_iterate, - op_find, - op_update - }; - auto src = read<char>(in, is_valid_var); - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_set: { - auto value = read<size_t>(in); - vars[dst] = vars[src].set(value, 42); - break; - } - case op_erase: { - auto value = read<size_t>(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_set_move: { - auto value = read<size_t>(in); - vars[dst] = std::move(vars[src]).set(value, 42); - break; - } - case op_erase_move: { - auto value = read<size_t>(in); - vars[dst] = std::move(vars[src]).erase(value); - break; - } - case op_iterate: { - auto srcv = vars[src]; - for (const auto& v : srcv) { - vars[dst] = vars[dst].set(v.first, v.second); - } - break; - } - case op_find: { - auto value = read<size_t>(in); - auto res = vars[src].find(value); - if (res != nullptr) { - vars[dst] = vars[dst].set(*res, 42); - } - break; - } - case op_update: { - auto key = read<size_t>(in); - vars[dst] = vars[src].update(key, [](int x) { return x + 1; }); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/map.cpp b/third_party/immer/extra/fuzzer/map.cpp deleted file mode 100644 index eb650679e932..000000000000 --- a/third_party/immer/extra/fuzzer/map.cpp +++ /dev/null @@ -1,85 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/map.hpp> - -#include <array> - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using map_t = immer::map<char, int>; - - auto vars = std::array<map_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_set, - op_erase, - op_set_move, - op_erase_move, - op_iterate, - op_find, - op_update - }; - auto src = read<char>(in, is_valid_var); - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_set: { - auto value = read<size_t>(in); - vars[dst] = vars[src].set(value, 42); - break; - } - case op_erase: { - auto value = read<size_t>(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_set_move: { - auto value = read<size_t>(in); - vars[dst] = std::move(vars[src]).set(value, 42); - break; - } - case op_erase_move: { - auto value = read<size_t>(in); - vars[dst] = std::move(vars[src]).erase(value); - break; - } - case op_iterate: { - auto srcv = vars[src]; - for (const auto& v : srcv) { - vars[dst] = vars[dst].set(v.first, v.second); - } - break; - } - case op_find: { - auto value = read<size_t>(in); - auto res = vars[src].find(value); - if (res != nullptr) { - vars[dst] = vars[dst].set(*res, 42); - } - break; - } - case op_update: { - auto key = read<size_t>(in); - vars[dst] = vars[src].update(key, [](int x) { return x + 1; }); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/set-gc.cpp b/third_party/immer/extra/fuzzer/set-gc.cpp deleted file mode 100644 index 3b88c08f3c2d..000000000000 --- a/third_party/immer/extra/fuzzer/set-gc.cpp +++ /dev/null @@ -1,78 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/set.hpp> - -#include <array> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using set_t = - immer::set<int, std::hash<char>, std::equal_to<char>, gc_memory>; - - auto vars = std::array<set_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_insert, - op_erase, - op_insert_move, - op_erase_move, - op_iterate - }; - auto src = read<char>(in, is_valid_var); - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_insert: { - auto value = read<size_t>(in); - vars[dst] = vars[src].insert(value); - break; - } - case op_erase: { - auto value = read<size_t>(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_insert_move: { - auto value = read<size_t>(in); - vars[dst] = std::move(vars[src]).insert(value); - break; - } - case op_erase_move: { - auto value = read<size_t>(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_iterate: { - auto srcv = vars[src]; - for (const auto& v : srcv) { - vars[dst] = vars[dst].insert(v); - } - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/set.cpp b/third_party/immer/extra/fuzzer/set.cpp deleted file mode 100644 index b25313d18cfc..000000000000 --- a/third_party/immer/extra/fuzzer/set.cpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/set.hpp> - -#include <array> - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - - using set_t = immer::set<int>; - - auto vars = std::array<set_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_insert, - op_erase, - op_insert_move, - op_erase_move, - op_iterate - }; - auto src = read<char>(in, is_valid_var); - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_insert: { - auto value = read<size_t>(in); - vars[dst] = vars[src].insert(value); - break; - } - case op_erase: { - auto value = read<size_t>(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_insert_move: { - auto value = read<size_t>(in); - vars[dst] = std::move(vars[src]).insert(value); - break; - } - case op_erase_move: { - auto value = read<size_t>(in); - vars[dst] = vars[src].erase(value); - break; - } - case op_iterate: { - auto srcv = vars[src]; - for (const auto& v : srcv) { - vars[dst] = vars[dst].insert(v); - } - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/vector-gc.cpp b/third_party/immer/extra/fuzzer/vector-gc.cpp deleted file mode 100644 index 1faa729c5a72..000000000000 --- a/third_party/immer/extra/fuzzer/vector-gc.cpp +++ /dev/null @@ -1,104 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -#include <array> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - constexpr auto bits = 2; - - using vector_t = immer::vector<int, gc_memory, bits, bits>; - using transient_t = typename vector_t::transient_type; - using size_t = std::uint8_t; - - auto vs = std::array<vector_t, var_count>{}; - auto ts = std::array<transient_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_transient, - op_persistent, - op_push_back, - op_update, - op_take, - op_push_back_mut, - op_update_mut, - op_take_mut, - }; - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_transient: { - auto src = read<char>(in, is_valid_var); - ts[dst] = vs[src].transient(); - break; - } - case op_persistent: { - auto src = read<char>(in, is_valid_var); - vs[dst] = ts[src].persistent(); - break; - } - case op_push_back: { - auto src = read<char>(in, is_valid_var); - vs[dst] = vs[src].push_back(42); - break; - } - case op_update: { - auto src = read<char>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_index(vs[src])); - vs[dst] = vs[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto src = read<char>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_size(vs[src])); - vs[dst] = vs[src].take(idx); - break; - } - case op_push_back_mut: { - ts[dst].push_back(13); - break; - } - case op_update_mut: { - auto idx = read<size_t>(in, is_valid_index(ts[dst])); - ts[dst].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_mut: { - auto idx = read<size_t>(in, is_valid_size(ts[dst])); - ts[dst].take(idx); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/fuzzer/vector.cpp b/third_party/immer/extra/fuzzer/vector.cpp deleted file mode 100644 index b04cbcee870c..000000000000 --- a/third_party/immer/extra/fuzzer/vector.cpp +++ /dev/null @@ -1,82 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "fuzzer_input.hpp" - -#include <immer/vector.hpp> - -#include <array> - -extern "C" int LLVMFuzzerTestOneInput(const std::uint8_t* data, - std::size_t size) -{ - constexpr auto var_count = 4; - constexpr auto bits = 2; - - using vector_t = - immer::vector<int, immer::default_memory_policy, bits, bits>; - using size_t = std::uint8_t; - - auto vars = std::array<vector_t, var_count>{}; - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < var_count; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_push_back_move, - op_update_move, - op_take_move, - }; - auto src = read<char>(in, is_valid_var); - auto dst = read<char>(in, is_valid_var); - switch (read<char>(in)) { - case op_push_back: { - vars[dst] = vars[src].push_back(42); - break; - } - case op_update: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - vars[dst] = vars[src].take(idx); - break; - } - case op_push_back_move: { - vars[dst] = std::move(vars[src]).push_back(12); - break; - } - case op_update_move: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - vars[dst] = - std::move(vars[src]).update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_move: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - vars[dst] = std::move(vars[src]).take(idx); - break; - } - default: - break; - }; - return true; - }); -} diff --git a/third_party/immer/extra/guile/CMakeLists.txt b/third_party/immer/extra/guile/CMakeLists.txt deleted file mode 100644 index 99338060d6da..000000000000 --- a/third_party/immer/extra/guile/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ - -find_package(PkgConfig) - -pkg_check_modules(Guile guile-2.2) - -if (NOT Guile_FOUND) - message(STATUS "Disabling Guile modules") - return() -endif() - -set(GUILE_EXTENSION_DIR ${CMAKE_CURRENT_BINARY_DIR}) -configure_file(immer.scm.in immer.scm) - -add_library(guile-immer SHARED EXCLUDE_FROM_ALL - src/immer.cpp) -target_include_directories(guile-immer PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR} - ${CALLABLE_TRAITS_INCLUDE_DIR} - ${Guile_INCLUDE_DIRS}) -target_link_libraries(guile-immer PUBLIC - immer - ${Guile_LIBRARIES}) - -add_custom_target(guile DEPENDS guile-immer) diff --git a/third_party/immer/extra/guile/README.rst b/third_party/immer/extra/guile/README.rst deleted file mode 100644 index 09cf8be644ec..000000000000 --- a/third_party/immer/extra/guile/README.rst +++ /dev/null @@ -1,144 +0,0 @@ - -Guile bindings -============== - -This library includes experimental bindings bring efficient immutable -vectors for the `GNU Guile`_ Scheme implementation. The interface is -somewhat **incomplete**, but you can already do something interesting -things like: - -.. literalinclude:: ../extra/guile/example.scm - :language: scheme - :start-after: intro/start - :end-before: intro/end -.. - - **Do you want to help** making these bindings complete and production - ready? Drop a line at `immer@sinusoid.al - <mailto:immer@sinusoid.al>`_ or `open an issue on Github - <https://github.com/arximboldi/immer>`_ - -.. _GNU Guile: https://www.gnu.org/software/guile/ - -Installation ------------- - -.. highlight:: sh - -To install the software, you need `GNU Guile 2.2 -<https://www.gnu.org/software/guile/download/>`_. Then you have to -`clone the repository <https://github.com/arximboldi/immer>`_ and -inside the repository do something like:: - - mkdir build; cd build - cmake .. -DCMAKE_BUILD_TYPE=Release \ - -DGUILE_EXTENSION_DIR="<somewhere...>" - make guile - cp extra/guile/libguile-immer.so "<...the GUILE_EXTENSION_DIR>" - cp extra/guile/immer.scm "<somewhere in your GUILE_LOAD_PATH>" - -Benchmarks ----------- - -The library includes some quick and dirty benchmarks that show how -these vectors perform compared to *mutable vectors*, *lists*, and -*v-lists*. Once you have installed the library, you may run them by -executing the following in the project root:: - - guile extra/guile/benchmark.scm - -This is the output I get when running those: - -.. code-block:: scheme - :name: benchmark-output - - (define bench-size 1000000) - (define bench-samples 10) - ;;;; benchmarking creation... - ; evaluating: - (apply ivector (iota bench-size)) - ; average time: 0.0608697784 seconds - ; evaluating: - (apply ivector-u32 (iota bench-size)) - ; average time: 0.0567354933 seconds - ; evaluating: - (iota bench-size) - ; average time: 0.032995402 seconds - ; evaluating: - (apply vector (iota bench-size)) - ; average time: 0.0513594425 seconds - ; evaluating: - (apply u32vector (iota bench-size)) - ; average time: 0.0939185315 seconds - ; evaluating: - (list->vlist (iota bench-size)) - ; average time: 0.2369570977 seconds - ;;;; benchmarking iteration... - (define bench-ivector (apply ivector (iota bench-size))) - (define bench-ivector-u32 (apply ivector-u32 (iota bench-size))) - (define bench-list (iota bench-size)) - (define bench-vector (apply vector (iota bench-size))) - (define bench-u32vector (apply u32vector (iota bench-size))) - (define bench-vlist (list->vlist (iota bench-size))) - ; evaluating: - (ivector-fold + 0 bench-ivector) - ; average time: 0.035750341 seconds - ; evaluating: - (ivector-u32-fold + 0 bench-ivector-u32) - ; average time: 0.0363843682 seconds - ; evaluating: - (fold + 0 bench-list) - ; average time: 0.0271881423 seconds - ; evaluating: - (vector-fold + 0 bench-vector) - ; average time: 0.0405022349 seconds - ; evaluating: - (vlist-fold + 0 bench-vlist) - ; average time: 0.0424709098 seconds - ;;;; benchmarking iteration by index... - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (ivector-length bench-ivector)) - (iter (+ i 1) (+ acc (ivector-ref bench-ivector i))) - acc)) - ; average time: 0.2195658936 seconds - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (ivector-u32-length bench-ivector-u32)) - (iter (+ i 1) (+ acc (ivector-u32-ref bench-ivector-u32 i))) - acc)) - ; average time: 0.2205486326 seconds - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (vector-length bench-vector)) - (iter (+ i 1) (+ acc (vector-ref bench-vector i))) - acc)) - ; average time: 0.0097157637 seconds - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (u32vector-length bench-u32vector)) - (iter (+ i 1) (+ acc (u32vector-ref bench-u32vector i))) - acc)) - ; average time: 0.0733736008 seconds - ; evaluating: - (let iter ((i 0) (acc 0)) - (if (< i (vlist-length bench-vlist)) - (iter (+ i 1) (+ acc (vlist-ref bench-vlist i))) - acc)) - ; average time: 0.3220357243 seconds - ;;;; benchmarking concatenation... - ; evaluating: - (ivector-append bench-ivector bench-ivector) - ; average time: 1.63022e-5 seconds - ; evaluating: - (ivector-u32-append bench-ivector-u32 bench-ivector-u32) - ; average time: 1.63754e-5 seconds - ; evaluating: - (append bench-list bench-list) - ; average time: 0.0135592963 seconds - ; evaluating: - (vector-append bench-vector bench-vector) - ; average time: 0.0044506586 seconds - ; evaluating: - (vlist-append bench-vlist bench-vlist) - ; average time: 0.3227312512 seconds diff --git a/third_party/immer/extra/guile/benchmark.scm b/third_party/immer/extra/guile/benchmark.scm deleted file mode 100644 index 463a8eb17d9e..000000000000 --- a/third_party/immer/extra/guile/benchmark.scm +++ /dev/null @@ -1,168 +0,0 @@ -;; -;; immer: immutable data structures for C++ -;; Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -;; -;; This software is distributed under the Boost Software License, Version 1.0. -;; See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -;; - -(use-modules (immer) - (fector) ; https://wingolog.org/pub/fector.scm - (srfi srfi-1) - (srfi srfi-43) - (ice-9 vlist) - (ice-9 pretty-print) - (rnrs bytevectors)) - -(define-syntax display-eval - (syntax-rules () - ((_ expr) - (begin (pretty-print 'expr - #:max-expr-width 72) - expr)))) - -(display-eval (define bench-size 1000000)) -(display-eval (define bench-samples 10)) - -(define (average . ns) - (/ (apply + ns) (length ns))) - -(define (generate-n n fn) - (unfold (lambda (x) (= x n)) - (lambda (x) (fn)) - (lambda (x) (+ x 1)) - 0)) - -(define-syntax benchmark - (syntax-rules () - ((_ expr) - (begin - (display "; evaluating: ") (newline) - (pretty-print 'expr - #:max-expr-width 72 - #:per-line-prefix " ") - (let* ((sample (lambda () - (gc) - (let* ((t0 (get-internal-real-time)) - (r expr) - (t1 (get-internal-real-time))) - (/ (- t1 t0) internal-time-units-per-second)))) - (samples (generate-n bench-samples sample)) - (result (apply average samples))) - (display "; average time: ") - (display (exact->inexact result)) - (display " seconds") - (newline)))))) - -(display ";;;; benchmarking creation...") (newline) - -(display-eval - (define (fector . args) - (persistent-fector (fold (lambda (v fv) (fector-push! fv v)) - (transient-fector) - args)))) - -(benchmark (apply ivector (iota bench-size))) -(benchmark (apply ivector-u32 (iota bench-size))) -(benchmark (iota bench-size)) -(benchmark (apply vector (iota bench-size))) -(benchmark (apply u32vector (iota bench-size))) -(benchmark (list->vlist (iota bench-size))) -(benchmark (apply fector (iota bench-size))) - -(display ";;;; benchmarking iteration...") (newline) - -(display-eval (define bench-ivector (apply ivector (iota bench-size)))) -(display-eval (define bench-ivector-u32 (apply ivector-u32 (iota bench-size)))) -(display-eval (define bench-list (iota bench-size))) -(display-eval (define bench-vector (apply vector (iota bench-size)))) -(display-eval (define bench-u32vector (apply u32vector (iota bench-size)))) -(display-eval (define bench-vlist (list->vlist (iota bench-size)))) -(display-eval (define bench-fector (apply fector (iota bench-size)))) -(display-eval (define bench-bytevector-u32 - (uint-list->bytevector (iota bench-size) - (native-endianness) - 4))) - -(benchmark (ivector-fold + 0 bench-ivector)) -(benchmark (ivector-u32-fold + 0 bench-ivector-u32)) -(benchmark (fold + 0 bench-list)) -(benchmark (vector-fold + 0 bench-vector)) -(benchmark (vlist-fold + 0 bench-vlist)) -(benchmark (fector-fold + bench-fector 0)) - -(display ";;;; benchmarking iteration by index...") (newline) - -(display-eval - (define-syntax iteration-by-index - (syntax-rules () - ((_ *length *ref *vector *step) - (let ((len (*length *vector))) - (let iter ((i 0) (acc 0)) - (if (< i len) - (iter (+ i *step) - (+ acc (*ref *vector i))) - acc))))))) - -(display-eval - (define-syntax iteration-by-index-truncate - (syntax-rules () - ((_ *length *ref *vector *step) - (let ((len (*length *vector))) - (let iter ((i 0) (acc 0)) - (if (< i len) - (iter (+ i *step) - (logand #xffffffffFFFFFFFF - (+ acc (*ref *vector i)))) - acc))))))) - -(benchmark (iteration-by-index ivector-length - ivector-ref - bench-ivector 1)) -(benchmark (iteration-by-index ivector-u32-length - ivector-u32-ref - bench-ivector-u32 1)) -(benchmark (iteration-by-index vector-length - vector-ref - bench-vector 1)) -(benchmark (iteration-by-index u32vector-length - u32vector-ref - bench-u32vector 1)) -(benchmark (iteration-by-index vlist-length - vlist-ref - bench-vlist 1)) -(benchmark (iteration-by-index fector-length - fector-ref - bench-fector 1)) -(benchmark (iteration-by-index bytevector-length - bytevector-u32-native-ref - bench-bytevector-u32 4)) - -(benchmark (iteration-by-index-truncate ivector-length - ivector-ref - bench-ivector 1)) -(benchmark (iteration-by-index-truncate ivector-u32-length - ivector-u32-ref - bench-ivector-u32 1)) -(benchmark (iteration-by-index-truncate vector-length - vector-ref - bench-vector 1)) -(benchmark (iteration-by-index-truncate u32vector-length - u32vector-ref - bench-u32vector 1)) -(benchmark (iteration-by-index-truncate vlist-length - vlist-ref - bench-vlist 1)) -(benchmark (iteration-by-index-truncate fector-length - fector-ref - bench-fector 1)) -(benchmark (iteration-by-index-truncate bytevector-length - bytevector-u32-native-ref - bench-bytevector-u32 4)) - -(display ";;;; benchmarking concatenation...") (newline) -(benchmark (ivector-append bench-ivector bench-ivector)) -(benchmark (ivector-u32-append bench-ivector-u32 bench-ivector-u32)) -(benchmark (append bench-list bench-list)) -(benchmark (vector-append bench-vector bench-vector)) -(benchmark (vlist-append bench-vlist bench-vlist)) diff --git a/third_party/immer/extra/guile/example.scm b/third_party/immer/extra/guile/example.scm deleted file mode 100644 index 6649508cedc3..000000000000 --- a/third_party/immer/extra/guile/example.scm +++ /dev/null @@ -1,51 +0,0 @@ -;; -;; immer: immutable data structures for C++ -;; Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -;; -;; This software is distributed under the Boost Software License, Version 1.0. -;; See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -;; - -;; include:intro/start -(use-modules (immer) - (rnrs base)) - -(let ((v1 (ivector 1 "hola" 3 'que #:tal))) - (assert (eq? (ivector-ref v1 3) 'que)) - - (let* ((v2 (ivector-set v1 3 'what)) - (v2 (ivector-update v2 2 (lambda (x) (+ 1 x))))) - (assert (eq? (ivector-ref v1 2) 3)) - (assert (eq? (ivector-ref v1 3) 'que)) - (assert (eq? (ivector-ref v2 2) 4)) - (assert (eq? (ivector-ref v2 3) 'what)) - - (let ((v3 (ivector-push v2 "hehe"))) - (assert (eq? (ivector-length v3) 6)) - (assert (eq? (ivector-ref v3 (- (ivector-length v3) 1)) "hehe"))))) - -(let ((v (apply ivector (iota 10)))) - (assert (eq? (ivector-length v) 10)) - (assert (eq? (ivector-length (ivector-drop v 3)) 7)) - (assert (eq? (ivector-length (ivector-take v 3)) 3)) - (assert (eq? (ivector-length (ivector-append v v)) 20))) - -(let ((v1 (make-ivector 3)) - (v2 (make-ivector 3 ":)"))) - (assert (eq? (ivector-ref v1 2) - (vector-ref (make-vector 3) 2))) - (assert (eq? (ivector-ref v2 2) ":)"))) -;; include:intro/end - -;; Experiments - -(let ((d (dummy))) - (dummy-foo d) - (dummy-bar d 42)) -(gc) - -(func1) -(func2) -(func3 (dummy) 12) -(foo-func1) -(gc) diff --git a/third_party/immer/extra/guile/immer.scm.in b/third_party/immer/extra/guile/immer.scm.in deleted file mode 100644 index 8624aabd5bf4..000000000000 --- a/third_party/immer/extra/guile/immer.scm.in +++ /dev/null @@ -1,5 +0,0 @@ -(define-module (immer)) - -;; The extension automatically exports the names via 'scm_c_export' -(load-extension "@GUILE_EXTENSION_DIR@/libguile-immer" - "init_immer") diff --git a/third_party/immer/extra/guile/scm/detail/convert.hpp b/third_party/immer/extra/guile/scm/detail/convert.hpp deleted file mode 100644 index 4c87ff185669..000000000000 --- a/third_party/immer/extra/guile/scm/detail/convert.hpp +++ /dev/null @@ -1,58 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <scm/detail/util.hpp> - -#include <cstdint> -#include <type_traits> -#include <utility> - -#include <libguile.h> - -namespace scm { -namespace detail { - -template <typename T, typename Enable=void> -struct convert; - -template <typename T> -auto to_scm(T&& v) - -> SCM_DECLTYPE_RETURN( - convert<std::decay_t<T>>::to_scm(std::forward<T>(v))); - -template <typename T> -auto to_cpp(SCM v) - -> SCM_DECLTYPE_RETURN( - convert<std::decay_t<T>>::to_cpp(v)); - -} // namespace detail -} // namespace scm - -#define SCM_DECLARE_NUMERIC_TYPE(cpp_name__, scm_name__) \ - namespace scm { \ - namespace detail { \ - template <> \ - struct convert<cpp_name__> { \ - static cpp_name__ to_cpp(SCM v) { return scm_to_ ## scm_name__(v); } \ - static SCM to_scm(cpp_name__ v) { return scm_from_ ## scm_name__(v); } \ - }; \ - }} /* namespace scm::detail */ \ - /**/ - -SCM_DECLARE_NUMERIC_TYPE(float, double); -SCM_DECLARE_NUMERIC_TYPE(double, double); -SCM_DECLARE_NUMERIC_TYPE(std::int8_t, int8); -SCM_DECLARE_NUMERIC_TYPE(std::int16_t, int16); -SCM_DECLARE_NUMERIC_TYPE(std::int32_t, int32); -SCM_DECLARE_NUMERIC_TYPE(std::int64_t, int64); -SCM_DECLARE_NUMERIC_TYPE(std::uint8_t, uint8); -SCM_DECLARE_NUMERIC_TYPE(std::uint16_t, uint16); -SCM_DECLARE_NUMERIC_TYPE(std::uint32_t, uint32); -SCM_DECLARE_NUMERIC_TYPE(std::uint64_t, uint64); diff --git a/third_party/immer/extra/guile/scm/detail/define.hpp b/third_party/immer/extra/guile/scm/detail/define.hpp deleted file mode 100644 index 08b6e763381f..000000000000 --- a/third_party/immer/extra/guile/scm/detail/define.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#ifndef SCM_AUTO_EXPORT -#define SCM_AUTO_EXPORT 1 -#endif - -#include <scm/detail/subr_wrapper.hpp> -#include <scm/list.hpp> - -namespace scm { -namespace detail { - -template <typename Tag, typename Fn> -static void define_impl(const std::string& name, Fn fn) -{ - using args_t = function_args_t<Fn>; - constexpr auto args_size = pack_size_v<args_t>; - constexpr auto has_rest = std::is_same<pack_last_t<args_t>, scm::args>{}; - constexpr auto arg_count = args_size - has_rest; - auto subr = (scm_t_subr) +subr_wrapper_aux<Tag>(fn, args_t{}); - scm_c_define_gsubr(name.c_str(), arg_count, 0, has_rest, subr); -#if SCM_AUTO_EXPORT - scm_c_export(name.c_str()); -#endif -} - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/finalizer_wrapper.hpp b/third_party/immer/extra/guile/scm/detail/finalizer_wrapper.hpp deleted file mode 100644 index 258249eb2c73..000000000000 --- a/third_party/immer/extra/guile/scm/detail/finalizer_wrapper.hpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <scm/detail/invoke.hpp> -#include <scm/detail/function_args.hpp> -#include <scm/detail/convert.hpp> - -namespace scm { -namespace detail { -// this anonymous namespace should help avoiding registration clashes -// among translation units. -namespace { - -template <typename Tag, typename Fn> -auto finalizer_wrapper_impl(Fn fn, pack<>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] { invoke(fn_); }; -} -template <typename Tag, typename Fn, typename T1> -auto finalizer_wrapper_impl(Fn fn, pack<T1>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] (SCM a1) { invoke(fn_, to_cpp<T1>(a1)); }; -} -template <typename Tag, typename Fn, typename T1, typename T2> -auto finalizer_wrapper_impl(Fn fn, pack<T1, T2>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2) { - invoke(fn_, to_cpp<T1>(a1), to_cpp<T2>(a2)); - }; -} -template <typename Tag, typename Fn, typename T1, typename T2, typename T3> -auto finalizer_wrapper_impl(Fn fn, pack<T1, T2, T3>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2, SCM a3) { - invoke(fn_, to_cpp<T1>(a1), to_cpp<T2>(a2), to_cpp<T3>(a3)); - }; -} - -template <typename Tag, typename Fn> -auto finalizer_wrapper(Fn fn) -{ - return finalizer_wrapper_impl<Tag>(fn, function_args_t<Fn>{}); -} - -} // anonymous namespace -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/function_args.hpp b/third_party/immer/extra/guile/scm/detail/function_args.hpp deleted file mode 100644 index 809e3eb1979b..000000000000 --- a/third_party/immer/extra/guile/scm/detail/function_args.hpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <scm/detail/pack.hpp> -#include <boost/callable_traits/args.hpp> - -namespace scm { -namespace detail { - -template <typename Fn> -using function_args_t = boost::callable_traits::args_t<Fn, pack>; - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/invoke.hpp b/third_party/immer/extra/guile/scm/detail/invoke.hpp deleted file mode 100644 index d9f2b37ccece..000000000000 --- a/third_party/immer/extra/guile/scm/detail/invoke.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -// Adapted from the official std::invoke proposal: -// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4169.html - -#include <type_traits> -#include <functional> - -namespace scm { -namespace detail { - -template <typename Functor, typename... Args> -std::enable_if_t< - std::is_member_pointer<std::decay_t<Functor>>::value, - std::result_of_t<Functor&&(Args&&...)>> -invoke(Functor&& f, Args&&... args) -{ - return std::mem_fn(f)(std::forward<Args>(args)...); -} - -template <typename Functor, typename... Args> -std::enable_if_t< - !std::is_member_pointer<std::decay_t<Functor>>::value, - std::result_of_t<Functor&&(Args&&...)>> -invoke(Functor&& f, Args&&... args) -{ - return std::forward<Functor>(f)(std::forward<Args>(args)...); -} - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/pack.hpp b/third_party/immer/extra/guile/scm/detail/pack.hpp deleted file mode 100644 index 9a1813570bcd..000000000000 --- a/third_party/immer/extra/guile/scm/detail/pack.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -namespace scm { -namespace detail { - -struct none_t; - -template <typename... Ts> -struct pack {}; - -template <typename Pack> -struct pack_size; - -template <typename... Ts> -struct pack_size<pack<Ts...>> -{ - static constexpr auto value = sizeof...(Ts); -}; - -template <typename Pack> -constexpr auto pack_size_v = pack_size<Pack>::value; - -template <typename Pack> -struct pack_last -{ - using type = none_t; -}; - -template <typename T, typename ...Ts> -struct pack_last<pack<T, Ts...>> - : pack_last<pack<Ts...>> -{}; - -template <typename T> -struct pack_last<pack<T>> -{ - using type = T; -}; - -template <typename Pack> -using pack_last_t = typename pack_last<Pack>::type; - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/subr_wrapper.hpp b/third_party/immer/extra/guile/scm/detail/subr_wrapper.hpp deleted file mode 100644 index fc11ff1c51ec..000000000000 --- a/third_party/immer/extra/guile/scm/detail/subr_wrapper.hpp +++ /dev/null @@ -1,111 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <scm/detail/invoke.hpp> -#include <scm/detail/function_args.hpp> -#include <scm/detail/convert.hpp> - -namespace scm { -namespace detail { - -// this anonymous namespace should help avoiding registration clashes -// among translation units. -namespace { - -template <typename Tag, typename R, typename Fn> -auto subr_wrapper_impl(Fn fn, pack<R>, pack<>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] () -> SCM { return to_scm(invoke(fn_)); }; -} -template <typename Tag, typename Fn, typename R, typename T1> -auto subr_wrapper_impl(Fn fn, pack<R>, pack<T1>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] (SCM a1) -> SCM { - return to_scm(invoke(fn_, to_cpp<T1>(a1))); - }; -} -template <typename Tag, typename Fn, typename R, typename T1, typename T2> -auto subr_wrapper_impl(Fn fn, pack<R>, pack<T1, T2>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2) -> SCM { - return to_scm(invoke(fn_, to_cpp<T1>(a1), to_cpp<T2>(a2))); - }; -} -template <typename Tag, typename Fn, typename R, typename T1, typename T2, - typename T3> -auto subr_wrapper_impl(Fn fn, pack<R>, pack<T1, T2, T3>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2, SCM a3) -> SCM { - return to_scm(invoke(fn_, to_cpp<T1>(a1), to_cpp<T2>(a2), - to_cpp<T3>(a3))); - }; -} - -template <typename Tag, typename Fn> -auto subr_wrapper_impl(Fn fn, pack<void>, pack<>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] () -> SCM { invoke(fn_); return SCM_UNSPECIFIED; }; -} -template <typename Tag, typename Fn, typename T1> -auto subr_wrapper_impl(Fn fn, pack<void>, pack<T1>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] (SCM a1) -> SCM { - invoke(fn_, to_cpp<T1>(a1)); return SCM_UNSPECIFIED; - }; -} -template <typename Tag, typename Fn, typename T1, typename T2> -auto subr_wrapper_impl(Fn fn, pack<void>, pack<T1, T2>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2) -> SCM { - invoke(fn_, to_cpp<T1>(a1), to_cpp<T2>(a2)); - return SCM_UNSPECIFIED; - }; -} -template <typename Tag, typename Fn, typename T1, typename T2, typename T3> -auto subr_wrapper_impl(Fn fn, pack<void>, pack<T1, T2, T3>) -{ - check_call_once<Tag, Fn>(); - static const Fn fn_ = fn; - return [] (SCM a1, SCM a2, SCM a3) -> SCM { - invoke(fn_, to_cpp<T1>(a1), to_cpp<T2>(a2), to_cpp<T3>(a3)); - return SCM_UNSPECIFIED; - }; -} - -template <typename Tag, typename Fn, typename... Args> -auto subr_wrapper_aux(Fn fn, pack<Args...>) -{ - return subr_wrapper_impl<Tag>( - fn, pack<std::result_of_t<Fn(Args...)>>{}, pack<Args...>{}); -} - -template <typename Tag, typename Fn> -auto subr_wrapper(Fn fn) -{ - return subr_wrapper_aux<Tag>(fn, function_args_t<Fn>{}); -} - -} // anonymous namespace -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/detail/util.hpp b/third_party/immer/extra/guile/scm/detail/util.hpp deleted file mode 100644 index fdc323722e99..000000000000 --- a/third_party/immer/extra/guile/scm/detail/util.hpp +++ /dev/null @@ -1,49 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <libguile.h> - -namespace scm { -namespace detail { - -#define SCM_DECLTYPE_RETURN(...) \ - decltype(__VA_ARGS__) \ - { return __VA_ARGS__; } \ - /**/ - -template <typename... Ts> -constexpr bool is_valid_v = true; - -template <typename... Ts> -using is_valid_t = void; - -template <typename... Ts> -void check_call_once() -{ - static bool called = false; - if (called) scm_misc_error (nullptr, "Double defined binding. \ -This may be caused because there are multiple C++ binding groups in the same \ -translation unit. You may solve this by using different type tags for each \ -binding group.", SCM_EOL); - called = true; -} - -struct move_sequence -{ - move_sequence() = default; - move_sequence(const move_sequence&) = delete; - move_sequence(move_sequence&& other) - { other.moved_from_ = true; }; - - bool moved_from_ = false; -}; - -} // namespace detail -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/group.hpp b/third_party/immer/extra/guile/scm/group.hpp deleted file mode 100644 index 69cd385820cb..000000000000 --- a/third_party/immer/extra/guile/scm/group.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <scm/detail/define.hpp> -#include <string> - -namespace scm { -namespace detail { - -template <typename Tag, int Seq=0> -struct definer -{ - using this_t = definer; - using next_t = definer<Tag, Seq + 1>; - - std::string group_name_ = {}; - - definer() = default; - definer(definer&&) = default; - - template <int Seq2, - typename Enable=std::enable_if_t<Seq2 + 1 == Seq>> - definer(definer<Tag, Seq2>) - {} - - template <typename Fn> - next_t define(std::string name, Fn fn) && - { - define_impl<this_t>(name, fn); - return { std::move(*this) }; - } - - template <typename Fn> - next_t maker(Fn fn) && - { - define_impl<this_t>("make", fn); - return { std::move(*this) }; - } -}; - -template <typename Tag, int Seq=0> -struct group_definer -{ - using this_t = group_definer; - using next_t = group_definer<Tag, Seq + 1>; - - std::string group_name_ = {}; - - group_definer(std::string name) - : group_name_{std::move(name)} {} - - group_definer(group_definer&&) = default; - - template <int Seq2, - typename Enable=std::enable_if_t<Seq2 + 1 == Seq>> - group_definer(group_definer<Tag, Seq2>) - {} - - template <typename Fn> - next_t define(std::string name, Fn fn) && - { - define_impl<this_t>(group_name_ + "-" + name, fn); - return { std::move(*this) }; - } -}; - -} // namespace detail - -template <typename Tag=void> -detail::definer<Tag> group() -{ - return {}; -} - -template <typename Tag=void> -detail::group_definer<Tag> group(std::string name) -{ - return { std::move(name) }; -} - -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/list.hpp b/third_party/immer/extra/guile/scm/list.hpp deleted file mode 100644 index dc162c200244..000000000000 --- a/third_party/immer/extra/guile/scm/list.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <scm/val.hpp> -#include <iostream> - -namespace scm { - -struct list : detail::wrapper -{ - using base_t = detail::wrapper; - using base_t::base_t; - - using iterator = list; - using value_type = val; - - list() : base_t{SCM_EOL} {}; - list end() const { return {}; } - list begin() const { return *this; } - - explicit operator bool() { return handle_ != SCM_EOL; } - - val operator* () const { return val{scm_car(handle_)}; } - - list& operator++ () - { - handle_ = scm_cdr(handle_); - return *this; - } - - list operator++ (int) - { - auto result = *this; - result.handle_ = scm_cdr(handle_); - return result; - } -}; - -struct args : list -{ - using list::list; -}; - -} // namespace scm - -SCM_DECLARE_WRAPPER_TYPE(scm::list); -SCM_DECLARE_WRAPPER_TYPE(scm::args); diff --git a/third_party/immer/extra/guile/scm/scm.hpp b/third_party/immer/extra/guile/scm/scm.hpp deleted file mode 100644 index f4e4989a44a9..000000000000 --- a/third_party/immer/extra/guile/scm/scm.hpp +++ /dev/null @@ -1,14 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <scm/val.hpp> -#include <scm/list.hpp> -#include <scm/group.hpp> -#include <scm/type.hpp> diff --git a/third_party/immer/extra/guile/scm/type.hpp b/third_party/immer/extra/guile/scm/type.hpp deleted file mode 100644 index da53ed46ef8b..000000000000 --- a/third_party/immer/extra/guile/scm/type.hpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <scm/detail/finalizer_wrapper.hpp> -#include <scm/detail/define.hpp> -#include <string> - -namespace scm { -namespace detail { - -template <typename T> -struct foreign_type_storage -{ - static SCM data; -}; - -template <typename T> -SCM foreign_type_storage<T>::data = SCM_UNSPECIFIED; - -template <typename T> -struct convert_foreign_type -{ - using storage_t = foreign_type_storage<T>; - static T& to_cpp(SCM v) - { - assert(storage_t::data != SCM_UNSPECIFIED && - "can not convert to undefined type"); - scm_assert_foreign_object_type(storage_t::data, v); - return *(T*)scm_foreign_object_ref(v, 0); - } - - template <typename U> - static SCM to_scm(U&& v) - { - assert(storage_t::data != SCM_UNSPECIFIED && - "can not convert from undefined type"); - return scm_make_foreign_object_1( - storage_t::data, - new (scm_gc_malloc(sizeof(T), "scmpp")) T( - std::forward<U>(v))); - } -}; - -// Assume that every other type is foreign -template <typename T> -struct convert<T, - std::enable_if_t<!std::is_fundamental<T>::value && - // only value types are supported at - // the moment but the story might - // change later... - !std::is_pointer<T>::value>> - : convert_foreign_type<T> -{ -}; - -template <typename Tag, typename T, int Seq=0> -struct type_definer : move_sequence -{ - using this_t = type_definer; - using next_t = type_definer<Tag, T, Seq + 1>; - - std::string type_name_ = {}; - scm_t_struct_finalize finalizer_ = nullptr; - - type_definer(type_definer&&) = default; - - type_definer(std::string type_name) - : type_name_(std::move(type_name)) - {} - - ~type_definer() - { - if (!moved_from_) { - using storage_t = detail::foreign_type_storage<T>; - assert(storage_t::data == SCM_UNSPECIFIED); - storage_t::data = scm_make_foreign_object_type( - scm_from_utf8_symbol(("<" + type_name_ + ">").c_str()), - scm_list_1(scm_from_utf8_symbol("data")), - finalizer_); - } - } - - template <int Seq2, typename Enable=std::enable_if_t<Seq2 + 1 == Seq>> - type_definer(type_definer<Tag, T, Seq2> r) - : move_sequence{std::move(r)} - , type_name_{std::move(r.type_name_)} - , finalizer_{std::move(r.finalizer_)} - {} - - next_t constructor() && - { - define_impl<this_t>(type_name_, [] { return T{}; }); - return { std::move(*this) }; - } - - template <typename Fn> - next_t constructor(Fn fn) && - { - define_impl<this_t>(type_name_, fn); - return { std::move(*this) }; - } - - next_t finalizer() && - { - finalizer_ = (scm_t_struct_finalize) +finalizer_wrapper<Tag>( - [] (T& x) { x.~T(); }); - return { std::move(*this) }; - } - - template <typename Fn> - next_t finalizer(Fn fn) && - { - finalizer_ = (scm_t_struct_finalize) +finalizer_wrapper<Tag>(fn); - return { std::move(*this) }; - } - - next_t maker() && - { - define_impl<this_t>("make-" + type_name_, [] { return T{}; }); - return { std::move(*this) }; - } - - template <typename Fn> - next_t maker(Fn fn) && - { - define_impl<this_t>("make-" + type_name_, fn); - return { std::move(*this) }; - } - - template <typename Fn> - next_t define(std::string name, Fn fn) && - { - define_impl<this_t>(type_name_ + "-" + name, fn); - return { std::move(*this) }; - } -}; - -} // namespace detail - -template <typename Tag, typename T=Tag> -detail::type_definer<Tag, T> type(std::string type_name) -{ - return { type_name }; -} - -} // namespace scm diff --git a/third_party/immer/extra/guile/scm/val.hpp b/third_party/immer/extra/guile/scm/val.hpp deleted file mode 100644 index 63d7189262da..000000000000 --- a/third_party/immer/extra/guile/scm/val.hpp +++ /dev/null @@ -1,88 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <scm/detail/convert.hpp> - -namespace scm { -namespace detail { - -template <typename T> -struct convert_wrapper_type -{ - static T to_cpp(SCM v) { return T{v}; } - static SCM to_scm(T v) { return v.get(); } -}; - -struct wrapper -{ - wrapper() = default; - wrapper(SCM hdl) : handle_{hdl} {} - SCM get() const { return handle_; } - operator SCM () const { return handle_; } - - bool operator==(wrapper other) { return handle_ == other.handle_; } - bool operator!=(wrapper other) { return handle_ != other.handle_; } - -protected: - SCM handle_ = SCM_UNSPECIFIED; -}; - -} // namespace detail - -struct val : detail::wrapper -{ - using base_t = detail::wrapper; - using base_t::base_t; - - template <typename T, - typename = std::enable_if_t< - (!std::is_same<std::decay_t<T>, val>{} && - !std::is_same<std::decay_t<T>, SCM>{})>> - val(T&& x) - : base_t(detail::to_scm(std::forward<T>(x))) - {} - - template <typename T, - typename = std::enable_if_t< - std::is_same<T, decltype(detail::to_cpp<T>(SCM{}))>{}>> - operator T() const { return detail::to_cpp<T>(handle_); } - - template <typename T, - typename = std::enable_if_t< - std::is_same<T&, decltype(detail::to_cpp<T>(SCM{}))>{}>> - operator T& () const { return detail::to_cpp<T>(handle_); } - - template <typename T, - typename = std::enable_if_t< - std::is_same<const T&, decltype(detail::to_cpp<T>(SCM{}))>{}>> - operator const T& () const { return detail::to_cpp<T>(handle_); } - - val operator() () const - { return val{scm_call_0(get())}; } - val operator() (val a0) const - { return val{scm_call_1(get(), a0)}; } - val operator() (val a0, val a1) const - { return val{scm_call_2(get(), a0, a1)}; } - val operator() (val a0, val a1, val a3) const - { return val{scm_call_3(get(), a0, a1, a3)}; } -}; - -} // namespace scm - -#define SCM_DECLARE_WRAPPER_TYPE(cpp_name__) \ - namespace scm { \ - namespace detail { \ - template <> \ - struct convert<cpp_name__> \ - : convert_wrapper_type<cpp_name__> {}; \ - }} /* namespace scm::detail */ \ - /**/ - -SCM_DECLARE_WRAPPER_TYPE(val); diff --git a/third_party/immer/extra/guile/src/immer.cpp b/third_party/immer/extra/guile/src/immer.cpp deleted file mode 100644 index 7933447a8d18..000000000000 --- a/third_party/immer/extra/guile/src/immer.cpp +++ /dev/null @@ -1,153 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/algorithm.hpp> -#include <scm/scm.hpp> -#include <iostream> - -namespace { - -struct guile_heap -{ - static void* allocate(std::size_t size) - { return scm_gc_malloc(size, "immer"); } - - static void* allocate(std::size_t size, immer::norefs_tag) - { return scm_gc_malloc_pointerless(size, "immer"); } - - template <typename ...Tags> - static void deallocate(std::size_t size, void* obj, Tags...) - { scm_gc_free(obj, size, "immer"); } -}; - -using guile_memory = immer::memory_policy< - immer::heap_policy<guile_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename T> -using guile_ivector = immer::flex_vector<T, guile_memory>; - -struct dummy -{ - SCM port_ = scm_current_warning_port(); - - dummy(dummy&&) - { scm_puts("~~ dummy move constructor\n", port_); } - - dummy() - { scm_puts("~~ dummy default constructor\n", port_); } - - ~dummy() - { scm_puts("~~ dummy finalized\n", port_); } - - void foo() - { scm_puts("~~ dummy foo\n", port_); } - - int bar(int x) - { - auto res = x + 42; - scm_puts("~~ dummy bar: ", port_); - scm_display(scm::val{res}, port_); - scm_newline(port_); - return res; - } -}; - -template <int I> -void func() -{ - auto port = scm_current_warning_port(); - scm_puts("~~ func", port); - scm_display(scm_from_int(I), port); - scm_newline(port); -} - -template <typename T = scm::val> -void init_ivector(std::string type_name = "") -{ - using namespace std::string_literals; - - using self_t = guile_ivector<T>; - using size_t = typename self_t::size_type; - - auto name = "ivector"s + (type_name.empty() ? ""s : "-" + type_name); - - scm::type<self_t>(name) - .constructor([] (scm::args rest) { - return self_t(rest.begin(), rest.end()); - }) - .maker([] (size_t n, scm::args rest) { - return self_t(n, rest ? *rest : scm::val{}); - }) - .define("ref", &self_t::operator[]) - .define("length", &self_t::size) - .define("set", [] (const self_t& v, size_t i, scm::val x) { - return v.set(i, x); - }) - .define("update", [] (const self_t& v, size_t i, scm::val fn) { - return v.update(i, fn); - }) - .define("push", [] (const self_t& v, scm::val x) { - return v.push_back(x); - }) - .define("take", [] (const self_t& v, size_t s) { - return v.take(s); - }) - .define("drop", [] (const self_t& v, size_t s) { - return v.drop(s); - }) - .define("append", [] (self_t v, scm::args rest) { - for (auto x : rest) - v = v + x; - return v; - }) - .define("fold", [] (scm::val fn, scm::val first, const self_t& v) { - return immer::accumulate(v, first, fn); - }) - ; -} - -} // anonymous namespace - -struct bar_tag_t {}; - -extern "C" -void init_immer() -{ - scm::type<dummy>("dummy") - .constructor() - .finalizer() - .define("foo", &dummy::foo) - .define("bar", &dummy::bar); - - scm::group() - .define("func1", func<1>); - - scm::group<bar_tag_t>() - .define("func2", func<2>) - .define("func3", &dummy::bar); - - scm::group("foo") - .define("func1", func<1>); - - init_ivector(); - init_ivector<std::uint8_t>("u8"); - init_ivector<std::uint16_t>("u16"); - init_ivector<std::uint32_t>("u32"); - init_ivector<std::uint64_t>("u64"); - init_ivector<std::int8_t>("s8"); - init_ivector<std::int16_t>("s16"); - init_ivector<std::int32_t>("s32"); - init_ivector<std::int64_t>("s64"); - init_ivector<float>("f32"); - init_ivector<double>("f64"); -} diff --git a/third_party/immer/extra/js/immer.cpp b/third_party/immer/extra/js/immer.cpp deleted file mode 100644 index d0d77c8a2c55..000000000000 --- a/third_party/immer/extra/js/immer.cpp +++ /dev/null @@ -1,79 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> -#include <emscripten/bind.h> - -namespace { - -using memory_t = immer::memory_policy< - immer::unsafe_free_list_heap_policy<immer::malloc_heap>, - immer::unsafe_refcount_policy>; - -template <typename T> -using js_vector_t = immer::vector<T, memory_t>; - -template <typename VectorT> -VectorT range(typename VectorT::value_type first, - typename VectorT::value_type last) -{ - auto v = VectorT{}; - for (; first != last; ++first) - v = std::move(v).push_back(first); - return v; -} - -template <typename VectorT> -VectorT range_slow(typename VectorT::value_type first, - typename VectorT::value_type last) -{ - auto v = VectorT{}; - for (; first != last; ++first) - v = v.push_back(first); - return v; -} - -template <typename VectorT> -VectorT push_back(VectorT& v, typename VectorT::value_type x) -{ return v.push_back(x); } - -template <typename VectorT> -VectorT set(VectorT& v, std::size_t i, typename VectorT::value_type x) -{ return v.set(i, x); } - -template <typename T> -void bind_vector(const char* name) -{ - using emscripten::class_; - - using vector_t = js_vector_t<T>; - - class_<vector_t>(name) - .constructor() - .function("push", &push_back<vector_t>) - .function("set", &set<vector_t>) - .function("get", &vector_t::operator[]) - .property("size", &vector_t::size); -} - -} // anonymous namespace - -EMSCRIPTEN_BINDINGS(immer) -{ - using emscripten::function; - - bind_vector<emscripten::val>("Vector"); - bind_vector<int>("VectorInt"); - bind_vector<double>("VectorNumber"); - - function("range_int", &range<js_vector_t<int>>); - function("rangeSlow_int", &range_slow<js_vector_t<int>>); - function("range_double", &range<js_vector_t<double>>); - function("rangeSlow_double", &range_slow<js_vector_t<double>>); -} diff --git a/third_party/immer/extra/js/index.js b/third_party/immer/extra/js/index.js deleted file mode 100644 index 6da994164f8e..000000000000 --- a/third_party/immer/extra/js/index.js +++ /dev/null @@ -1,74 +0,0 @@ -/* - * immer: immutable data structures for C++ - * Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente - * - * This software is distributed under the Boost Software License, Version 1.0. - * See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt - */ - -var immer = Module - -var N = 1000 - -var suite = new Benchmark.Suite('push') - .add('Immutable.List', function(){ - var v = new Immutable.List - for (var x = 0; x < N; ++x) - v = v.push(x) - }) - .add('mori.vector', function(){ - var v = mori.vector() - for (var x = 0; x < N; ++x) - v = mori.conj.f2(v, x) - }) - .add('mori.vector-Transient', function(){ - var v = mori.mutable.thaw(mori.vector()) - for (var x = 0; x < N; ++x) - v = mori.mutable.conj.f2(v, x) - return mori.mutable.freeze(v) - }) - .add('immer.Vector', function(){ - var v = new immer.Vector - for (var x = 0; x < N; ++x) { - var v_ = v - v = v.push(x) - v_.delete() - } - }) - .add('immer.VectorInt', function(){ - var v = new immer.VectorInt - for (var x = 0; x < N; ++x) { - var v_ = v - v = v.push(x) - v_.delete() - } - v.delete() - }) - .add('immer.VectorNumber', function(){ - var v = new immer.VectorNumber - for (var x = 0; x < N; ++x) { - var v_ = v - v = v.push(x) - v_.delete() - } - v.delete() - }) - .add('immer.VectorInt-Native', function(){ - immer.rangeSlow_int(0, N).delete() - }) - .add('immer.VectorInt-NativeTransient', function(){ - immer.range_int(0, N).delete() - }) - .add('immer.VectorDouble-Native', function(){ - immer.rangeSlow_double(0, N).delete() - }) - .add('immer.VectorDouble-NativeTransient', function(){ - immer.range_double(0, N).delete() - }) - .on('cycle', function(event) { - console.log(String(event.target)); - }) - .on('complete', function() { - console.log('Fastest is ' + this.filter('fastest').map('name')); - }) - .run({ 'async': true }) diff --git a/third_party/immer/extra/js/index.tpl.html b/third_party/immer/extra/js/index.tpl.html deleted file mode 100644 index fdbd40a86a10..000000000000 --- a/third_party/immer/extra/js/index.tpl.html +++ /dev/null @@ -1,77 +0,0 @@ -<!-- - immer: immutable data structures for C++ - Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente - - This software is distributed under the Boost Software License, Version 1.0. - See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt ---> -<!DOCTYPE html> -<html> - <head> - <meta charset="UTF-8"> - <script src="../lib/lodash.js"></script> - <script src="../lib/platform.js"></script> - <script src="../lib/benchmark.js"></script> - <script src="../lib/immutable.min.js"></script> - <script src="../lib/mori.js"></script> - <script> - </script> - </head> - <body> - <script> - var IMMER_WASM_HAS_MEM = false; - var IMMER_JS_FILE = '%IMMER_JS%' - var Module = {}; - - if (IMMER_JS_FILE.endsWith('wasm.js')) - loadWasm() - else if (IMMER_JS_FILE.endsWith('asmjs.js')) - loadAsmjs() - else - throw Error('Wrong format') - - function loadAsync(u, c) { - var d = document, t = 'script', - o = d.createElement(t), - s = d.getElementsByTagName(t)[0]; - o.src = u; - if (c) { o.addEventListener('load', function (e) { c(null, e); }, false); } - s.parentNode.insertBefore(o, s); - } - - function loadAsmjs() { - loadAsync(IMMER_JS_FILE, function () { - loadAsync('../index.js') - }); - } - - function loadWasm() { - var xhr = new XMLHttpRequest(); - var basename = IMMER_JS_FILE.substring(0, IMMER_JS_FILE.length-3) - xhr.open('GET', basename + '.wasm', true); - xhr.responseType = 'arraybuffer'; - xhr.onload = function() { - Module.wasmBinary = xhr.response; - if (IMMER_WASM_HAS_MEM) { - (function() { - var memoryInitializer = IMMER_JS_FILE + '.mem'; - if (typeof Module['locateFile'] === 'function') { - memoryInitializer = Module['locateFile'](memoryInitializer); - } else if (Module['memoryInitializerPrefixURL']) { - memoryInitializer = Module['memoryInitializerPrefixURL'] + memoryInitializer; - } - var xhr = Module['memoryInitializerRequest'] = new XMLHttpRequest(); - xhr.open('GET', memoryInitializer, true); - xhr.responseType = 'arraybuffer'; - xhr.send(null); - })(); - } - loadAsync(IMMER_JS_FILE, function () { - loadAsync('../index.js') - }); - }; - xhr.send(null); - } - </script> - </body> -</html> diff --git a/third_party/immer/extra/js/lib/benchmark.js b/third_party/immer/extra/js/lib/benchmark.js deleted file mode 100644 index 11bc2babaf25..000000000000 --- a/third_party/immer/extra/js/lib/benchmark.js +++ /dev/null @@ -1,2811 +0,0 @@ -/*! - * Benchmark.js <https://benchmarkjs.com/> - * Copyright 2010-2016 Mathias Bynens <https://mths.be/> - * Based on JSLitmus.js, copyright Robert Kieffer <http://broofa.com/> - * Modified by John-David Dalton <http://allyoucanleet.com/> - * Available under MIT license <https://mths.be/mit> - */ -;(function() { - 'use strict'; - - /** Used as a safe reference for `undefined` in pre ES5 environments. */ - var undefined; - - /** Used to determine if values are of the language type Object. */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object. */ - var root = (objectTypes[typeof window] && window) || this; - - /** Detect free variable `define`. */ - var freeDefine = typeof define == 'function' && typeof define.amd == 'object' && define.amd && define; - - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root`. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** Detect free variable `require`. */ - var freeRequire = typeof require == 'function' && require; - - /** Used to assign each benchmark an incremented id. */ - var counter = 0; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** Used to detect primitive types. */ - var rePrimitive = /^(?:boolean|number|string|undefined)$/; - - /** Used to make every compiled test unique. */ - var uidCounter = 0; - - /** Used to assign default `context` object properties. */ - var contextProps = [ - 'Array', 'Date', 'Function', 'Math', 'Object', 'RegExp', 'String', '_', - 'clearTimeout', 'chrome', 'chromium', 'document', 'navigator', 'phantom', - 'platform', 'process', 'runtime', 'setTimeout' - ]; - - /** Used to avoid hz of Infinity. */ - var divisors = { - '1': 4096, - '2': 512, - '3': 64, - '4': 8, - '5': 0 - }; - - /** - * T-Distribution two-tailed critical values for 95% confidence. - * For more info see http://www.itl.nist.gov/div898/handbook/eda/section3/eda3672.htm. - */ - var tTable = { - '1': 12.706, '2': 4.303, '3': 3.182, '4': 2.776, '5': 2.571, '6': 2.447, - '7': 2.365, '8': 2.306, '9': 2.262, '10': 2.228, '11': 2.201, '12': 2.179, - '13': 2.16, '14': 2.145, '15': 2.131, '16': 2.12, '17': 2.11, '18': 2.101, - '19': 2.093, '20': 2.086, '21': 2.08, '22': 2.074, '23': 2.069, '24': 2.064, - '25': 2.06, '26': 2.056, '27': 2.052, '28': 2.048, '29': 2.045, '30': 2.042, - 'infinity': 1.96 - }; - - /** - * Critical Mann-Whitney U-values for 95% confidence. - * For more info see http://www.saburchill.com/IBbiology/stats/003.html. - */ - var uTable = { - '5': [0, 1, 2], - '6': [1, 2, 3, 5], - '7': [1, 3, 5, 6, 8], - '8': [2, 4, 6, 8, 10, 13], - '9': [2, 4, 7, 10, 12, 15, 17], - '10': [3, 5, 8, 11, 14, 17, 20, 23], - '11': [3, 6, 9, 13, 16, 19, 23, 26, 30], - '12': [4, 7, 11, 14, 18, 22, 26, 29, 33, 37], - '13': [4, 8, 12, 16, 20, 24, 28, 33, 37, 41, 45], - '14': [5, 9, 13, 17, 22, 26, 31, 36, 40, 45, 50, 55], - '15': [5, 10, 14, 19, 24, 29, 34, 39, 44, 49, 54, 59, 64], - '16': [6, 11, 15, 21, 26, 31, 37, 42, 47, 53, 59, 64, 70, 75], - '17': [6, 11, 17, 22, 28, 34, 39, 45, 51, 57, 63, 67, 75, 81, 87], - '18': [7, 12, 18, 24, 30, 36, 42, 48, 55, 61, 67, 74, 80, 86, 93, 99], - '19': [7, 13, 19, 25, 32, 38, 45, 52, 58, 65, 72, 78, 85, 92, 99, 106, 113], - '20': [8, 14, 20, 27, 34, 41, 48, 55, 62, 69, 76, 83, 90, 98, 105, 112, 119, 127], - '21': [8, 15, 22, 29, 36, 43, 50, 58, 65, 73, 80, 88, 96, 103, 111, 119, 126, 134, 142], - '22': [9, 16, 23, 30, 38, 45, 53, 61, 69, 77, 85, 93, 101, 109, 117, 125, 133, 141, 150, 158], - '23': [9, 17, 24, 32, 40, 48, 56, 64, 73, 81, 89, 98, 106, 115, 123, 132, 140, 149, 157, 166, 175], - '24': [10, 17, 25, 33, 42, 50, 59, 67, 76, 85, 94, 102, 111, 120, 129, 138, 147, 156, 165, 174, 183, 192], - '25': [10, 18, 27, 35, 44, 53, 62, 71, 80, 89, 98, 107, 117, 126, 135, 145, 154, 163, 173, 182, 192, 201, 211], - '26': [11, 19, 28, 37, 46, 55, 64, 74, 83, 93, 102, 112, 122, 132, 141, 151, 161, 171, 181, 191, 200, 210, 220, 230], - '27': [11, 20, 29, 38, 48, 57, 67, 77, 87, 97, 107, 118, 125, 138, 147, 158, 168, 178, 188, 199, 209, 219, 230, 240, 250], - '28': [12, 21, 30, 40, 50, 60, 70, 80, 90, 101, 111, 122, 132, 143, 154, 164, 175, 186, 196, 207, 218, 228, 239, 250, 261, 272], - '29': [13, 22, 32, 42, 52, 62, 73, 83, 94, 105, 116, 127, 138, 149, 160, 171, 182, 193, 204, 215, 226, 238, 249, 260, 271, 282, 294], - '30': [13, 23, 33, 43, 54, 65, 76, 87, 98, 109, 120, 131, 143, 154, 166, 177, 189, 200, 212, 223, 235, 247, 258, 270, 282, 293, 305, 317] - }; - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new `Benchmark` function using the given `context` object. - * - * @static - * @memberOf Benchmark - * @param {Object} [context=root] The context object. - * @returns {Function} Returns a new `Benchmark` function. - */ - function runInContext(context) { - // Exit early if unable to acquire lodash. - var _ = context && context._ || require('lodash') || root._; - if (!_) { - Benchmark.runInContext = runInContext; - return Benchmark; - } - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See http://es5.github.io/#x11.1.5. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - - /** Native constructor references. */ - var Array = context.Array, - Date = context.Date, - Function = context.Function, - Math = context.Math, - Object = context.Object, - RegExp = context.RegExp, - String = context.String; - - /** Used for `Array` and `Object` method references. */ - var arrayRef = [], - objectProto = Object.prototype; - - /** Native method shortcuts. */ - var abs = Math.abs, - clearTimeout = context.clearTimeout, - floor = Math.floor, - log = Math.log, - max = Math.max, - min = Math.min, - pow = Math.pow, - push = arrayRef.push, - setTimeout = context.setTimeout, - shift = arrayRef.shift, - slice = arrayRef.slice, - sqrt = Math.sqrt, - toString = objectProto.toString, - unshift = arrayRef.unshift; - - /** Used to avoid inclusion in Browserified bundles. */ - var req = require; - - /** Detect DOM document object. */ - var doc = isHostType(context, 'document') && context.document; - - /** Used to access Wade Simmons' Node.js `microtime` module. */ - var microtimeObject = req('microtime'); - - /** Used to access Node.js's high resolution timer. */ - var processObject = isHostType(context, 'process') && context.process; - - /** Used to prevent a `removeChild` memory leak in IE < 9. */ - var trash = doc && doc.createElement('div'); - - /** Used to integrity check compiled tests. */ - var uid = 'uid' + _.now(); - - /** Used to avoid infinite recursion when methods call each other. */ - var calledBy = {}; - - /** - * An object used to flag environments/features. - * - * @static - * @memberOf Benchmark - * @type Object - */ - var support = {}; - - (function() { - - /** - * Detect if running in a browser environment. - * - * @memberOf Benchmark.support - * @type boolean - */ - support.browser = doc && isHostType(context, 'navigator') && !isHostType(context, 'phantom'); - - /** - * Detect if the Timers API exists. - * - * @memberOf Benchmark.support - * @type boolean - */ - support.timeout = isHostType(context, 'setTimeout') && isHostType(context, 'clearTimeout'); - - /** - * Detect if function decompilation is support. - * - * @name decompilation - * @memberOf Benchmark.support - * @type boolean - */ - try { - // Safari 2.x removes commas in object literals from `Function#toString` results. - // See http://webk.it/11609 for more details. - // Firefox 3.6 and Opera 9.25 strip grouping parentheses from `Function#toString` results. - // See http://bugzil.la/559438 for more details. - support.decompilation = Function( - ('return (' + (function(x) { return { 'x': '' + (1 + x) + '', 'y': 0 }; }) + ')') - // Avoid issues with code added by Istanbul. - .replace(/__cov__[^;]+;/g, '') - )()(0).x === '1'; - } catch(e) { - support.decompilation = false; - } - }()); - - /** - * Timer object used by `clock()` and `Deferred#resolve`. - * - * @private - * @type Object - */ - var timer = { - - /** - * The timer namespace object or constructor. - * - * @private - * @memberOf timer - * @type {Function|Object} - */ - 'ns': Date, - - /** - * Starts the deferred timer. - * - * @private - * @memberOf timer - * @param {Object} deferred The deferred instance. - */ - 'start': null, // Lazy defined in `clock()`. - - /** - * Stops the deferred timer. - * - * @private - * @memberOf timer - * @param {Object} deferred The deferred instance. - */ - 'stop': null // Lazy defined in `clock()`. - }; - - /*------------------------------------------------------------------------*/ - - /** - * The Benchmark constructor. - * - * Note: The Benchmark constructor exposes a handful of lodash methods to - * make working with arrays, collections, and objects easier. The lodash - * methods are: - * [`each/forEach`](https://lodash.com/docs#forEach), [`forOwn`](https://lodash.com/docs#forOwn), - * [`has`](https://lodash.com/docs#has), [`indexOf`](https://lodash.com/docs#indexOf), - * [`map`](https://lodash.com/docs#map), and [`reduce`](https://lodash.com/docs#reduce) - * - * @constructor - * @param {string} name A name to identify the benchmark. - * @param {Function|string} fn The test to benchmark. - * @param {Object} [options={}] Options object. - * @example - * - * // basic usage (the `new` operator is optional) - * var bench = new Benchmark(fn); - * - * // or using a name first - * var bench = new Benchmark('foo', fn); - * - * // or with options - * var bench = new Benchmark('foo', fn, { - * - * // displayed by `Benchmark#toString` if `name` is not available - * 'id': 'xyz', - * - * // called when the benchmark starts running - * 'onStart': onStart, - * - * // called after each run cycle - * 'onCycle': onCycle, - * - * // called when aborted - * 'onAbort': onAbort, - * - * // called when a test errors - * 'onError': onError, - * - * // called when reset - * 'onReset': onReset, - * - * // called when the benchmark completes running - * 'onComplete': onComplete, - * - * // compiled/called before the test loop - * 'setup': setup, - * - * // compiled/called after the test loop - * 'teardown': teardown - * }); - * - * // or name and options - * var bench = new Benchmark('foo', { - * - * // a flag to indicate the benchmark is deferred - * 'defer': true, - * - * // benchmark test function - * 'fn': function(deferred) { - * // call `Deferred#resolve` when the deferred test is finished - * deferred.resolve(); - * } - * }); - * - * // or options only - * var bench = new Benchmark({ - * - * // benchmark name - * 'name': 'foo', - * - * // benchmark test as a string - * 'fn': '[1,2,3,4].sort()' - * }); - * - * // a test's `this` binding is set to the benchmark instance - * var bench = new Benchmark('foo', function() { - * 'My name is '.concat(this.name); // "My name is foo" - * }); - */ - function Benchmark(name, fn, options) { - var bench = this; - - // Allow instance creation without the `new` operator. - if (!(bench instanceof Benchmark)) { - return new Benchmark(name, fn, options); - } - // Juggle arguments. - if (_.isPlainObject(name)) { - // 1 argument (options). - options = name; - } - else if (_.isFunction(name)) { - // 2 arguments (fn, options). - options = fn; - fn = name; - } - else if (_.isPlainObject(fn)) { - // 2 arguments (name, options). - options = fn; - fn = null; - bench.name = name; - } - else { - // 3 arguments (name, fn [, options]). - bench.name = name; - } - setOptions(bench, options); - - bench.id || (bench.id = ++counter); - bench.fn == null && (bench.fn = fn); - - bench.stats = cloneDeep(bench.stats); - bench.times = cloneDeep(bench.times); - } - - /** - * The Deferred constructor. - * - * @constructor - * @memberOf Benchmark - * @param {Object} clone The cloned benchmark instance. - */ - function Deferred(clone) { - var deferred = this; - if (!(deferred instanceof Deferred)) { - return new Deferred(clone); - } - deferred.benchmark = clone; - clock(deferred); - } - - /** - * The Event constructor. - * - * @constructor - * @memberOf Benchmark - * @param {Object|string} type The event type. - */ - function Event(type) { - var event = this; - if (type instanceof Event) { - return type; - } - return (event instanceof Event) - ? _.assign(event, { 'timeStamp': _.now() }, typeof type == 'string' ? { 'type': type } : type) - : new Event(type); - } - - /** - * The Suite constructor. - * - * Note: Each Suite instance has a handful of wrapped lodash methods to - * make working with Suites easier. The wrapped lodash methods are: - * [`each/forEach`](https://lodash.com/docs#forEach), [`indexOf`](https://lodash.com/docs#indexOf), - * [`map`](https://lodash.com/docs#map), and [`reduce`](https://lodash.com/docs#reduce) - * - * @constructor - * @memberOf Benchmark - * @param {string} name A name to identify the suite. - * @param {Object} [options={}] Options object. - * @example - * - * // basic usage (the `new` operator is optional) - * var suite = new Benchmark.Suite; - * - * // or using a name first - * var suite = new Benchmark.Suite('foo'); - * - * // or with options - * var suite = new Benchmark.Suite('foo', { - * - * // called when the suite starts running - * 'onStart': onStart, - * - * // called between running benchmarks - * 'onCycle': onCycle, - * - * // called when aborted - * 'onAbort': onAbort, - * - * // called when a test errors - * 'onError': onError, - * - * // called when reset - * 'onReset': onReset, - * - * // called when the suite completes running - * 'onComplete': onComplete - * }); - */ - function Suite(name, options) { - var suite = this; - - // Allow instance creation without the `new` operator. - if (!(suite instanceof Suite)) { - return new Suite(name, options); - } - // Juggle arguments. - if (_.isPlainObject(name)) { - // 1 argument (options). - options = name; - } else { - // 2 arguments (name [, options]). - suite.name = name; - } - setOptions(suite, options); - } - - /*------------------------------------------------------------------------*/ - - /** - * A specialized version of `_.cloneDeep` which only clones arrays and plain - * objects assigning all other values by reference. - * - * @private - * @param {*} value The value to clone. - * @returns {*} The cloned value. - */ - var cloneDeep = _.partial(_.cloneDeepWith, _, function(value) { - // Only clone primitives, arrays, and plain objects. - return (_.isObject(value) && !_.isArray(value) && !_.isPlainObject(value)) - ? value - : undefined; - }); - - /** - * Creates a function from the given arguments string and body. - * - * @private - * @param {string} args The comma separated function arguments. - * @param {string} body The function body. - * @returns {Function} The new function. - */ - function createFunction() { - // Lazy define. - createFunction = function(args, body) { - var result, - anchor = freeDefine ? freeDefine.amd : Benchmark, - prop = uid + 'createFunction'; - - runScript((freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '=function(' + args + '){' + body + '}'); - result = anchor[prop]; - delete anchor[prop]; - return result; - }; - // Fix JaegerMonkey bug. - // For more information see http://bugzil.la/639720. - createFunction = support.browser && (createFunction('', 'return"' + uid + '"') || _.noop)() == uid ? createFunction : Function; - return createFunction.apply(null, arguments); - } - - /** - * Delay the execution of a function based on the benchmark's `delay` property. - * - * @private - * @param {Object} bench The benchmark instance. - * @param {Object} fn The function to execute. - */ - function delay(bench, fn) { - bench._timerId = _.delay(fn, bench.delay * 1e3); - } - - /** - * Destroys the given element. - * - * @private - * @param {Element} element The element to destroy. - */ - function destroyElement(element) { - trash.appendChild(element); - trash.innerHTML = ''; - } - - /** - * Gets the name of the first argument from a function's source. - * - * @private - * @param {Function} fn The function. - * @returns {string} The argument name. - */ - function getFirstArgument(fn) { - return (!_.has(fn, 'toString') && - (/^[\s(]*function[^(]*\(([^\s,)]+)/.exec(fn) || 0)[1]) || ''; - } - - /** - * Computes the arithmetic mean of a sample. - * - * @private - * @param {Array} sample The sample. - * @returns {number} The mean. - */ - function getMean(sample) { - return (_.reduce(sample, function(sum, x) { - return sum + x; - }) / sample.length) || 0; - } - - /** - * Gets the source code of a function. - * - * @private - * @param {Function} fn The function. - * @returns {string} The function's source code. - */ - function getSource(fn) { - var result = ''; - if (isStringable(fn)) { - result = String(fn); - } else if (support.decompilation) { - // Escape the `{` for Firefox 1. - result = _.result(/^[^{]+\{([\s\S]*)\}\s*$/.exec(fn), 1); - } - // Trim string. - result = (result || '').replace(/^\s+|\s+$/g, ''); - - // Detect strings containing only the "use strict" directive. - return /^(?:\/\*+[\w\W]*?\*\/|\/\/.*?[\n\r\u2028\u2029]|\s)*(["'])use strict\1;?$/.test(result) - ? '' - : result; - } - - /** - * Checks if an object is of the specified class. - * - * @private - * @param {*} value The value to check. - * @param {string} name The name of the class. - * @returns {boolean} Returns `true` if the value is of the specified class, else `false`. - */ - function isClassOf(value, name) { - return value != null && toString.call(value) == '[object ' + name + ']'; - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - if (object == null) { - return false; - } - var type = typeof object[property]; - return !rePrimitive.test(type) && (type != 'object' || !!object[property]); - } - - /** - * Checks if a value can be safely coerced to a string. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if the value can be coerced, else `false`. - */ - function isStringable(value) { - return _.isString(value) || (_.has(value, 'toString') && _.isFunction(value.toString)); - } - - /** - * A wrapper around `require` to suppress `module missing` errors. - * - * @private - * @param {string} id The module id. - * @returns {*} The exported module or `null`. - */ - function require(id) { - try { - var result = freeExports && freeRequire(id); - } catch(e) {} - return result || null; - } - - /** - * Runs a snippet of JavaScript via script injection. - * - * @private - * @param {string} code The code to run. - */ - function runScript(code) { - var anchor = freeDefine ? define.amd : Benchmark, - script = doc.createElement('script'), - sibling = doc.getElementsByTagName('script')[0], - parent = sibling.parentNode, - prop = uid + 'runScript', - prefix = '(' + (freeDefine ? 'define.amd.' : 'Benchmark.') + prop + '||function(){})();'; - - // Firefox 2.0.0.2 cannot use script injection as intended because it executes - // asynchronously, but that's OK because script injection is only used to avoid - // the previously commented JaegerMonkey bug. - try { - // Remove the inserted script *before* running the code to avoid differences - // in the expected script element count/order of the document. - script.appendChild(doc.createTextNode(prefix + code)); - anchor[prop] = function() { destroyElement(script); }; - } catch(e) { - parent = parent.cloneNode(false); - sibling = null; - script.text = code; - } - parent.insertBefore(script, sibling); - delete anchor[prop]; - } - - /** - * A helper function for setting options/event handlers. - * - * @private - * @param {Object} object The benchmark or suite instance. - * @param {Object} [options={}] Options object. - */ - function setOptions(object, options) { - options = object.options = _.assign({}, cloneDeep(object.constructor.options), cloneDeep(options)); - - _.forOwn(options, function(value, key) { - if (value != null) { - // Add event listeners. - if (/^on[A-Z]/.test(key)) { - _.each(key.split(' '), function(key) { - object.on(key.slice(2).toLowerCase(), value); - }); - } else if (!_.has(object, key)) { - object[key] = cloneDeep(value); - } - } - }); - } - - /*------------------------------------------------------------------------*/ - - /** - * Handles cycling/completing the deferred benchmark. - * - * @memberOf Benchmark.Deferred - */ - function resolve() { - var deferred = this, - clone = deferred.benchmark, - bench = clone._original; - - if (bench.aborted) { - // cycle() -> clone cycle/complete event -> compute()'s invoked bench.run() cycle/complete. - deferred.teardown(); - clone.running = false; - cycle(deferred); - } - else if (++deferred.cycles < clone.count) { - clone.compiled.call(deferred, context, timer); - } - else { - timer.stop(deferred); - deferred.teardown(); - delay(clone, function() { cycle(deferred); }); - } - } - - /*------------------------------------------------------------------------*/ - - /** - * A generic `Array#filter` like method. - * - * @static - * @memberOf Benchmark - * @param {Array} array The array to iterate over. - * @param {Function|string} callback The function/alias called per iteration. - * @returns {Array} A new array of values that passed callback filter. - * @example - * - * // get odd numbers - * Benchmark.filter([1, 2, 3, 4, 5], function(n) { - * return n % 2; - * }); // -> [1, 3, 5]; - * - * // get fastest benchmarks - * Benchmark.filter(benches, 'fastest'); - * - * // get slowest benchmarks - * Benchmark.filter(benches, 'slowest'); - * - * // get benchmarks that completed without erroring - * Benchmark.filter(benches, 'successful'); - */ - function filter(array, callback) { - if (callback === 'successful') { - // Callback to exclude those that are errored, unrun, or have hz of Infinity. - callback = function(bench) { - return bench.cycles && _.isFinite(bench.hz) && !bench.error; - }; - } - else if (callback === 'fastest' || callback === 'slowest') { - // Get successful, sort by period + margin of error, and filter fastest/slowest. - var result = filter(array, 'successful').sort(function(a, b) { - a = a.stats; b = b.stats; - return (a.mean + a.moe > b.mean + b.moe ? 1 : -1) * (callback === 'fastest' ? 1 : -1); - }); - - return _.filter(result, function(bench) { - return result[0].compare(bench) == 0; - }); - } - return _.filter(array, callback); - } - - /** - * Converts a number to a more readable comma-separated string representation. - * - * @static - * @memberOf Benchmark - * @param {number} number The number to convert. - * @returns {string} The more readable string representation. - */ - function formatNumber(number) { - number = String(number).split('.'); - return number[0].replace(/(?=(?:\d{3})+$)(?!\b)/g, ',') + - (number[1] ? '.' + number[1] : ''); - } - - /** - * Invokes a method on all items in an array. - * - * @static - * @memberOf Benchmark - * @param {Array} benches Array of benchmarks to iterate over. - * @param {Object|string} name The name of the method to invoke OR options object. - * @param {...*} [args] Arguments to invoke the method with. - * @returns {Array} A new array of values returned from each method invoked. - * @example - * - * // invoke `reset` on all benchmarks - * Benchmark.invoke(benches, 'reset'); - * - * // invoke `emit` with arguments - * Benchmark.invoke(benches, 'emit', 'complete', listener); - * - * // invoke `run(true)`, treat benchmarks as a queue, and register invoke callbacks - * Benchmark.invoke(benches, { - * - * // invoke the `run` method - * 'name': 'run', - * - * // pass a single argument - * 'args': true, - * - * // treat as queue, removing benchmarks from front of `benches` until empty - * 'queued': true, - * - * // called before any benchmarks have been invoked. - * 'onStart': onStart, - * - * // called between invoking benchmarks - * 'onCycle': onCycle, - * - * // called after all benchmarks have been invoked. - * 'onComplete': onComplete - * }); - */ - function invoke(benches, name) { - var args, - bench, - queued, - index = -1, - eventProps = { 'currentTarget': benches }, - options = { 'onStart': _.noop, 'onCycle': _.noop, 'onComplete': _.noop }, - result = _.toArray(benches); - - /** - * Invokes the method of the current object and if synchronous, fetches the next. - */ - function execute() { - var listeners, - async = isAsync(bench); - - if (async) { - // Use `getNext` as the first listener. - bench.on('complete', getNext); - listeners = bench.events.complete; - listeners.splice(0, 0, listeners.pop()); - } - // Execute method. - result[index] = _.isFunction(bench && bench[name]) ? bench[name].apply(bench, args) : undefined; - // If synchronous return `true` until finished. - return !async && getNext(); - } - - /** - * Fetches the next bench or executes `onComplete` callback. - */ - function getNext(event) { - var cycleEvent, - last = bench, - async = isAsync(last); - - if (async) { - last.off('complete', getNext); - last.emit('complete'); - } - // Emit "cycle" event. - eventProps.type = 'cycle'; - eventProps.target = last; - cycleEvent = Event(eventProps); - options.onCycle.call(benches, cycleEvent); - - // Choose next benchmark if not exiting early. - if (!cycleEvent.aborted && raiseIndex() !== false) { - bench = queued ? benches[0] : result[index]; - if (isAsync(bench)) { - delay(bench, execute); - } - else if (async) { - // Resume execution if previously asynchronous but now synchronous. - while (execute()) {} - } - else { - // Continue synchronous execution. - return true; - } - } else { - // Emit "complete" event. - eventProps.type = 'complete'; - options.onComplete.call(benches, Event(eventProps)); - } - // When used as a listener `event.aborted = true` will cancel the rest of - // the "complete" listeners because they were already called above and when - // used as part of `getNext` the `return false` will exit the execution while-loop. - if (event) { - event.aborted = true; - } else { - return false; - } - } - - /** - * Checks if invoking `Benchmark#run` with asynchronous cycles. - */ - function isAsync(object) { - // Avoid using `instanceof` here because of IE memory leak issues with host objects. - var async = args[0] && args[0].async; - return name == 'run' && (object instanceof Benchmark) && - ((async == null ? object.options.async : async) && support.timeout || object.defer); - } - - /** - * Raises `index` to the next defined index or returns `false`. - */ - function raiseIndex() { - index++; - - // If queued remove the previous bench. - if (queued && index > 0) { - shift.call(benches); - } - // If we reached the last index then return `false`. - return (queued ? benches.length : index < result.length) - ? index - : (index = false); - } - // Juggle arguments. - if (_.isString(name)) { - // 2 arguments (array, name). - args = slice.call(arguments, 2); - } else { - // 2 arguments (array, options). - options = _.assign(options, name); - name = options.name; - args = _.isArray(args = 'args' in options ? options.args : []) ? args : [args]; - queued = options.queued; - } - // Start iterating over the array. - if (raiseIndex() !== false) { - // Emit "start" event. - bench = result[index]; - eventProps.type = 'start'; - eventProps.target = bench; - options.onStart.call(benches, Event(eventProps)); - - // End early if the suite was aborted in an "onStart" listener. - if (name == 'run' && (benches instanceof Suite) && benches.aborted) { - // Emit "cycle" event. - eventProps.type = 'cycle'; - options.onCycle.call(benches, Event(eventProps)); - // Emit "complete" event. - eventProps.type = 'complete'; - options.onComplete.call(benches, Event(eventProps)); - } - // Start method execution. - else { - if (isAsync(bench)) { - delay(bench, execute); - } else { - while (execute()) {} - } - } - } - return result; - } - - /** - * Creates a string of joined array values or object key-value pairs. - * - * @static - * @memberOf Benchmark - * @param {Array|Object} object The object to operate on. - * @param {string} [separator1=','] The separator used between key-value pairs. - * @param {string} [separator2=': '] The separator used between keys and values. - * @returns {string} The joined result. - */ - function join(object, separator1, separator2) { - var result = [], - length = (object = Object(object)).length, - arrayLike = length === length >>> 0; - - separator2 || (separator2 = ': '); - _.each(object, function(value, key) { - result.push(arrayLike ? value : key + separator2 + value); - }); - return result.join(separator1 || ','); - } - - /*------------------------------------------------------------------------*/ - - /** - * Aborts all benchmarks in the suite. - * - * @name abort - * @memberOf Benchmark.Suite - * @returns {Object} The suite instance. - */ - function abortSuite() { - var event, - suite = this, - resetting = calledBy.resetSuite; - - if (suite.running) { - event = Event('abort'); - suite.emit(event); - if (!event.cancelled || resetting) { - // Avoid infinite recursion. - calledBy.abortSuite = true; - suite.reset(); - delete calledBy.abortSuite; - - if (!resetting) { - suite.aborted = true; - invoke(suite, 'abort'); - } - } - } - return suite; - } - - /** - * Adds a test to the benchmark suite. - * - * @memberOf Benchmark.Suite - * @param {string} name A name to identify the benchmark. - * @param {Function|string} fn The test to benchmark. - * @param {Object} [options={}] Options object. - * @returns {Object} The suite instance. - * @example - * - * // basic usage - * suite.add(fn); - * - * // or using a name first - * suite.add('foo', fn); - * - * // or with options - * suite.add('foo', fn, { - * 'onCycle': onCycle, - * 'onComplete': onComplete - * }); - * - * // or name and options - * suite.add('foo', { - * 'fn': fn, - * 'onCycle': onCycle, - * 'onComplete': onComplete - * }); - * - * // or options only - * suite.add({ - * 'name': 'foo', - * 'fn': fn, - * 'onCycle': onCycle, - * 'onComplete': onComplete - * }); - */ - function add(name, fn, options) { - var suite = this, - bench = new Benchmark(name, fn, options), - event = Event({ 'type': 'add', 'target': bench }); - - if (suite.emit(event), !event.cancelled) { - suite.push(bench); - } - return suite; - } - - /** - * Creates a new suite with cloned benchmarks. - * - * @name clone - * @memberOf Benchmark.Suite - * @param {Object} options Options object to overwrite cloned options. - * @returns {Object} The new suite instance. - */ - function cloneSuite(options) { - var suite = this, - result = new suite.constructor(_.assign({}, suite.options, options)); - - // Copy own properties. - _.forOwn(suite, function(value, key) { - if (!_.has(result, key)) { - result[key] = value && _.isFunction(value.clone) - ? value.clone() - : cloneDeep(value); - } - }); - return result; - } - - /** - * An `Array#filter` like method. - * - * @name filter - * @memberOf Benchmark.Suite - * @param {Function|string} callback The function/alias called per iteration. - * @returns {Object} A new suite of benchmarks that passed callback filter. - */ - function filterSuite(callback) { - var suite = this, - result = new suite.constructor(suite.options); - - result.push.apply(result, filter(suite, callback)); - return result; - } - - /** - * Resets all benchmarks in the suite. - * - * @name reset - * @memberOf Benchmark.Suite - * @returns {Object} The suite instance. - */ - function resetSuite() { - var event, - suite = this, - aborting = calledBy.abortSuite; - - if (suite.running && !aborting) { - // No worries, `resetSuite()` is called within `abortSuite()`. - calledBy.resetSuite = true; - suite.abort(); - delete calledBy.resetSuite; - } - // Reset if the state has changed. - else if ((suite.aborted || suite.running) && - (suite.emit(event = Event('reset')), !event.cancelled)) { - suite.aborted = suite.running = false; - if (!aborting) { - invoke(suite, 'reset'); - } - } - return suite; - } - - /** - * Runs the suite. - * - * @name run - * @memberOf Benchmark.Suite - * @param {Object} [options={}] Options object. - * @returns {Object} The suite instance. - * @example - * - * // basic usage - * suite.run(); - * - * // or with options - * suite.run({ 'async': true, 'queued': true }); - */ - function runSuite(options) { - var suite = this; - - suite.reset(); - suite.running = true; - options || (options = {}); - - invoke(suite, { - 'name': 'run', - 'args': options, - 'queued': options.queued, - 'onStart': function(event) { - suite.emit(event); - }, - 'onCycle': function(event) { - var bench = event.target; - if (bench.error) { - suite.emit({ 'type': 'error', 'target': bench }); - } - suite.emit(event); - event.aborted = suite.aborted; - }, - 'onComplete': function(event) { - suite.running = false; - suite.emit(event); - } - }); - return suite; - } - - /*------------------------------------------------------------------------*/ - - /** - * Executes all registered listeners of the specified event type. - * - * @memberOf Benchmark, Benchmark.Suite - * @param {Object|string} type The event type or object. - * @param {...*} [args] Arguments to invoke the listener with. - * @returns {*} Returns the return value of the last listener executed. - */ - function emit(type) { - var listeners, - object = this, - event = Event(type), - events = object.events, - args = (arguments[0] = event, arguments); - - event.currentTarget || (event.currentTarget = object); - event.target || (event.target = object); - delete event.result; - - if (events && (listeners = _.has(events, event.type) && events[event.type])) { - _.each(listeners.slice(), function(listener) { - if ((event.result = listener.apply(object, args)) === false) { - event.cancelled = true; - } - return !event.aborted; - }); - } - return event.result; - } - - /** - * Returns an array of event listeners for a given type that can be manipulated - * to add or remove listeners. - * - * @memberOf Benchmark, Benchmark.Suite - * @param {string} type The event type. - * @returns {Array} The listeners array. - */ - function listeners(type) { - var object = this, - events = object.events || (object.events = {}); - - return _.has(events, type) ? events[type] : (events[type] = []); - } - - /** - * Unregisters a listener for the specified event type(s), - * or unregisters all listeners for the specified event type(s), - * or unregisters all listeners for all event types. - * - * @memberOf Benchmark, Benchmark.Suite - * @param {string} [type] The event type. - * @param {Function} [listener] The function to unregister. - * @returns {Object} The current instance. - * @example - * - * // unregister a listener for an event type - * bench.off('cycle', listener); - * - * // unregister a listener for multiple event types - * bench.off('start cycle', listener); - * - * // unregister all listeners for an event type - * bench.off('cycle'); - * - * // unregister all listeners for multiple event types - * bench.off('start cycle complete'); - * - * // unregister all listeners for all event types - * bench.off(); - */ - function off(type, listener) { - var object = this, - events = object.events; - - if (!events) { - return object; - } - _.each(type ? type.split(' ') : events, function(listeners, type) { - var index; - if (typeof listeners == 'string') { - type = listeners; - listeners = _.has(events, type) && events[type]; - } - if (listeners) { - if (listener) { - index = _.indexOf(listeners, listener); - if (index > -1) { - listeners.splice(index, 1); - } - } else { - listeners.length = 0; - } - } - }); - return object; - } - - /** - * Registers a listener for the specified event type(s). - * - * @memberOf Benchmark, Benchmark.Suite - * @param {string} type The event type. - * @param {Function} listener The function to register. - * @returns {Object} The current instance. - * @example - * - * // register a listener for an event type - * bench.on('cycle', listener); - * - * // register a listener for multiple event types - * bench.on('start cycle', listener); - */ - function on(type, listener) { - var object = this, - events = object.events || (object.events = {}); - - _.each(type.split(' '), function(type) { - (_.has(events, type) - ? events[type] - : (events[type] = []) - ).push(listener); - }); - return object; - } - - /*------------------------------------------------------------------------*/ - - /** - * Aborts the benchmark without recording times. - * - * @memberOf Benchmark - * @returns {Object} The benchmark instance. - */ - function abort() { - var event, - bench = this, - resetting = calledBy.reset; - - if (bench.running) { - event = Event('abort'); - bench.emit(event); - if (!event.cancelled || resetting) { - // Avoid infinite recursion. - calledBy.abort = true; - bench.reset(); - delete calledBy.abort; - - if (support.timeout) { - clearTimeout(bench._timerId); - delete bench._timerId; - } - if (!resetting) { - bench.aborted = true; - bench.running = false; - } - } - } - return bench; - } - - /** - * Creates a new benchmark using the same test and options. - * - * @memberOf Benchmark - * @param {Object} options Options object to overwrite cloned options. - * @returns {Object} The new benchmark instance. - * @example - * - * var bizarro = bench.clone({ - * 'name': 'doppelganger' - * }); - */ - function clone(options) { - var bench = this, - result = new bench.constructor(_.assign({}, bench, options)); - - // Correct the `options` object. - result.options = _.assign({}, cloneDeep(bench.options), cloneDeep(options)); - - // Copy own custom properties. - _.forOwn(bench, function(value, key) { - if (!_.has(result, key)) { - result[key] = cloneDeep(value); - } - }); - - return result; - } - - /** - * Determines if a benchmark is faster than another. - * - * @memberOf Benchmark - * @param {Object} other The benchmark to compare. - * @returns {number} Returns `-1` if slower, `1` if faster, and `0` if indeterminate. - */ - function compare(other) { - var bench = this; - - // Exit early if comparing the same benchmark. - if (bench == other) { - return 0; - } - var critical, - zStat, - sample1 = bench.stats.sample, - sample2 = other.stats.sample, - size1 = sample1.length, - size2 = sample2.length, - maxSize = max(size1, size2), - minSize = min(size1, size2), - u1 = getU(sample1, sample2), - u2 = getU(sample2, sample1), - u = min(u1, u2); - - function getScore(xA, sampleB) { - return _.reduce(sampleB, function(total, xB) { - return total + (xB > xA ? 0 : xB < xA ? 1 : 0.5); - }, 0); - } - - function getU(sampleA, sampleB) { - return _.reduce(sampleA, function(total, xA) { - return total + getScore(xA, sampleB); - }, 0); - } - - function getZ(u) { - return (u - ((size1 * size2) / 2)) / sqrt((size1 * size2 * (size1 + size2 + 1)) / 12); - } - // Reject the null hypothesis the two samples come from the - // same population (i.e. have the same median) if... - if (size1 + size2 > 30) { - // ...the z-stat is greater than 1.96 or less than -1.96 - // http://www.statisticslectures.com/topics/mannwhitneyu/ - zStat = getZ(u); - return abs(zStat) > 1.96 ? (u == u1 ? 1 : -1) : 0; - } - // ...the U value is less than or equal the critical U value. - critical = maxSize < 5 || minSize < 3 ? 0 : uTable[maxSize][minSize - 3]; - return u <= critical ? (u == u1 ? 1 : -1) : 0; - } - - /** - * Reset properties and abort if running. - * - * @memberOf Benchmark - * @returns {Object} The benchmark instance. - */ - function reset() { - var bench = this; - if (bench.running && !calledBy.abort) { - // No worries, `reset()` is called within `abort()`. - calledBy.reset = true; - bench.abort(); - delete calledBy.reset; - return bench; - } - var event, - index = 0, - changes = [], - queue = []; - - // A non-recursive solution to check if properties have changed. - // For more information see http://www.jslab.dk/articles/non.recursive.preorder.traversal.part4. - var data = { - 'destination': bench, - 'source': _.assign({}, cloneDeep(bench.constructor.prototype), cloneDeep(bench.options)) - }; - - do { - _.forOwn(data.source, function(value, key) { - var changed, - destination = data.destination, - currValue = destination[key]; - - // Skip pseudo private properties like `_timerId` which could be a - // Java object in environments like RingoJS. - if (key.charAt(0) == '_') { - return; - } - if (value && typeof value == 'object') { - if (_.isArray(value)) { - // Check if an array value has changed to a non-array value. - if (!_.isArray(currValue)) { - changed = currValue = []; - } - // Check if an array has changed its length. - if (currValue.length != value.length) { - changed = currValue = currValue.slice(0, value.length); - currValue.length = value.length; - } - } - // Check if an object has changed to a non-object value. - else if (!currValue || typeof currValue != 'object') { - changed = currValue = {}; - } - // Register a changed object. - if (changed) { - changes.push({ 'destination': destination, 'key': key, 'value': currValue }); - } - queue.push({ 'destination': currValue, 'source': value }); - } - // Register a changed primitive. - else if (value !== currValue && !(value == null || _.isFunction(value))) { - changes.push({ 'destination': destination, 'key': key, 'value': value }); - } - }); - } - while ((data = queue[index++])); - - // If changed emit the `reset` event and if it isn't cancelled reset the benchmark. - if (changes.length && (bench.emit(event = Event('reset')), !event.cancelled)) { - _.each(changes, function(data) { - data.destination[data.key] = data.value; - }); - } - return bench; - } - - /** - * Displays relevant benchmark information when coerced to a string. - * - * @name toString - * @memberOf Benchmark - * @returns {string} A string representation of the benchmark instance. - */ - function toStringBench() { - var bench = this, - error = bench.error, - hz = bench.hz, - id = bench.id, - stats = bench.stats, - size = stats.sample.length, - pm = '\xb1', - result = bench.name || (_.isNaN(id) ? id : '<Test #' + id + '>'); - - if (error) { - result += ': ' + join(error); - } else { - result += ' x ' + formatNumber(hz.toFixed(hz < 100 ? 2 : 0)) + ' ops/sec ' + pm + - stats.rme.toFixed(2) + '% (' + size + ' run' + (size == 1 ? '' : 's') + ' sampled)'; - } - return result; - } - - /*------------------------------------------------------------------------*/ - - /** - * Clocks the time taken to execute a test per cycle (secs). - * - * @private - * @param {Object} bench The benchmark instance. - * @returns {number} The time taken. - */ - function clock() { - var options = Benchmark.options, - templateData = {}, - timers = [{ 'ns': timer.ns, 'res': max(0.0015, getRes('ms')), 'unit': 'ms' }]; - - // Lazy define for hi-res timers. - clock = function(clone) { - var deferred; - - if (clone instanceof Deferred) { - deferred = clone; - clone = deferred.benchmark; - } - var bench = clone._original, - stringable = isStringable(bench.fn), - count = bench.count = clone.count, - decompilable = stringable || (support.decompilation && (clone.setup !== _.noop || clone.teardown !== _.noop)), - id = bench.id, - name = bench.name || (typeof id == 'number' ? '<Test #' + id + '>' : id), - result = 0; - - // Init `minTime` if needed. - clone.minTime = bench.minTime || (bench.minTime = bench.options.minTime = options.minTime); - - // Compile in setup/teardown functions and the test loop. - // Create a new compiled test, instead of using the cached `bench.compiled`, - // to avoid potential engine optimizations enabled over the life of the test. - var funcBody = deferred - ? 'var d#=this,${fnArg}=d#,m#=d#.benchmark._original,f#=m#.fn,su#=m#.setup,td#=m#.teardown;' + - // When `deferred.cycles` is `0` then... - 'if(!d#.cycles){' + - // set `deferred.fn`, - 'd#.fn=function(){var ${fnArg}=d#;if(typeof f#=="function"){try{${fn}\n}catch(e#){f#(d#)}}else{${fn}\n}};' + - // set `deferred.teardown`, - 'd#.teardown=function(){d#.cycles=0;if(typeof td#=="function"){try{${teardown}\n}catch(e#){td#()}}else{${teardown}\n}};' + - // execute the benchmark's `setup`, - 'if(typeof su#=="function"){try{${setup}\n}catch(e#){su#()}}else{${setup}\n};' + - // start timer, - 't#.start(d#);' + - // and then execute `deferred.fn` and return a dummy object. - '}d#.fn();return{uid:"${uid}"}' - - : 'var r#,s#,m#=this,f#=m#.fn,i#=m#.count,n#=t#.ns;${setup}\n${begin};' + - 'while(i#--){${fn}\n}${end};${teardown}\nreturn{elapsed:r#,uid:"${uid}"}'; - - var compiled = bench.compiled = clone.compiled = createCompiled(bench, decompilable, deferred, funcBody), - isEmpty = !(templateData.fn || stringable); - - try { - if (isEmpty) { - // Firefox may remove dead code from `Function#toString` results. - // For more information see http://bugzil.la/536085. - throw new Error('The test "' + name + '" is empty. This may be the result of dead code removal.'); - } - else if (!deferred) { - // Pretest to determine if compiled code exits early, usually by a - // rogue `return` statement, by checking for a return object with the uid. - bench.count = 1; - compiled = decompilable && (compiled.call(bench, context, timer) || {}).uid == templateData.uid && compiled; - bench.count = count; - } - } catch(e) { - compiled = null; - clone.error = e || new Error(String(e)); - bench.count = count; - } - // Fallback when a test exits early or errors during pretest. - if (!compiled && !deferred && !isEmpty) { - funcBody = ( - stringable || (decompilable && !clone.error) - ? 'function f#(){${fn}\n}var r#,s#,m#=this,i#=m#.count' - : 'var r#,s#,m#=this,f#=m#.fn,i#=m#.count' - ) + - ',n#=t#.ns;${setup}\n${begin};m#.f#=f#;while(i#--){m#.f#()}${end};' + - 'delete m#.f#;${teardown}\nreturn{elapsed:r#}'; - - compiled = createCompiled(bench, decompilable, deferred, funcBody); - - try { - // Pretest one more time to check for errors. - bench.count = 1; - compiled.call(bench, context, timer); - bench.count = count; - delete clone.error; - } - catch(e) { - bench.count = count; - if (!clone.error) { - clone.error = e || new Error(String(e)); - } - } - } - // If no errors run the full test loop. - if (!clone.error) { - compiled = bench.compiled = clone.compiled = createCompiled(bench, decompilable, deferred, funcBody); - result = compiled.call(deferred || bench, context, timer).elapsed; - } - return result; - }; - - /*----------------------------------------------------------------------*/ - - /** - * Creates a compiled function from the given function `body`. - */ - function createCompiled(bench, decompilable, deferred, body) { - var fn = bench.fn, - fnArg = deferred ? getFirstArgument(fn) || 'deferred' : ''; - - templateData.uid = uid + uidCounter++; - - _.assign(templateData, { - 'setup': decompilable ? getSource(bench.setup) : interpolate('m#.setup()'), - 'fn': decompilable ? getSource(fn) : interpolate('m#.fn(' + fnArg + ')'), - 'fnArg': fnArg, - 'teardown': decompilable ? getSource(bench.teardown) : interpolate('m#.teardown()') - }); - - // Use API of chosen timer. - if (timer.unit == 'ns') { - _.assign(templateData, { - 'begin': interpolate('s#=n#()'), - 'end': interpolate('r#=n#(s#);r#=r#[0]+(r#[1]/1e9)') - }); - } - else if (timer.unit == 'us') { - if (timer.ns.stop) { - _.assign(templateData, { - 'begin': interpolate('s#=n#.start()'), - 'end': interpolate('r#=n#.microseconds()/1e6') - }); - } else { - _.assign(templateData, { - 'begin': interpolate('s#=n#()'), - 'end': interpolate('r#=(n#()-s#)/1e6') - }); - } - } - else if (timer.ns.now) { - _.assign(templateData, { - 'begin': interpolate('s#=n#.now()'), - 'end': interpolate('r#=(n#.now()-s#)/1e3') - }); - } - else { - _.assign(templateData, { - 'begin': interpolate('s#=new n#().getTime()'), - 'end': interpolate('r#=(new n#().getTime()-s#)/1e3') - }); - } - // Define `timer` methods. - timer.start = createFunction( - interpolate('o#'), - interpolate('var n#=this.ns,${begin};o#.elapsed=0;o#.timeStamp=s#') - ); - - timer.stop = createFunction( - interpolate('o#'), - interpolate('var n#=this.ns,s#=o#.timeStamp,${end};o#.elapsed=r#') - ); - - // Create compiled test. - return createFunction( - interpolate('window,t#'), - 'var global = window, clearTimeout = global.clearTimeout, setTimeout = global.setTimeout;\n' + - interpolate(body) - ); - } - - /** - * Gets the current timer's minimum resolution (secs). - */ - function getRes(unit) { - var measured, - begin, - count = 30, - divisor = 1e3, - ns = timer.ns, - sample = []; - - // Get average smallest measurable time. - while (count--) { - if (unit == 'us') { - divisor = 1e6; - if (ns.stop) { - ns.start(); - while (!(measured = ns.microseconds())) {} - } else { - begin = ns(); - while (!(measured = ns() - begin)) {} - } - } - else if (unit == 'ns') { - divisor = 1e9; - begin = (begin = ns())[0] + (begin[1] / divisor); - while (!(measured = ((measured = ns())[0] + (measured[1] / divisor)) - begin)) {} - divisor = 1; - } - else if (ns.now) { - begin = ns.now(); - while (!(measured = ns.now() - begin)) {} - } - else { - begin = new ns().getTime(); - while (!(measured = new ns().getTime() - begin)) {} - } - // Check for broken timers. - if (measured > 0) { - sample.push(measured); - } else { - sample.push(Infinity); - break; - } - } - // Convert to seconds. - return getMean(sample) / divisor; - } - - /** - * Interpolates a given template string. - */ - function interpolate(string) { - // Replaces all occurrences of `#` with a unique number and template tokens with content. - return _.template(string.replace(/\#/g, /\d+/.exec(templateData.uid)))(templateData); - } - - /*----------------------------------------------------------------------*/ - - // Detect Chrome's microsecond timer: - // enable benchmarking via the --enable-benchmarking command - // line switch in at least Chrome 7 to use chrome.Interval - try { - if ((timer.ns = new (context.chrome || context.chromium).Interval)) { - timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); - } - } catch(e) {} - - // Detect Node.js's nanosecond resolution timer available in Node.js >= 0.8. - if (processObject && typeof (timer.ns = processObject.hrtime) == 'function') { - timers.push({ 'ns': timer.ns, 'res': getRes('ns'), 'unit': 'ns' }); - } - // Detect Wade Simmons' Node.js `microtime` module. - if (microtimeObject && typeof (timer.ns = microtimeObject.now) == 'function') { - timers.push({ 'ns': timer.ns, 'res': getRes('us'), 'unit': 'us' }); - } - // Pick timer with highest resolution. - timer = _.minBy(timers, 'res'); - - // Error if there are no working timers. - if (timer.res == Infinity) { - throw new Error('Benchmark.js was unable to find a working timer.'); - } - // Resolve time span required to achieve a percent uncertainty of at most 1%. - // For more information see http://spiff.rit.edu/classes/phys273/uncert/uncert.html. - options.minTime || (options.minTime = max(timer.res / 2 / 0.01, 0.05)); - return clock.apply(null, arguments); - } - - /*------------------------------------------------------------------------*/ - - /** - * Computes stats on benchmark results. - * - * @private - * @param {Object} bench The benchmark instance. - * @param {Object} options The options object. - */ - function compute(bench, options) { - options || (options = {}); - - var async = options.async, - elapsed = 0, - initCount = bench.initCount, - minSamples = bench.minSamples, - queue = [], - sample = bench.stats.sample; - - /** - * Adds a clone to the queue. - */ - function enqueue() { - queue.push(bench.clone({ - '_original': bench, - 'events': { - 'abort': [update], - 'cycle': [update], - 'error': [update], - 'start': [update] - } - })); - } - - /** - * Updates the clone/original benchmarks to keep their data in sync. - */ - function update(event) { - var clone = this, - type = event.type; - - if (bench.running) { - if (type == 'start') { - // Note: `clone.minTime` prop is inited in `clock()`. - clone.count = bench.initCount; - } - else { - if (type == 'error') { - bench.error = clone.error; - } - if (type == 'abort') { - bench.abort(); - bench.emit('cycle'); - } else { - event.currentTarget = event.target = bench; - bench.emit(event); - } - } - } else if (bench.aborted) { - // Clear abort listeners to avoid triggering bench's abort/cycle again. - clone.events.abort.length = 0; - clone.abort(); - } - } - - /** - * Determines if more clones should be queued or if cycling should stop. - */ - function evaluate(event) { - var critical, - df, - mean, - moe, - rme, - sd, - sem, - variance, - clone = event.target, - done = bench.aborted, - now = _.now(), - size = sample.push(clone.times.period), - maxedOut = size >= minSamples && (elapsed += now - clone.times.timeStamp) / 1e3 > bench.maxTime, - times = bench.times, - varOf = function(sum, x) { return sum + pow(x - mean, 2); }; - - // Exit early for aborted or unclockable tests. - if (done || clone.hz == Infinity) { - maxedOut = !(size = sample.length = queue.length = 0); - } - - if (!done) { - // Compute the sample mean (estimate of the population mean). - mean = getMean(sample); - // Compute the sample variance (estimate of the population variance). - variance = _.reduce(sample, varOf, 0) / (size - 1) || 0; - // Compute the sample standard deviation (estimate of the population standard deviation). - sd = sqrt(variance); - // Compute the standard error of the mean (a.k.a. the standard deviation of the sampling distribution of the sample mean). - sem = sd / sqrt(size); - // Compute the degrees of freedom. - df = size - 1; - // Compute the critical value. - critical = tTable[Math.round(df) || 1] || tTable.infinity; - // Compute the margin of error. - moe = sem * critical; - // Compute the relative margin of error. - rme = (moe / mean) * 100 || 0; - - _.assign(bench.stats, { - 'deviation': sd, - 'mean': mean, - 'moe': moe, - 'rme': rme, - 'sem': sem, - 'variance': variance - }); - - // Abort the cycle loop when the minimum sample size has been collected - // and the elapsed time exceeds the maximum time allowed per benchmark. - // We don't count cycle delays toward the max time because delays may be - // increased by browsers that clamp timeouts for inactive tabs. For more - // information see https://developer.mozilla.org/en/window.setTimeout#Inactive_tabs. - if (maxedOut) { - // Reset the `initCount` in case the benchmark is rerun. - bench.initCount = initCount; - bench.running = false; - done = true; - times.elapsed = (now - times.timeStamp) / 1e3; - } - if (bench.hz != Infinity) { - bench.hz = 1 / mean; - times.cycle = mean * bench.count; - times.period = mean; - } - } - // If time permits, increase sample size to reduce the margin of error. - if (queue.length < 2 && !maxedOut) { - enqueue(); - } - // Abort the `invoke` cycle when done. - event.aborted = done; - } - - // Init queue and begin. - enqueue(); - invoke(queue, { - 'name': 'run', - 'args': { 'async': async }, - 'queued': true, - 'onCycle': evaluate, - 'onComplete': function() { bench.emit('complete'); } - }); - } - - /*------------------------------------------------------------------------*/ - - /** - * Cycles a benchmark until a run `count` can be established. - * - * @private - * @param {Object} clone The cloned benchmark instance. - * @param {Object} options The options object. - */ - function cycle(clone, options) { - options || (options = {}); - - var deferred; - if (clone instanceof Deferred) { - deferred = clone; - clone = clone.benchmark; - } - var clocked, - cycles, - divisor, - event, - minTime, - period, - async = options.async, - bench = clone._original, - count = clone.count, - times = clone.times; - - // Continue, if not aborted between cycles. - if (clone.running) { - // `minTime` is set to `Benchmark.options.minTime` in `clock()`. - cycles = ++clone.cycles; - clocked = deferred ? deferred.elapsed : clock(clone); - minTime = clone.minTime; - - if (cycles > bench.cycles) { - bench.cycles = cycles; - } - if (clone.error) { - event = Event('error'); - event.message = clone.error; - clone.emit(event); - if (!event.cancelled) { - clone.abort(); - } - } - } - // Continue, if not errored. - if (clone.running) { - // Compute the time taken to complete last test cycle. - bench.times.cycle = times.cycle = clocked; - // Compute the seconds per operation. - period = bench.times.period = times.period = clocked / count; - // Compute the ops per second. - bench.hz = clone.hz = 1 / period; - // Avoid working our way up to this next time. - bench.initCount = clone.initCount = count; - // Do we need to do another cycle? - clone.running = clocked < minTime; - - if (clone.running) { - // Tests may clock at `0` when `initCount` is a small number, - // to avoid that we set its count to something a bit higher. - if (!clocked && (divisor = divisors[clone.cycles]) != null) { - count = floor(4e6 / divisor); - } - // Calculate how many more iterations it will take to achieve the `minTime`. - if (count <= clone.count) { - count += Math.ceil((minTime - clocked) / period); - } - clone.running = count != Infinity; - } - } - // Should we exit early? - event = Event('cycle'); - clone.emit(event); - if (event.aborted) { - clone.abort(); - } - // Figure out what to do next. - if (clone.running) { - // Start a new cycle. - clone.count = count; - if (deferred) { - clone.compiled.call(deferred, context, timer); - } else if (async) { - delay(clone, function() { cycle(clone, options); }); - } else { - cycle(clone); - } - } - else { - // Fix TraceMonkey bug associated with clock fallbacks. - // For more information see http://bugzil.la/509069. - if (support.browser) { - runScript(uid + '=1;delete ' + uid); - } - // We're done. - clone.emit('complete'); - } - } - - /*------------------------------------------------------------------------*/ - - /** - * Runs the benchmark. - * - * @memberOf Benchmark - * @param {Object} [options={}] Options object. - * @returns {Object} The benchmark instance. - * @example - * - * // basic usage - * bench.run(); - * - * // or with options - * bench.run({ 'async': true }); - */ - function run(options) { - var bench = this, - event = Event('start'); - - // Set `running` to `false` so `reset()` won't call `abort()`. - bench.running = false; - bench.reset(); - bench.running = true; - - bench.count = bench.initCount; - bench.times.timeStamp = _.now(); - bench.emit(event); - - if (!event.cancelled) { - options = { 'async': ((options = options && options.async) == null ? bench.async : options) && support.timeout }; - - // For clones created within `compute()`. - if (bench._original) { - if (bench.defer) { - Deferred(bench); - } else { - cycle(bench, options); - } - } - // For original benchmarks. - else { - compute(bench, options); - } - } - return bench; - } - - /*------------------------------------------------------------------------*/ - - // Firefox 1 erroneously defines variable and argument names of functions on - // the function itself as non-configurable properties with `undefined` values. - // The bugginess continues as the `Benchmark` constructor has an argument - // named `options` and Firefox 1 will not assign a value to `Benchmark.options`, - // making it non-writable in the process, unless it is the first property - // assigned by for-in loop of `_.assign()`. - _.assign(Benchmark, { - - /** - * The default options copied by benchmark instances. - * - * @static - * @memberOf Benchmark - * @type Object - */ - 'options': { - - /** - * A flag to indicate that benchmark cycles will execute asynchronously - * by default. - * - * @memberOf Benchmark.options - * @type boolean - */ - 'async': false, - - /** - * A flag to indicate that the benchmark clock is deferred. - * - * @memberOf Benchmark.options - * @type boolean - */ - 'defer': false, - - /** - * The delay between test cycles (secs). - * @memberOf Benchmark.options - * @type number - */ - 'delay': 0.005, - - /** - * Displayed by `Benchmark#toString` when a `name` is not available - * (auto-generated if absent). - * - * @memberOf Benchmark.options - * @type string - */ - 'id': undefined, - - /** - * The default number of times to execute a test on a benchmark's first cycle. - * - * @memberOf Benchmark.options - * @type number - */ - 'initCount': 1, - - /** - * The maximum time a benchmark is allowed to run before finishing (secs). - * - * Note: Cycle delays aren't counted toward the maximum time. - * - * @memberOf Benchmark.options - * @type number - */ - 'maxTime': 5, - - /** - * The minimum sample size required to perform statistical analysis. - * - * @memberOf Benchmark.options - * @type number - */ - 'minSamples': 5, - - /** - * The time needed to reduce the percent uncertainty of measurement to 1% (secs). - * - * @memberOf Benchmark.options - * @type number - */ - 'minTime': 0, - - /** - * The name of the benchmark. - * - * @memberOf Benchmark.options - * @type string - */ - 'name': undefined, - - /** - * An event listener called when the benchmark is aborted. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onAbort': undefined, - - /** - * An event listener called when the benchmark completes running. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onComplete': undefined, - - /** - * An event listener called after each run cycle. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onCycle': undefined, - - /** - * An event listener called when a test errors. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onError': undefined, - - /** - * An event listener called when the benchmark is reset. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onReset': undefined, - - /** - * An event listener called when the benchmark starts running. - * - * @memberOf Benchmark.options - * @type Function - */ - 'onStart': undefined - }, - - /** - * Platform object with properties describing things like browser name, - * version, and operating system. See [`platform.js`](https://mths.be/platform). - * - * @static - * @memberOf Benchmark - * @type Object - */ - 'platform': context.platform || require('platform') || ({ - 'description': context.navigator && context.navigator.userAgent || null, - 'layout': null, - 'product': null, - 'name': null, - 'manufacturer': null, - 'os': null, - 'prerelease': null, - 'version': null, - 'toString': function() { - return this.description || ''; - } - }), - - /** - * The semantic version number. - * - * @static - * @memberOf Benchmark - * @type string - */ - 'version': '2.1.1' - }); - - _.assign(Benchmark, { - 'filter': filter, - 'formatNumber': formatNumber, - 'invoke': invoke, - 'join': join, - 'runInContext': runInContext, - 'support': support - }); - - // Add lodash methods to Benchmark. - _.each(['each', 'forEach', 'forOwn', 'has', 'indexOf', 'map', 'reduce'], function(methodName) { - Benchmark[methodName] = _[methodName]; - }); - - /*------------------------------------------------------------------------*/ - - _.assign(Benchmark.prototype, { - - /** - * The number of times a test was executed. - * - * @memberOf Benchmark - * @type number - */ - 'count': 0, - - /** - * The number of cycles performed while benchmarking. - * - * @memberOf Benchmark - * @type number - */ - 'cycles': 0, - - /** - * The number of executions per second. - * - * @memberOf Benchmark - * @type number - */ - 'hz': 0, - - /** - * The compiled test function. - * - * @memberOf Benchmark - * @type {Function|string} - */ - 'compiled': undefined, - - /** - * The error object if the test failed. - * - * @memberOf Benchmark - * @type Object - */ - 'error': undefined, - - /** - * The test to benchmark. - * - * @memberOf Benchmark - * @type {Function|string} - */ - 'fn': undefined, - - /** - * A flag to indicate if the benchmark is aborted. - * - * @memberOf Benchmark - * @type boolean - */ - 'aborted': false, - - /** - * A flag to indicate if the benchmark is running. - * - * @memberOf Benchmark - * @type boolean - */ - 'running': false, - - /** - * Compiled into the test and executed immediately **before** the test loop. - * - * @memberOf Benchmark - * @type {Function|string} - * @example - * - * // basic usage - * var bench = Benchmark({ - * 'setup': function() { - * var c = this.count, - * element = document.getElementById('container'); - * while (c--) { - * element.appendChild(document.createElement('div')); - * } - * }, - * 'fn': function() { - * element.removeChild(element.lastChild); - * } - * }); - * - * // compiles to something like: - * var c = this.count, - * element = document.getElementById('container'); - * while (c--) { - * element.appendChild(document.createElement('div')); - * } - * var start = new Date; - * while (count--) { - * element.removeChild(element.lastChild); - * } - * var end = new Date - start; - * - * // or using strings - * var bench = Benchmark({ - * 'setup': '\ - * var a = 0;\n\ - * (function() {\n\ - * (function() {\n\ - * (function() {', - * 'fn': 'a += 1;', - * 'teardown': '\ - * }())\n\ - * }())\n\ - * }())' - * }); - * - * // compiles to something like: - * var a = 0; - * (function() { - * (function() { - * (function() { - * var start = new Date; - * while (count--) { - * a += 1; - * } - * var end = new Date - start; - * }()) - * }()) - * }()) - */ - 'setup': _.noop, - - /** - * Compiled into the test and executed immediately **after** the test loop. - * - * @memberOf Benchmark - * @type {Function|string} - */ - 'teardown': _.noop, - - /** - * An object of stats including mean, margin or error, and standard deviation. - * - * @memberOf Benchmark - * @type Object - */ - 'stats': { - - /** - * The margin of error. - * - * @memberOf Benchmark#stats - * @type number - */ - 'moe': 0, - - /** - * The relative margin of error (expressed as a percentage of the mean). - * - * @memberOf Benchmark#stats - * @type number - */ - 'rme': 0, - - /** - * The standard error of the mean. - * - * @memberOf Benchmark#stats - * @type number - */ - 'sem': 0, - - /** - * The sample standard deviation. - * - * @memberOf Benchmark#stats - * @type number - */ - 'deviation': 0, - - /** - * The sample arithmetic mean (secs). - * - * @memberOf Benchmark#stats - * @type number - */ - 'mean': 0, - - /** - * The array of sampled periods. - * - * @memberOf Benchmark#stats - * @type Array - */ - 'sample': [], - - /** - * The sample variance. - * - * @memberOf Benchmark#stats - * @type number - */ - 'variance': 0 - }, - - /** - * An object of timing data including cycle, elapsed, period, start, and stop. - * - * @memberOf Benchmark - * @type Object - */ - 'times': { - - /** - * The time taken to complete the last cycle (secs). - * - * @memberOf Benchmark#times - * @type number - */ - 'cycle': 0, - - /** - * The time taken to complete the benchmark (secs). - * - * @memberOf Benchmark#times - * @type number - */ - 'elapsed': 0, - - /** - * The time taken to execute the test once (secs). - * - * @memberOf Benchmark#times - * @type number - */ - 'period': 0, - - /** - * A timestamp of when the benchmark started (ms). - * - * @memberOf Benchmark#times - * @type number - */ - 'timeStamp': 0 - } - }); - - _.assign(Benchmark.prototype, { - 'abort': abort, - 'clone': clone, - 'compare': compare, - 'emit': emit, - 'listeners': listeners, - 'off': off, - 'on': on, - 'reset': reset, - 'run': run, - 'toString': toStringBench - }); - - /*------------------------------------------------------------------------*/ - - _.assign(Deferred.prototype, { - - /** - * The deferred benchmark instance. - * - * @memberOf Benchmark.Deferred - * @type Object - */ - 'benchmark': null, - - /** - * The number of deferred cycles performed while benchmarking. - * - * @memberOf Benchmark.Deferred - * @type number - */ - 'cycles': 0, - - /** - * The time taken to complete the deferred benchmark (secs). - * - * @memberOf Benchmark.Deferred - * @type number - */ - 'elapsed': 0, - - /** - * A timestamp of when the deferred benchmark started (ms). - * - * @memberOf Benchmark.Deferred - * @type number - */ - 'timeStamp': 0 - }); - - _.assign(Deferred.prototype, { - 'resolve': resolve - }); - - /*------------------------------------------------------------------------*/ - - _.assign(Event.prototype, { - - /** - * A flag to indicate if the emitters listener iteration is aborted. - * - * @memberOf Benchmark.Event - * @type boolean - */ - 'aborted': false, - - /** - * A flag to indicate if the default action is cancelled. - * - * @memberOf Benchmark.Event - * @type boolean - */ - 'cancelled': false, - - /** - * The object whose listeners are currently being processed. - * - * @memberOf Benchmark.Event - * @type Object - */ - 'currentTarget': undefined, - - /** - * The return value of the last executed listener. - * - * @memberOf Benchmark.Event - * @type Mixed - */ - 'result': undefined, - - /** - * The object to which the event was originally emitted. - * - * @memberOf Benchmark.Event - * @type Object - */ - 'target': undefined, - - /** - * A timestamp of when the event was created (ms). - * - * @memberOf Benchmark.Event - * @type number - */ - 'timeStamp': 0, - - /** - * The event type. - * - * @memberOf Benchmark.Event - * @type string - */ - 'type': '' - }); - - /*------------------------------------------------------------------------*/ - - /** - * The default options copied by suite instances. - * - * @static - * @memberOf Benchmark.Suite - * @type Object - */ - Suite.options = { - - /** - * The name of the suite. - * - * @memberOf Benchmark.Suite.options - * @type string - */ - 'name': undefined - }; - - /*------------------------------------------------------------------------*/ - - _.assign(Suite.prototype, { - - /** - * The number of benchmarks in the suite. - * - * @memberOf Benchmark.Suite - * @type number - */ - 'length': 0, - - /** - * A flag to indicate if the suite is aborted. - * - * @memberOf Benchmark.Suite - * @type boolean - */ - 'aborted': false, - - /** - * A flag to indicate if the suite is running. - * - * @memberOf Benchmark.Suite - * @type boolean - */ - 'running': false - }); - - _.assign(Suite.prototype, { - 'abort': abortSuite, - 'add': add, - 'clone': cloneSuite, - 'emit': emit, - 'filter': filterSuite, - 'join': arrayRef.join, - 'listeners': listeners, - 'off': off, - 'on': on, - 'pop': arrayRef.pop, - 'push': push, - 'reset': resetSuite, - 'run': runSuite, - 'reverse': arrayRef.reverse, - 'shift': shift, - 'slice': slice, - 'sort': arrayRef.sort, - 'splice': arrayRef.splice, - 'unshift': unshift - }); - - /*------------------------------------------------------------------------*/ - - // Expose Deferred, Event, and Suite. - _.assign(Benchmark, { - 'Deferred': Deferred, - 'Event': Event, - 'Suite': Suite - }); - - /*------------------------------------------------------------------------*/ - - // Add lodash methods as Suite methods. - _.each(['each', 'forEach', 'indexOf', 'map', 'reduce'], function(methodName) { - var func = _[methodName]; - Suite.prototype[methodName] = function() { - var args = [this]; - push.apply(args, arguments); - return func.apply(_, args); - }; - }); - - // Avoid array-like object bugs with `Array#shift` and `Array#splice` - // in Firefox < 10 and IE < 9. - _.each(['pop', 'shift', 'splice'], function(methodName) { - var func = arrayRef[methodName]; - - Suite.prototype[methodName] = function() { - var value = this, - result = func.apply(value, arguments); - - if (value.length === 0) { - delete value[0]; - } - return result; - }; - }); - - // Avoid buggy `Array#unshift` in IE < 8 which doesn't return the new - // length of the array. - Suite.prototype.unshift = function() { - var value = this; - unshift.apply(value, arguments); - return value.length; - }; - - return Benchmark; - } - - /*--------------------------------------------------------------------------*/ - - // Export Benchmark. - // Some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Define as an anonymous module so, through path mapping, it can be aliased. - define(['lodash', 'platform'], function(_, platform) { - return runInContext({ - '_': _, - 'platform': platform - }); - }); - } - else { - var Benchmark = runInContext(); - - // Check for `exports` after `define` in case a build optimizer adds an `exports` object. - if (freeExports && freeModule) { - // Export for Node.js. - if (moduleExports) { - (freeModule.exports = Benchmark).Benchmark = Benchmark; - } - // Export for CommonJS support. - freeExports.Benchmark = Benchmark; - } - else { - // Export to the global object. - root.Benchmark = Benchmark; - } - } -}.call(this)); diff --git a/third_party/immer/extra/js/lib/immutable.min.js b/third_party/immer/extra/js/lib/immutable.min.js deleted file mode 100644 index 18ffb77bb115..000000000000 --- a/third_party/immer/extra/js/lib/immutable.min.js +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright (c) 2014-2015, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.Immutable=e()}(this,function(){"use strict";function t(t,e){e&&(t.prototype=Object.create(e.prototype)),t.prototype.constructor=t}function e(t){return o(t)?t:O(t)}function r(t){return u(t)?t:x(t)}function n(t){return s(t)?t:k(t)}function i(t){return o(t)&&!a(t)?t:A(t)}function o(t){return!(!t||!t[ar])}function u(t){return!(!t||!t[hr])}function s(t){return!(!t||!t[fr])}function a(t){return u(t)||s(t)}function h(t){return!(!t||!t[cr])}function f(t){return t.value=!1,t}function c(t){t&&(t.value=!0)}function _(){}function p(t,e){e=e||0;for(var r=Math.max(0,t.length-e),n=Array(r),i=0;r>i;i++)n[i]=t[i+e];return n}function v(t){return void 0===t.size&&(t.size=t.__iterate(y)),t.size}function l(t,e){if("number"!=typeof e){var r=e>>>0;if(""+r!==e||4294967295===r)return NaN;e=r}return 0>e?v(t)+e:e}function y(){return!0}function d(t,e,r){return(0===t||void 0!==r&&-r>=t)&&(void 0===e||void 0!==r&&e>=r)}function m(t,e){return w(t,e,0)}function g(t,e){return w(t,e,e)}function w(t,e,r){return void 0===t?r:0>t?Math.max(0,e+t):void 0===e?t:Math.min(e,t)}function S(t){this.next=t}function z(t,e,r,n){var i=0===t?e:1===t?r:[e,r];return n?n.value=i:n={value:i,done:!1},n}function I(){return{value:void 0,done:!0}}function b(t){return!!M(t)}function q(t){return t&&"function"==typeof t.next}function D(t){var e=M(t);return e&&e.call(t)}function M(t){var e=t&&(zr&&t[zr]||t[Ir]);return"function"==typeof e?e:void 0}function E(t){return t&&"number"==typeof t.length}function O(t){return null===t||void 0===t?T():o(t)?t.toSeq():C(t)}function x(t){return null===t||void 0===t?T().toKeyedSeq():o(t)?u(t)?t.toSeq():t.fromEntrySeq():B(t)}function k(t){return null===t||void 0===t?T():o(t)?u(t)?t.entrySeq():t.toIndexedSeq():W(t)}function A(t){return(null===t||void 0===t?T():o(t)?u(t)?t.entrySeq():t:W(t)).toSetSeq()}function j(t){this._array=t,this.size=t.length}function R(t){var e=Object.keys(t);this._object=t,this._keys=e, -this.size=e.length}function U(t){this._iterable=t,this.size=t.length||t.size}function K(t){this._iterator=t,this._iteratorCache=[]}function L(t){return!(!t||!t[qr])}function T(){return Dr||(Dr=new j([]))}function B(t){var e=Array.isArray(t)?new j(t).fromEntrySeq():q(t)?new K(t).fromEntrySeq():b(t)?new U(t).fromEntrySeq():"object"==typeof t?new R(t):void 0;if(!e)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+t);return e}function W(t){var e=J(t);if(!e)throw new TypeError("Expected Array or iterable object of values: "+t);return e}function C(t){var e=J(t)||"object"==typeof t&&new R(t);if(!e)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+t);return e}function J(t){return E(t)?new j(t):q(t)?new K(t):b(t)?new U(t):void 0}function N(t,e,r,n){var i=t._cache;if(i){for(var o=i.length-1,u=0;o>=u;u++){var s=i[r?o-u:u];if(e(s[1],n?s[0]:u,t)===!1)return u+1}return u}return t.__iterateUncached(e,r)}function P(t,e,r,n){var i=t._cache;if(i){var o=i.length-1,u=0;return new S(function(){var t=i[r?o-u:u];return u++>o?I():z(e,n?t[0]:u-1,t[1])})}return t.__iteratorUncached(e,r)}function H(t,e){return e?V(e,t,"",{"":t}):Y(t)}function V(t,e,r,n){return Array.isArray(e)?t.call(n,r,k(e).map(function(r,n){return V(t,r,n,e)})):Q(e)?t.call(n,r,x(e).map(function(r,n){return V(t,r,n,e)})):e}function Y(t){return Array.isArray(t)?k(t).map(Y).toList():Q(t)?x(t).map(Y).toMap():t}function Q(t){return t&&(t.constructor===Object||void 0===t.constructor)}function X(t,e){if(t===e||t!==t&&e!==e)return!0;if(!t||!e)return!1;if("function"==typeof t.valueOf&&"function"==typeof e.valueOf){if(t=t.valueOf(),e=e.valueOf(),t===e||t!==t&&e!==e)return!0;if(!t||!e)return!1}return"function"==typeof t.equals&&"function"==typeof e.equals&&t.equals(e)?!0:!1}function F(t,e){if(t===e)return!0;if(!o(e)||void 0!==t.size&&void 0!==e.size&&t.size!==e.size||void 0!==t.__hash&&void 0!==e.__hash&&t.__hash!==e.__hash||u(t)!==u(e)||s(t)!==s(e)||h(t)!==h(e))return!1;if(0===t.size&&0===e.size)return!0; -var r=!a(t);if(h(t)){var n=t.entries();return e.every(function(t,e){var i=n.next().value;return i&&X(i[1],t)&&(r||X(i[0],e))})&&n.next().done}var i=!1;if(void 0===t.size)if(void 0===e.size)"function"==typeof t.cacheResult&&t.cacheResult();else{i=!0;var f=t;t=e,e=f}var c=!0,_=e.__iterate(function(e,n){return(r?t.has(e):i?X(e,t.get(n,yr)):X(t.get(n,yr),e))?void 0:(c=!1,!1)});return c&&t.size===_}function G(t,e){if(!(this instanceof G))return new G(t,e);if(this._value=t,this.size=void 0===e?1/0:Math.max(0,e),0===this.size){if(Mr)return Mr;Mr=this}}function Z(t,e){if(!t)throw Error(e)}function $(t,e,r){if(!(this instanceof $))return new $(t,e,r);if(Z(0!==r,"Cannot step a Range by 0"),t=t||0,void 0===e&&(e=1/0),r=void 0===r?1:Math.abs(r),t>e&&(r=-r),this._start=t,this._end=e,this._step=r,this.size=Math.max(0,Math.ceil((e-t)/r-1)+1),0===this.size){if(Er)return Er;Er=this}}function tt(){throw TypeError("Abstract")}function et(){}function rt(){}function nt(){}function it(t){return t>>>1&1073741824|3221225471&t}function ot(t){if(t===!1||null===t||void 0===t)return 0;if("function"==typeof t.valueOf&&(t=t.valueOf(),t===!1||null===t||void 0===t))return 0;if(t===!0)return 1;var e=typeof t;if("number"===e){if(t!==t||t===1/0)return 0;var r=0|t;for(r!==t&&(r^=4294967295*t);t>4294967295;)t/=4294967295,r^=t;return it(r)}if("string"===e)return t.length>Kr?ut(t):st(t);if("function"==typeof t.hashCode)return t.hashCode();if("object"===e)return at(t);if("function"==typeof t.toString)return st(""+t);throw Error("Value type "+e+" cannot be hashed.")}function ut(t){var e=Br[t];return void 0===e&&(e=st(t),Tr===Lr&&(Tr=0,Br={}),Tr++,Br[t]=e),e}function st(t){for(var e=0,r=0;t.length>r;r++)e=31*e+t.charCodeAt(r)|0;return it(e)}function at(t){var e;if(jr&&(e=Or.get(t),void 0!==e))return e;if(e=t[Ur],void 0!==e)return e;if(!Ar){if(e=t.propertyIsEnumerable&&t.propertyIsEnumerable[Ur],void 0!==e)return e;if(e=ht(t),void 0!==e)return e}if(e=++Rr,1073741824&Rr&&(Rr=0),jr)Or.set(t,e);else{if(void 0!==kr&&kr(t)===!1)throw Error("Non-extensible objects are not allowed as keys."); -if(Ar)Object.defineProperty(t,Ur,{enumerable:!1,configurable:!1,writable:!1,value:e});else if(void 0!==t.propertyIsEnumerable&&t.propertyIsEnumerable===t.constructor.prototype.propertyIsEnumerable)t.propertyIsEnumerable=function(){return this.constructor.prototype.propertyIsEnumerable.apply(this,arguments)},t.propertyIsEnumerable[Ur]=e;else{if(void 0===t.nodeType)throw Error("Unable to set a non-enumerable property on object.");t[Ur]=e}}return e}function ht(t){if(t&&t.nodeType>0)switch(t.nodeType){case 1:return t.uniqueID;case 9:return t.documentElement&&t.documentElement.uniqueID}}function ft(t){Z(t!==1/0,"Cannot perform this action with an infinite size.")}function ct(t){return null===t||void 0===t?zt():_t(t)&&!h(t)?t:zt().withMutations(function(e){var n=r(t);ft(n.size),n.forEach(function(t,r){return e.set(r,t)})})}function _t(t){return!(!t||!t[Wr])}function pt(t,e){this.ownerID=t,this.entries=e}function vt(t,e,r){this.ownerID=t,this.bitmap=e,this.nodes=r}function lt(t,e,r){this.ownerID=t,this.count=e,this.nodes=r}function yt(t,e,r){this.ownerID=t,this.keyHash=e,this.entries=r}function dt(t,e,r){this.ownerID=t,this.keyHash=e,this.entry=r}function mt(t,e,r){this._type=e,this._reverse=r,this._stack=t._root&&wt(t._root)}function gt(t,e){return z(t,e[0],e[1])}function wt(t,e){return{node:t,index:0,__prev:e}}function St(t,e,r,n){var i=Object.create(Cr);return i.size=t,i._root=e,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function zt(){return Jr||(Jr=St(0))}function It(t,e,r){var n,i;if(t._root){var o=f(dr),u=f(mr);if(n=bt(t._root,t.__ownerID,0,void 0,e,r,o,u),!u.value)return t;i=t.size+(o.value?r===yr?-1:1:0)}else{if(r===yr)return t;i=1,n=new pt(t.__ownerID,[[e,r]])}return t.__ownerID?(t.size=i,t._root=n,t.__hash=void 0,t.__altered=!0,t):n?St(i,n):zt()}function bt(t,e,r,n,i,o,u,s){return t?t.update(e,r,n,i,o,u,s):o===yr?t:(c(s),c(u),new dt(e,n,[i,o]))}function qt(t){return t.constructor===dt||t.constructor===yt}function Dt(t,e,r,n,i){if(t.keyHash===n)return new yt(e,n,[t.entry,i]);var o,u=(0===r?t.keyHash:t.keyHash>>>r)&lr,s=(0===r?n:n>>>r)&lr,a=u===s?[Dt(t,e,r+pr,n,i)]:(o=new dt(e,n,i), -s>u?[t,o]:[o,t]);return new vt(e,1<<u|1<<s,a)}function Mt(t,e,r,n){t||(t=new _);for(var i=new dt(t,ot(r),[r,n]),o=0;e.length>o;o++){var u=e[o];i=i.update(t,0,void 0,u[0],u[1])}return i}function Et(t,e,r,n){for(var i=0,o=0,u=Array(r),s=0,a=1,h=e.length;h>s;s++,a<<=1){var f=e[s];void 0!==f&&s!==n&&(i|=a,u[o++]=f)}return new vt(t,i,u)}function Ot(t,e,r,n,i){for(var o=0,u=Array(vr),s=0;0!==r;s++,r>>>=1)u[s]=1&r?e[o++]:void 0;return u[n]=i,new lt(t,o+1,u)}function xt(t,e,n){for(var i=[],u=0;n.length>u;u++){var s=n[u],a=r(s);o(s)||(a=a.map(function(t){return H(t)})),i.push(a)}return jt(t,e,i)}function kt(t,e,r){return t&&t.mergeDeep&&o(e)?t.mergeDeep(e):X(t,e)?t:e}function At(t){return function(e,r,n){if(e&&e.mergeDeepWith&&o(r))return e.mergeDeepWith(t,r);var i=t(e,r,n);return X(e,i)?e:i}}function jt(t,e,r){return r=r.filter(function(t){return 0!==t.size}),0===r.length?t:0!==t.size||t.__ownerID||1!==r.length?t.withMutations(function(t){for(var n=e?function(r,n){t.update(n,yr,function(t){return t===yr?r:e(t,r,n)})}:function(e,r){t.set(r,e)},i=0;r.length>i;i++)r[i].forEach(n)}):t.constructor(r[0])}function Rt(t,e,r,n){var i=t===yr,o=e.next();if(o.done){var u=i?r:t,s=n(u);return s===u?t:s}Z(i||t&&t.set,"invalid keyPath");var a=o.value,h=i?yr:t.get(a,yr),f=Rt(h,e,r,n);return f===h?t:f===yr?t.remove(a):(i?zt():t).set(a,f)}function Ut(t){return t-=t>>1&1431655765,t=(858993459&t)+(t>>2&858993459),t=t+(t>>4)&252645135,t+=t>>8,t+=t>>16,127&t}function Kt(t,e,r,n){var i=n?t:p(t);return i[e]=r,i}function Lt(t,e,r,n){var i=t.length+1;if(n&&e+1===i)return t[e]=r,t;for(var o=Array(i),u=0,s=0;i>s;s++)s===e?(o[s]=r,u=-1):o[s]=t[s+u];return o}function Tt(t,e,r){var n=t.length-1;if(r&&e===n)return t.pop(),t;for(var i=Array(n),o=0,u=0;n>u;u++)u===e&&(o=1),i[u]=t[u+o];return i}function Bt(t){var e=Pt();if(null===t||void 0===t)return e;if(Wt(t))return t;var r=n(t),i=r.size;return 0===i?e:(ft(i),i>0&&vr>i?Nt(0,i,pr,null,new Ct(r.toArray())):e.withMutations(function(t){t.setSize(i),r.forEach(function(e,r){return t.set(r,e)})}))}function Wt(t){ -return!(!t||!t[Vr])}function Ct(t,e){this.array=t,this.ownerID=e}function Jt(t,e){function r(t,e,r){return 0===e?n(t,r):i(t,e,r)}function n(t,r){var n=r===s?a&&a.array:t&&t.array,i=r>o?0:o-r,h=u-r;return h>vr&&(h=vr),function(){if(i===h)return Xr;var t=e?--h:i++;return n&&n[t]}}function i(t,n,i){var s,a=t&&t.array,h=i>o?0:o-i>>n,f=(u-i>>n)+1;return f>vr&&(f=vr),function(){for(;;){if(s){var t=s();if(t!==Xr)return t;s=null}if(h===f)return Xr;var o=e?--f:h++;s=r(a&&a[o],n-pr,i+(o<<n))}}}var o=t._origin,u=t._capacity,s=Gt(u),a=t._tail;return r(t._root,t._level,0)}function Nt(t,e,r,n,i,o,u){var s=Object.create(Yr);return s.size=e-t,s._origin=t,s._capacity=e,s._level=r,s._root=n,s._tail=i,s.__ownerID=o,s.__hash=u,s.__altered=!1,s}function Pt(){return Qr||(Qr=Nt(0,0,pr))}function Ht(t,e,r){if(e=l(t,e),e!==e)return t;if(e>=t.size||0>e)return t.withMutations(function(t){0>e?Xt(t,e).set(0,r):Xt(t,0,e+1).set(e,r)});e+=t._origin;var n=t._tail,i=t._root,o=f(mr);return e>=Gt(t._capacity)?n=Vt(n,t.__ownerID,0,e,r,o):i=Vt(i,t.__ownerID,t._level,e,r,o),o.value?t.__ownerID?(t._root=i,t._tail=n,t.__hash=void 0,t.__altered=!0,t):Nt(t._origin,t._capacity,t._level,i,n):t}function Vt(t,e,r,n,i,o){var u=n>>>r&lr,s=t&&t.array.length>u;if(!s&&void 0===i)return t;var a;if(r>0){var h=t&&t.array[u],f=Vt(h,e,r-pr,n,i,o);return f===h?t:(a=Yt(t,e),a.array[u]=f,a)}return s&&t.array[u]===i?t:(c(o),a=Yt(t,e),void 0===i&&u===a.array.length-1?a.array.pop():a.array[u]=i,a)}function Yt(t,e){return e&&t&&e===t.ownerID?t:new Ct(t?t.array.slice():[],e)}function Qt(t,e){if(e>=Gt(t._capacity))return t._tail;if(1<<t._level+pr>e){for(var r=t._root,n=t._level;r&&n>0;)r=r.array[e>>>n&lr],n-=pr;return r}}function Xt(t,e,r){void 0!==e&&(e=0|e),void 0!==r&&(r=0|r);var n=t.__ownerID||new _,i=t._origin,o=t._capacity,u=i+e,s=void 0===r?o:0>r?o+r:i+r;if(u===i&&s===o)return t;if(u>=s)return t.clear();for(var a=t._level,h=t._root,f=0;0>u+f;)h=new Ct(h&&h.array.length?[void 0,h]:[],n),a+=pr,f+=1<<a;f&&(u+=f,i+=f,s+=f,o+=f);for(var c=Gt(o),p=Gt(s);p>=1<<a+pr;)h=new Ct(h&&h.array.length?[h]:[],n), -a+=pr;var v=t._tail,l=c>p?Qt(t,s-1):p>c?new Ct([],n):v;if(v&&p>c&&o>u&&v.array.length){h=Yt(h,n);for(var y=h,d=a;d>pr;d-=pr){var m=c>>>d&lr;y=y.array[m]=Yt(y.array[m],n)}y.array[c>>>pr&lr]=v}if(o>s&&(l=l&&l.removeAfter(n,0,s)),u>=p)u-=p,s-=p,a=pr,h=null,l=l&&l.removeBefore(n,0,u);else if(u>i||c>p){for(f=0;h;){var g=u>>>a&lr;if(g!==p>>>a&lr)break;g&&(f+=(1<<a)*g),a-=pr,h=h.array[g]}h&&u>i&&(h=h.removeBefore(n,a,u-f)),h&&c>p&&(h=h.removeAfter(n,a,p-f)),f&&(u-=f,s-=f)}return t.__ownerID?(t.size=s-u,t._origin=u,t._capacity=s,t._level=a,t._root=h,t._tail=l,t.__hash=void 0,t.__altered=!0,t):Nt(u,s,a,h,l)}function Ft(t,e,r){for(var i=[],u=0,s=0;r.length>s;s++){var a=r[s],h=n(a);h.size>u&&(u=h.size),o(a)||(h=h.map(function(t){return H(t)})),i.push(h)}return u>t.size&&(t=t.setSize(u)),jt(t,e,i)}function Gt(t){return vr>t?0:t-1>>>pr<<pr}function Zt(t){return null===t||void 0===t?ee():$t(t)?t:ee().withMutations(function(e){var n=r(t);ft(n.size),n.forEach(function(t,r){return e.set(r,t)})})}function $t(t){return _t(t)&&h(t)}function te(t,e,r,n){var i=Object.create(Zt.prototype);return i.size=t?t.size:0,i._map=t,i._list=e,i.__ownerID=r,i.__hash=n,i}function ee(){return Fr||(Fr=te(zt(),Pt()))}function re(t,e,r){var n,i,o=t._map,u=t._list,s=o.get(e),a=void 0!==s;if(r===yr){if(!a)return t;u.size>=vr&&u.size>=2*o.size?(i=u.filter(function(t,e){return void 0!==t&&s!==e}),n=i.toKeyedSeq().map(function(t){return t[0]}).flip().toMap(),t.__ownerID&&(n.__ownerID=i.__ownerID=t.__ownerID)):(n=o.remove(e),i=s===u.size-1?u.pop():u.set(s,void 0))}else if(a){if(r===u.get(s)[1])return t;n=o,i=u.set(s,[e,r])}else n=o.set(e,u.size),i=u.set(u.size,[e,r]);return t.__ownerID?(t.size=n.size,t._map=n,t._list=i,t.__hash=void 0,t):te(n,i)}function ne(t,e){this._iter=t,this._useKeys=e,this.size=t.size}function ie(t){this._iter=t,this.size=t.size}function oe(t){this._iter=t,this.size=t.size}function ue(t){this._iter=t,this.size=t.size}function se(t){var e=Ee(t);return e._iter=t,e.size=t.size,e.flip=function(){return t},e.reverse=function(){var e=t.reverse.apply(this); -return e.flip=function(){return t.reverse()},e},e.has=function(e){return t.includes(e)},e.includes=function(e){return t.has(e)},e.cacheResult=Oe,e.__iterateUncached=function(e,r){var n=this;return t.__iterate(function(t,r){return e(r,t,n)!==!1},r)},e.__iteratorUncached=function(e,r){if(e===Sr){var n=t.__iterator(e,r);return new S(function(){var t=n.next();if(!t.done){var e=t.value[0];t.value[0]=t.value[1],t.value[1]=e}return t})}return t.__iterator(e===wr?gr:wr,r)},e}function ae(t,e,r){var n=Ee(t);return n.size=t.size,n.has=function(e){return t.has(e)},n.get=function(n,i){var o=t.get(n,yr);return o===yr?i:e.call(r,o,n,t)},n.__iterateUncached=function(n,i){var o=this;return t.__iterate(function(t,i,u){return n(e.call(r,t,i,u),i,o)!==!1},i)},n.__iteratorUncached=function(n,i){var o=t.__iterator(Sr,i);return new S(function(){var i=o.next();if(i.done)return i;var u=i.value,s=u[0];return z(n,s,e.call(r,u[1],s,t),i)})},n}function he(t,e){var r=Ee(t);return r._iter=t,r.size=t.size,r.reverse=function(){return t},t.flip&&(r.flip=function(){var e=se(t);return e.reverse=function(){return t.flip()},e}),r.get=function(r,n){return t.get(e?r:-1-r,n)},r.has=function(r){return t.has(e?r:-1-r)},r.includes=function(e){return t.includes(e)},r.cacheResult=Oe,r.__iterate=function(e,r){var n=this;return t.__iterate(function(t,r){return e(t,r,n)},!r)},r.__iterator=function(e,r){return t.__iterator(e,!r)},r}function fe(t,e,r,n){var i=Ee(t);return n&&(i.has=function(n){var i=t.get(n,yr);return i!==yr&&!!e.call(r,i,n,t)},i.get=function(n,i){var o=t.get(n,yr);return o!==yr&&e.call(r,o,n,t)?o:i}),i.__iterateUncached=function(i,o){var u=this,s=0;return t.__iterate(function(t,o,a){return e.call(r,t,o,a)?(s++,i(t,n?o:s-1,u)):void 0},o),s},i.__iteratorUncached=function(i,o){var u=t.__iterator(Sr,o),s=0;return new S(function(){for(;;){var o=u.next();if(o.done)return o;var a=o.value,h=a[0],f=a[1];if(e.call(r,f,h,t))return z(i,n?h:s++,f,o)}})},i}function ce(t,e,r){var n=ct().asMutable();return t.__iterate(function(i,o){n.update(e.call(r,i,o,t),0,function(t){ -return t+1})}),n.asImmutable()}function _e(t,e,r){var n=u(t),i=(h(t)?Zt():ct()).asMutable();t.__iterate(function(o,u){i.update(e.call(r,o,u,t),function(t){return t=t||[],t.push(n?[u,o]:o),t})});var o=Me(t);return i.map(function(e){return be(t,o(e))})}function pe(t,e,r,n){var i=t.size;if(void 0!==e&&(e=0|e),void 0!==r&&(r=r===1/0?i:0|r),d(e,r,i))return t;var o=m(e,i),u=g(r,i);if(o!==o||u!==u)return pe(t.toSeq().cacheResult(),e,r,n);var s,a=u-o;a===a&&(s=0>a?0:a);var h=Ee(t);return h.size=0===s?s:t.size&&s||void 0,!n&&L(t)&&s>=0&&(h.get=function(e,r){return e=l(this,e),e>=0&&s>e?t.get(e+o,r):r}),h.__iterateUncached=function(e,r){var i=this;if(0===s)return 0;if(r)return this.cacheResult().__iterate(e,r);var u=0,a=!0,h=0;return t.__iterate(function(t,r){return a&&(a=u++<o)?void 0:(h++,e(t,n?r:h-1,i)!==!1&&h!==s)}),h},h.__iteratorUncached=function(e,r){if(0!==s&&r)return this.cacheResult().__iterator(e,r);var i=0!==s&&t.__iterator(e,r),u=0,a=0;return new S(function(){for(;u++<o;)i.next();if(++a>s)return I();var t=i.next();return n||e===wr?t:e===gr?z(e,a-1,void 0,t):z(e,a-1,t.value[1],t)})},h}function ve(t,e,r){var n=Ee(t);return n.__iterateUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterate(n,i);var u=0;return t.__iterate(function(t,i,s){return e.call(r,t,i,s)&&++u&&n(t,i,o)}),u},n.__iteratorUncached=function(n,i){var o=this;if(i)return this.cacheResult().__iterator(n,i);var u=t.__iterator(Sr,i),s=!0;return new S(function(){if(!s)return I();var t=u.next();if(t.done)return t;var i=t.value,a=i[0],h=i[1];return e.call(r,h,a,o)?n===Sr?t:z(n,a,h,t):(s=!1,I())})},n}function le(t,e,r,n){var i=Ee(t);return i.__iterateUncached=function(i,o){var u=this;if(o)return this.cacheResult().__iterate(i,o);var s=!0,a=0;return t.__iterate(function(t,o,h){return s&&(s=e.call(r,t,o,h))?void 0:(a++,i(t,n?o:a-1,u))}),a},i.__iteratorUncached=function(i,o){var u=this;if(o)return this.cacheResult().__iterator(i,o);var s=t.__iterator(Sr,o),a=!0,h=0;return new S(function(){var t,o,f;do{if(t=s.next(),t.done)return n||i===wr?t:i===gr?z(i,h++,void 0,t):z(i,h++,t.value[1],t); -var c=t.value;o=c[0],f=c[1],a&&(a=e.call(r,f,o,u))}while(a);return i===Sr?t:z(i,o,f,t)})},i}function ye(t,e){var n=u(t),i=[t].concat(e).map(function(t){return o(t)?n&&(t=r(t)):t=n?B(t):W(Array.isArray(t)?t:[t]),t}).filter(function(t){return 0!==t.size});if(0===i.length)return t;if(1===i.length){var a=i[0];if(a===t||n&&u(a)||s(t)&&s(a))return a}var h=new j(i);return n?h=h.toKeyedSeq():s(t)||(h=h.toSetSeq()),h=h.flatten(!0),h.size=i.reduce(function(t,e){if(void 0!==t){var r=e.size;if(void 0!==r)return t+r}},0),h}function de(t,e,r){var n=Ee(t);return n.__iterateUncached=function(n,i){function u(t,h){var f=this;t.__iterate(function(t,i){return(!e||e>h)&&o(t)?u(t,h+1):n(t,r?i:s++,f)===!1&&(a=!0),!a},i)}var s=0,a=!1;return u(t,0),s},n.__iteratorUncached=function(n,i){var u=t.__iterator(n,i),s=[],a=0;return new S(function(){for(;u;){var t=u.next();if(t.done===!1){var h=t.value;if(n===Sr&&(h=h[1]),e&&!(e>s.length)||!o(h))return r?t:z(n,a++,h,t);s.push(u),u=h.__iterator(n,i)}else u=s.pop()}return I()})},n}function me(t,e,r){var n=Me(t);return t.toSeq().map(function(i,o){return n(e.call(r,i,o,t))}).flatten(!0)}function ge(t,e){var r=Ee(t);return r.size=t.size&&2*t.size-1,r.__iterateUncached=function(r,n){var i=this,o=0;return t.__iterate(function(t,n){return(!o||r(e,o++,i)!==!1)&&r(t,o++,i)!==!1},n),o},r.__iteratorUncached=function(r,n){var i,o=t.__iterator(wr,n),u=0;return new S(function(){return(!i||u%2)&&(i=o.next(),i.done)?i:u%2?z(r,u++,e):z(r,u++,i.value,i)})},r}function we(t,e,r){e||(e=xe);var n=u(t),i=0,o=t.toSeq().map(function(e,n){return[n,e,i++,r?r(e,n,t):e]}).toArray();return o.sort(function(t,r){return e(t[3],r[3])||t[2]-r[2]}).forEach(n?function(t,e){o[e].length=2}:function(t,e){o[e]=t[1]}),n?x(o):s(t)?k(o):A(o)}function Se(t,e,r){if(e||(e=xe),r){var n=t.toSeq().map(function(e,n){return[e,r(e,n,t)]}).reduce(function(t,r){return ze(e,t[1],r[1])?r:t});return n&&n[0]}return t.reduce(function(t,r){return ze(e,t,r)?r:t})}function ze(t,e,r){var n=t(r,e);return 0===n&&r!==e&&(void 0===r||null===r||r!==r)||n>0}function Ie(t,r,n){ -var i=Ee(t);return i.size=new j(n).map(function(t){return t.size}).min(),i.__iterate=function(t,e){for(var r,n=this.__iterator(wr,e),i=0;!(r=n.next()).done&&t(r.value,i++,this)!==!1;);return i},i.__iteratorUncached=function(t,i){var o=n.map(function(t){return t=e(t),D(i?t.reverse():t)}),u=0,s=!1;return new S(function(){var e;return s||(e=o.map(function(t){return t.next()}),s=e.some(function(t){return t.done})),s?I():z(t,u++,r.apply(null,e.map(function(t){return t.value})))})},i}function be(t,e){return L(t)?e:t.constructor(e)}function qe(t){if(t!==Object(t))throw new TypeError("Expected [K, V] tuple: "+t)}function De(t){return ft(t.size),v(t)}function Me(t){return u(t)?r:s(t)?n:i}function Ee(t){return Object.create((u(t)?x:s(t)?k:A).prototype)}function Oe(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):O.prototype.cacheResult.call(this)}function xe(t,e){return t>e?1:e>t?-1:0}function ke(t){var r=D(t);if(!r){if(!E(t))throw new TypeError("Expected iterable or array-like: "+t);r=D(e(t))}return r}function Ae(t,e){var r,n=function(o){if(o instanceof n)return o;if(!(this instanceof n))return new n(o);if(!r){r=!0;var u=Object.keys(t);Ue(i,u),i.size=u.length,i._name=e,i._keys=u,i._defaultValues=t}this._map=ct(o)},i=n.prototype=Object.create(Gr);return i.constructor=n,n}function je(t,e,r){var n=Object.create(Object.getPrototypeOf(t));return n._map=e,n.__ownerID=r,n}function Re(t){return t._name||t.constructor.name||"Record"}function Ue(t,e){try{e.forEach(Ke.bind(void 0,t))}catch(r){}}function Ke(t,e){Object.defineProperty(t,e,{get:function(){return this.get(e)},set:function(t){Z(this.__ownerID,"Cannot set on an immutable record."),this.set(e,t)}})}function Le(t){return null===t||void 0===t?Ce():Te(t)&&!h(t)?t:Ce().withMutations(function(e){var r=i(t);ft(r.size),r.forEach(function(t){return e.add(t)})})}function Te(t){return!(!t||!t[Zr])}function Be(t,e){return t.__ownerID?(t.size=e.size,t._map=e,t):e===t._map?t:0===e.size?t.__empty():t.__make(e)}function We(t,e){var r=Object.create($r); -return r.size=t?t.size:0,r._map=t,r.__ownerID=e,r}function Ce(){return tn||(tn=We(zt()))}function Je(t){return null===t||void 0===t?He():Ne(t)?t:He().withMutations(function(e){var r=i(t);ft(r.size),r.forEach(function(t){return e.add(t)})})}function Ne(t){return Te(t)&&h(t)}function Pe(t,e){var r=Object.create(en);return r.size=t?t.size:0,r._map=t,r.__ownerID=e,r}function He(){return rn||(rn=Pe(ee()))}function Ve(t){return null===t||void 0===t?Xe():Ye(t)?t:Xe().unshiftAll(t)}function Ye(t){return!(!t||!t[nn])}function Qe(t,e,r,n){var i=Object.create(on);return i.size=t,i._head=e,i.__ownerID=r,i.__hash=n,i.__altered=!1,i}function Xe(){return un||(un=Qe(0))}function Fe(t,e){var r=function(r){t.prototype[r]=e[r]};return Object.keys(e).forEach(r),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(e).forEach(r),t}function Ge(t,e){return e}function Ze(t,e){return[e,t]}function $e(t){return function(){return!t.apply(this,arguments)}}function tr(t){return function(){return-t.apply(this,arguments)}}function er(t){return"string"==typeof t?JSON.stringify(t):t+""}function rr(){return p(arguments)}function nr(t,e){return e>t?1:t>e?-1:0}function ir(t){if(t.size===1/0)return 0;var e=h(t),r=u(t),n=e?1:0,i=t.__iterate(r?e?function(t,e){n=31*n+ur(ot(t),ot(e))|0}:function(t,e){n=n+ur(ot(t),ot(e))|0}:e?function(t){n=31*n+ot(t)|0}:function(t){n=n+ot(t)|0});return or(i,n)}function or(t,e){return e=xr(e,3432918353),e=xr(e<<15|e>>>-15,461845907),e=xr(e<<13|e>>>-13,5),e=(e+3864292196|0)^t,e=xr(e^e>>>16,2246822507),e=xr(e^e>>>13,3266489909),e=it(e^e>>>16)}function ur(t,e){return t^e+2654435769+(t<<6)+(t>>2)|0}var sr=Array.prototype.slice;t(r,e),t(n,e),t(i,e),e.isIterable=o,e.isKeyed=u,e.isIndexed=s,e.isAssociative=a,e.isOrdered=h,e.Keyed=r,e.Indexed=n,e.Set=i;var ar="@@__IMMUTABLE_ITERABLE__@@",hr="@@__IMMUTABLE_KEYED__@@",fr="@@__IMMUTABLE_INDEXED__@@",cr="@@__IMMUTABLE_ORDERED__@@",_r="delete",pr=5,vr=1<<pr,lr=vr-1,yr={},dr={value:!1},mr={value:!1},gr=0,wr=1,Sr=2,zr="function"==typeof Symbol&&Symbol.iterator,Ir="@@iterator",br=zr||Ir; -S.prototype.toString=function(){return"[Iterator]"},S.KEYS=gr,S.VALUES=wr,S.ENTRIES=Sr,S.prototype.inspect=S.prototype.toSource=function(){return""+this},S.prototype[br]=function(){return this},t(O,e),O.of=function(){return O(arguments)},O.prototype.toSeq=function(){return this},O.prototype.toString=function(){return this.__toString("Seq {","}")},O.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},O.prototype.__iterate=function(t,e){return N(this,t,e,!0)},O.prototype.__iterator=function(t,e){return P(this,t,e,!0)},t(x,O),x.prototype.toKeyedSeq=function(){return this},t(k,O),k.of=function(){return k(arguments)},k.prototype.toIndexedSeq=function(){return this},k.prototype.toString=function(){return this.__toString("Seq [","]")},k.prototype.__iterate=function(t,e){return N(this,t,e,!1)},k.prototype.__iterator=function(t,e){return P(this,t,e,!1)},t(A,O),A.of=function(){return A(arguments)},A.prototype.toSetSeq=function(){return this},O.isSeq=L,O.Keyed=x,O.Set=A,O.Indexed=k;var qr="@@__IMMUTABLE_SEQ__@@";O.prototype[qr]=!0,t(j,k),j.prototype.get=function(t,e){return this.has(t)?this._array[l(this,t)]:e},j.prototype.__iterate=function(t,e){for(var r=this._array,n=r.length-1,i=0;n>=i;i++)if(t(r[e?n-i:i],i,this)===!1)return i+1;return i},j.prototype.__iterator=function(t,e){var r=this._array,n=r.length-1,i=0;return new S(function(){return i>n?I():z(t,i,r[e?n-i++:i++])})},t(R,x),R.prototype.get=function(t,e){return void 0===e||this.has(t)?this._object[t]:e},R.prototype.has=function(t){return this._object.hasOwnProperty(t)},R.prototype.__iterate=function(t,e){for(var r=this._object,n=this._keys,i=n.length-1,o=0;i>=o;o++){var u=n[e?i-o:o];if(t(r[u],u,this)===!1)return o+1}return o},R.prototype.__iterator=function(t,e){var r=this._object,n=this._keys,i=n.length-1,o=0;return new S(function(){var u=n[e?i-o:o];return o++>i?I():z(t,u,r[u])})},R.prototype[cr]=!0,t(U,k),U.prototype.__iterateUncached=function(t,e){if(e)return this.cacheResult().__iterate(t,e); -var r=this._iterable,n=D(r),i=0;if(q(n))for(var o;!(o=n.next()).done&&t(o.value,i++,this)!==!1;);return i},U.prototype.__iteratorUncached=function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterable,n=D(r);if(!q(n))return new S(I);var i=0;return new S(function(){var e=n.next();return e.done?e:z(t,i++,e.value)})},t(K,k),K.prototype.__iterateUncached=function(t,e){if(e)return this.cacheResult().__iterate(t,e);for(var r=this._iterator,n=this._iteratorCache,i=0;n.length>i;)if(t(n[i],i++,this)===!1)return i;for(var o;!(o=r.next()).done;){var u=o.value;if(n[i]=u,t(u,i++,this)===!1)break}return i},K.prototype.__iteratorUncached=function(t,e){if(e)return this.cacheResult().__iterator(t,e);var r=this._iterator,n=this._iteratorCache,i=0;return new S(function(){if(i>=n.length){var e=r.next();if(e.done)return e;n[i]=e.value}return z(t,i,n[i++])})};var Dr;t(G,k),G.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},G.prototype.get=function(t,e){return this.has(t)?this._value:e},G.prototype.includes=function(t){return X(this._value,t)},G.prototype.slice=function(t,e){var r=this.size;return d(t,e,r)?this:new G(this._value,g(e,r)-m(t,r))},G.prototype.reverse=function(){return this},G.prototype.indexOf=function(t){return X(this._value,t)?0:-1},G.prototype.lastIndexOf=function(t){return X(this._value,t)?this.size:-1},G.prototype.__iterate=function(t,e){for(var r=0;this.size>r;r++)if(t(this._value,r,this)===!1)return r+1;return r},G.prototype.__iterator=function(t,e){var r=this,n=0;return new S(function(){return r.size>n?z(t,n++,r._value):I()})},G.prototype.equals=function(t){return t instanceof G?X(this._value,t._value):F(t)};var Mr;t($,k),$.prototype.toString=function(){return 0===this.size?"Range []":"Range [ "+this._start+"..."+this._end+(1!==this._step?" by "+this._step:"")+" ]"},$.prototype.get=function(t,e){return this.has(t)?this._start+l(this,t)*this._step:e},$.prototype.includes=function(t){var e=(t-this._start)/this._step;return e>=0&&this.size>e&&e===Math.floor(e); -},$.prototype.slice=function(t,e){return d(t,e,this.size)?this:(t=m(t,this.size),e=g(e,this.size),t>=e?new $(0,0):new $(this.get(t,this._end),this.get(e,this._end),this._step))},$.prototype.indexOf=function(t){var e=t-this._start;if(e%this._step===0){var r=e/this._step;if(r>=0&&this.size>r)return r}return-1},$.prototype.lastIndexOf=function(t){return this.indexOf(t)},$.prototype.__iterate=function(t,e){for(var r=this.size-1,n=this._step,i=e?this._start+r*n:this._start,o=0;r>=o;o++){if(t(i,o,this)===!1)return o+1;i+=e?-n:n}return o},$.prototype.__iterator=function(t,e){var r=this.size-1,n=this._step,i=e?this._start+r*n:this._start,o=0;return new S(function(){var u=i;return i+=e?-n:n,o>r?I():z(t,o++,u)})},$.prototype.equals=function(t){return t instanceof $?this._start===t._start&&this._end===t._end&&this._step===t._step:F(this,t)};var Er;t(tt,e),t(et,tt),t(rt,tt),t(nt,tt),tt.Keyed=et,tt.Indexed=rt,tt.Set=nt;var Or,xr="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(t,e){t=0|t,e=0|e;var r=65535&t,n=65535&e;return r*n+((t>>>16)*n+r*(e>>>16)<<16>>>0)|0},kr=Object.isExtensible,Ar=function(){try{return Object.defineProperty({},"@",{}),!0}catch(t){return!1}}(),jr="function"==typeof WeakMap;jr&&(Or=new WeakMap);var Rr=0,Ur="__immutablehash__";"function"==typeof Symbol&&(Ur=Symbol(Ur));var Kr=16,Lr=255,Tr=0,Br={};t(ct,et),ct.of=function(){var t=sr.call(arguments,0);return zt().withMutations(function(e){for(var r=0;t.length>r;r+=2){if(r+1>=t.length)throw Error("Missing value for key: "+t[r]);e.set(t[r],t[r+1])}})},ct.prototype.toString=function(){return this.__toString("Map {","}")},ct.prototype.get=function(t,e){return this._root?this._root.get(0,void 0,t,e):e},ct.prototype.set=function(t,e){return It(this,t,e)},ct.prototype.setIn=function(t,e){return this.updateIn(t,yr,function(){return e})},ct.prototype.remove=function(t){return It(this,t,yr)},ct.prototype.deleteIn=function(t){return this.updateIn(t,function(){return yr})},ct.prototype.update=function(t,e,r){return 1===arguments.length?t(this):this.updateIn([t],e,r); -},ct.prototype.updateIn=function(t,e,r){r||(r=e,e=void 0);var n=Rt(this,ke(t),e,r);return n===yr?void 0:n},ct.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):zt()},ct.prototype.merge=function(){return xt(this,void 0,arguments)},ct.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return xt(this,t,e)},ct.prototype.mergeIn=function(t){var e=sr.call(arguments,1);return this.updateIn(t,zt(),function(t){return"function"==typeof t.merge?t.merge.apply(t,e):e[e.length-1]})},ct.prototype.mergeDeep=function(){return xt(this,kt,arguments)},ct.prototype.mergeDeepWith=function(t){var e=sr.call(arguments,1);return xt(this,At(t),e)},ct.prototype.mergeDeepIn=function(t){var e=sr.call(arguments,1);return this.updateIn(t,zt(),function(t){return"function"==typeof t.mergeDeep?t.mergeDeep.apply(t,e):e[e.length-1]})},ct.prototype.sort=function(t){return Zt(we(this,t))},ct.prototype.sortBy=function(t,e){return Zt(we(this,e,t))},ct.prototype.withMutations=function(t){var e=this.asMutable();return t(e),e.wasAltered()?e.__ensureOwner(this.__ownerID):this},ct.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new _)},ct.prototype.asImmutable=function(){return this.__ensureOwner()},ct.prototype.wasAltered=function(){return this.__altered},ct.prototype.__iterator=function(t,e){return new mt(this,t,e)},ct.prototype.__iterate=function(t,e){var r=this,n=0;return this._root&&this._root.iterate(function(e){return n++,t(e[1],e[0],r)},e),n},ct.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?St(this.size,this._root,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this)},ct.isMap=_t;var Wr="@@__IMMUTABLE_MAP__@@",Cr=ct.prototype;Cr[Wr]=!0,Cr[_r]=Cr.remove,Cr.removeIn=Cr.deleteIn,pt.prototype.get=function(t,e,r,n){for(var i=this.entries,o=0,u=i.length;u>o;o++)if(X(r,i[o][0]))return i[o][1];return n},pt.prototype.update=function(t,e,r,n,i,o,u){for(var s=i===yr,a=this.entries,h=0,f=a.length;f>h&&!X(n,a[h][0]);h++); -var _=f>h;if(_?a[h][1]===i:s)return this;if(c(u),(s||!_)&&c(o),!s||1!==a.length){if(!_&&!s&&a.length>=Nr)return Mt(t,a,n,i);var v=t&&t===this.ownerID,l=v?a:p(a);return _?s?h===f-1?l.pop():l[h]=l.pop():l[h]=[n,i]:l.push([n,i]),v?(this.entries=l,this):new pt(t,l)}},vt.prototype.get=function(t,e,r,n){void 0===e&&(e=ot(r));var i=1<<((0===t?e:e>>>t)&lr),o=this.bitmap;return 0===(o&i)?n:this.nodes[Ut(o&i-1)].get(t+pr,e,r,n)},vt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=(0===e?r:r>>>e)&lr,a=1<<s,h=this.bitmap,f=0!==(h&a);if(!f&&i===yr)return this;var c=Ut(h&a-1),_=this.nodes,p=f?_[c]:void 0,v=bt(p,t,e+pr,r,n,i,o,u);if(v===p)return this;if(!f&&v&&_.length>=Pr)return Ot(t,_,h,s,v);if(f&&!v&&2===_.length&&qt(_[1^c]))return _[1^c];if(f&&v&&1===_.length&&qt(v))return v;var l=t&&t===this.ownerID,y=f?v?h:h^a:h|a,d=f?v?Kt(_,c,v,l):Tt(_,c,l):Lt(_,c,v,l);return l?(this.bitmap=y,this.nodes=d,this):new vt(t,y,d)},lt.prototype.get=function(t,e,r,n){void 0===e&&(e=ot(r));var i=(0===t?e:e>>>t)&lr,o=this.nodes[i];return o?o.get(t+pr,e,r,n):n},lt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=(0===e?r:r>>>e)&lr,a=i===yr,h=this.nodes,f=h[s];if(a&&!f)return this;var c=bt(f,t,e+pr,r,n,i,o,u);if(c===f)return this;var _=this.count;if(f){if(!c&&(_--,Hr>_))return Et(t,h,_,s)}else _++;var p=t&&t===this.ownerID,v=Kt(h,s,c,p);return p?(this.count=_,this.nodes=v,this):new lt(t,_,v)},yt.prototype.get=function(t,e,r,n){for(var i=this.entries,o=0,u=i.length;u>o;o++)if(X(r,i[o][0]))return i[o][1];return n},yt.prototype.update=function(t,e,r,n,i,o,u){void 0===r&&(r=ot(n));var s=i===yr;if(r!==this.keyHash)return s?this:(c(u),c(o),Dt(this,t,e,r,[n,i]));for(var a=this.entries,h=0,f=a.length;f>h&&!X(n,a[h][0]);h++);var _=f>h;if(_?a[h][1]===i:s)return this;if(c(u),(s||!_)&&c(o),s&&2===f)return new dt(t,this.keyHash,a[1^h]);var v=t&&t===this.ownerID,l=v?a:p(a);return _?s?h===f-1?l.pop():l[h]=l.pop():l[h]=[n,i]:l.push([n,i]),v?(this.entries=l,this):new yt(t,this.keyHash,l)},dt.prototype.get=function(t,e,r,n){return X(r,this.entry[0])?this.entry[1]:n; -},dt.prototype.update=function(t,e,r,n,i,o,u){var s=i===yr,a=X(n,this.entry[0]);return(a?i===this.entry[1]:s)?this:(c(u),s?void c(o):a?t&&t===this.ownerID?(this.entry[1]=i,this):new dt(t,this.keyHash,[n,i]):(c(o),Dt(this,t,e,ot(n),[n,i])))},pt.prototype.iterate=yt.prototype.iterate=function(t,e){for(var r=this.entries,n=0,i=r.length-1;i>=n;n++)if(t(r[e?i-n:n])===!1)return!1},vt.prototype.iterate=lt.prototype.iterate=function(t,e){for(var r=this.nodes,n=0,i=r.length-1;i>=n;n++){var o=r[e?i-n:n];if(o&&o.iterate(t,e)===!1)return!1}},dt.prototype.iterate=function(t,e){return t(this.entry)},t(mt,S),mt.prototype.next=function(){for(var t=this._type,e=this._stack;e;){var r,n=e.node,i=e.index++;if(n.entry){if(0===i)return gt(t,n.entry)}else if(n.entries){if(r=n.entries.length-1,r>=i)return gt(t,n.entries[this._reverse?r-i:i])}else if(r=n.nodes.length-1,r>=i){var o=n.nodes[this._reverse?r-i:i];if(o){if(o.entry)return gt(t,o.entry);e=this._stack=wt(o,e)}continue}e=this._stack=this._stack.__prev}return I()};var Jr,Nr=vr/4,Pr=vr/2,Hr=vr/4;t(Bt,rt),Bt.of=function(){return this(arguments)},Bt.prototype.toString=function(){return this.__toString("List [","]")},Bt.prototype.get=function(t,e){if(t=l(this,t),t>=0&&this.size>t){t+=this._origin;var r=Qt(this,t);return r&&r.array[t&lr]}return e},Bt.prototype.set=function(t,e){return Ht(this,t,e)},Bt.prototype.remove=function(t){return this.has(t)?0===t?this.shift():t===this.size-1?this.pop():this.splice(t,1):this},Bt.prototype.insert=function(t,e){return this.splice(t,0,e)},Bt.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=this._origin=this._capacity=0,this._level=pr,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):Pt()},Bt.prototype.push=function(){var t=arguments,e=this.size;return this.withMutations(function(r){Xt(r,0,e+t.length);for(var n=0;t.length>n;n++)r.set(e+n,t[n])})},Bt.prototype.pop=function(){return Xt(this,0,-1)},Bt.prototype.unshift=function(){var t=arguments;return this.withMutations(function(e){Xt(e,-t.length);for(var r=0;t.length>r;r++)e.set(r,t[r]); -})},Bt.prototype.shift=function(){return Xt(this,1)},Bt.prototype.merge=function(){return Ft(this,void 0,arguments)},Bt.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return Ft(this,t,e)},Bt.prototype.mergeDeep=function(){return Ft(this,kt,arguments)},Bt.prototype.mergeDeepWith=function(t){var e=sr.call(arguments,1);return Ft(this,At(t),e)},Bt.prototype.setSize=function(t){return Xt(this,0,t)},Bt.prototype.slice=function(t,e){var r=this.size;return d(t,e,r)?this:Xt(this,m(t,r),g(e,r))},Bt.prototype.__iterator=function(t,e){var r=0,n=Jt(this,e);return new S(function(){var e=n();return e===Xr?I():z(t,r++,e)})},Bt.prototype.__iterate=function(t,e){for(var r,n=0,i=Jt(this,e);(r=i())!==Xr&&t(r,n++,this)!==!1;);return n},Bt.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?Nt(this._origin,this._capacity,this._level,this._root,this._tail,t,this.__hash):(this.__ownerID=t,this)},Bt.isList=Wt;var Vr="@@__IMMUTABLE_LIST__@@",Yr=Bt.prototype;Yr[Vr]=!0,Yr[_r]=Yr.remove,Yr.setIn=Cr.setIn,Yr.deleteIn=Yr.removeIn=Cr.removeIn,Yr.update=Cr.update,Yr.updateIn=Cr.updateIn,Yr.mergeIn=Cr.mergeIn,Yr.mergeDeepIn=Cr.mergeDeepIn,Yr.withMutations=Cr.withMutations,Yr.asMutable=Cr.asMutable,Yr.asImmutable=Cr.asImmutable,Yr.wasAltered=Cr.wasAltered,Ct.prototype.removeBefore=function(t,e,r){if(r===e?1<<e:0===this.array.length)return this;var n=r>>>e&lr;if(n>=this.array.length)return new Ct([],t);var i,o=0===n;if(e>0){var u=this.array[n];if(i=u&&u.removeBefore(t,e-pr,r),i===u&&o)return this}if(o&&!i)return this;var s=Yt(this,t);if(!o)for(var a=0;n>a;a++)s.array[a]=void 0;return i&&(s.array[n]=i),s},Ct.prototype.removeAfter=function(t,e,r){if(r===(e?1<<e:0)||0===this.array.length)return this;var n=r-1>>>e&lr;if(n>=this.array.length)return this;var i;if(e>0){var o=this.array[n];if(i=o&&o.removeAfter(t,e-pr,r),i===o&&n===this.array.length-1)return this}var u=Yt(this,t);return u.array.splice(n+1),i&&(u.array[n]=i),u};var Qr,Xr={};t(Zt,ct),Zt.of=function(){return this(arguments)},Zt.prototype.toString=function(){return this.__toString("OrderedMap {","}"); -},Zt.prototype.get=function(t,e){var r=this._map.get(t);return void 0!==r?this._list.get(r)[1]:e},Zt.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._map.clear(),this._list.clear(),this):ee()},Zt.prototype.set=function(t,e){return re(this,t,e)},Zt.prototype.remove=function(t){return re(this,t,yr)},Zt.prototype.wasAltered=function(){return this._map.wasAltered()||this._list.wasAltered()},Zt.prototype.__iterate=function(t,e){var r=this;return this._list.__iterate(function(e){return e&&t(e[1],e[0],r)},e)},Zt.prototype.__iterator=function(t,e){return this._list.fromEntrySeq().__iterator(t,e)},Zt.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t),r=this._list.__ensureOwner(t);return t?te(e,r,t,this.__hash):(this.__ownerID=t,this._map=e,this._list=r,this)},Zt.isOrderedMap=$t,Zt.prototype[cr]=!0,Zt.prototype[_r]=Zt.prototype.remove;var Fr;t(ne,x),ne.prototype.get=function(t,e){return this._iter.get(t,e)},ne.prototype.has=function(t){return this._iter.has(t)},ne.prototype.valueSeq=function(){return this._iter.valueSeq()},ne.prototype.reverse=function(){var t=this,e=he(this,!0);return this._useKeys||(e.valueSeq=function(){return t._iter.toSeq().reverse()}),e},ne.prototype.map=function(t,e){var r=this,n=ae(this,t,e);return this._useKeys||(n.valueSeq=function(){return r._iter.toSeq().map(t,e)}),n},ne.prototype.__iterate=function(t,e){var r,n=this;return this._iter.__iterate(this._useKeys?function(e,r){return t(e,r,n)}:(r=e?De(this):0,function(i){return t(i,e?--r:r++,n)}),e)},ne.prototype.__iterator=function(t,e){if(this._useKeys)return this._iter.__iterator(t,e);var r=this._iter.__iterator(wr,e),n=e?De(this):0;return new S(function(){var i=r.next();return i.done?i:z(t,e?--n:n++,i.value,i)})},ne.prototype[cr]=!0,t(ie,k),ie.prototype.includes=function(t){return this._iter.includes(t)},ie.prototype.__iterate=function(t,e){var r=this,n=0;return this._iter.__iterate(function(e){return t(e,n++,r)},e)},ie.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e),n=0; -return new S(function(){var e=r.next();return e.done?e:z(t,n++,e.value,e)})},t(oe,A),oe.prototype.has=function(t){return this._iter.includes(t)},oe.prototype.__iterate=function(t,e){var r=this;return this._iter.__iterate(function(e){return t(e,e,r)},e)},oe.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e);return new S(function(){var e=r.next();return e.done?e:z(t,e.value,e.value,e)})},t(ue,x),ue.prototype.entrySeq=function(){return this._iter.toSeq()},ue.prototype.__iterate=function(t,e){var r=this;return this._iter.__iterate(function(e){if(e){qe(e);var n=o(e);return t(n?e.get(1):e[1],n?e.get(0):e[0],r)}},e)},ue.prototype.__iterator=function(t,e){var r=this._iter.__iterator(wr,e);return new S(function(){for(;;){var e=r.next();if(e.done)return e;var n=e.value;if(n){qe(n);var i=o(n);return z(t,i?n.get(0):n[0],i?n.get(1):n[1],e)}}})},ie.prototype.cacheResult=ne.prototype.cacheResult=oe.prototype.cacheResult=ue.prototype.cacheResult=Oe,t(Ae,et),Ae.prototype.toString=function(){return this.__toString(Re(this)+" {","}")},Ae.prototype.has=function(t){return this._defaultValues.hasOwnProperty(t)},Ae.prototype.get=function(t,e){if(!this.has(t))return e;var r=this._defaultValues[t];return this._map?this._map.get(t,r):r},Ae.prototype.clear=function(){if(this.__ownerID)return this._map&&this._map.clear(),this;var t=this.constructor;return t._empty||(t._empty=je(this,zt()))},Ae.prototype.set=function(t,e){if(!this.has(t))throw Error('Cannot set unknown key "'+t+'" on '+Re(this));if(this._map&&!this._map.has(t)){var r=this._defaultValues[t];if(e===r)return this}var n=this._map&&this._map.set(t,e);return this.__ownerID||n===this._map?this:je(this,n)},Ae.prototype.remove=function(t){if(!this.has(t))return this;var e=this._map&&this._map.remove(t);return this.__ownerID||e===this._map?this:je(this,e)},Ae.prototype.wasAltered=function(){return this._map.wasAltered()},Ae.prototype.__iterator=function(t,e){var n=this;return r(this._defaultValues).map(function(t,e){return n.get(e)}).__iterator(t,e)},Ae.prototype.__iterate=function(t,e){ -var n=this;return r(this._defaultValues).map(function(t,e){return n.get(e)}).__iterate(t,e)},Ae.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map&&this._map.__ensureOwner(t);return t?je(this,e,t):(this.__ownerID=t,this._map=e,this)};var Gr=Ae.prototype;Gr[_r]=Gr.remove,Gr.deleteIn=Gr.removeIn=Cr.removeIn,Gr.merge=Cr.merge,Gr.mergeWith=Cr.mergeWith,Gr.mergeIn=Cr.mergeIn,Gr.mergeDeep=Cr.mergeDeep,Gr.mergeDeepWith=Cr.mergeDeepWith,Gr.mergeDeepIn=Cr.mergeDeepIn,Gr.setIn=Cr.setIn,Gr.update=Cr.update,Gr.updateIn=Cr.updateIn,Gr.withMutations=Cr.withMutations,Gr.asMutable=Cr.asMutable,Gr.asImmutable=Cr.asImmutable,t(Le,nt),Le.of=function(){return this(arguments)},Le.fromKeys=function(t){return this(r(t).keySeq())},Le.prototype.toString=function(){return this.__toString("Set {","}")},Le.prototype.has=function(t){return this._map.has(t)},Le.prototype.add=function(t){return Be(this,this._map.set(t,!0))},Le.prototype.remove=function(t){return Be(this,this._map.remove(t))},Le.prototype.clear=function(){return Be(this,this._map.clear())},Le.prototype.union=function(){var t=sr.call(arguments,0);return t=t.filter(function(t){return 0!==t.size}),0===t.length?this:0!==this.size||this.__ownerID||1!==t.length?this.withMutations(function(e){for(var r=0;t.length>r;r++)i(t[r]).forEach(function(t){return e.add(t)})}):this.constructor(t[0])},Le.prototype.intersect=function(){var t=sr.call(arguments,0);if(0===t.length)return this;t=t.map(function(t){return i(t)});var e=this;return this.withMutations(function(r){e.forEach(function(e){t.every(function(t){return t.includes(e)})||r.remove(e)})})},Le.prototype.subtract=function(){var t=sr.call(arguments,0);if(0===t.length)return this;t=t.map(function(t){return i(t)});var e=this;return this.withMutations(function(r){e.forEach(function(e){t.some(function(t){return t.includes(e)})&&r.remove(e)})})},Le.prototype.merge=function(){return this.union.apply(this,arguments)},Le.prototype.mergeWith=function(t){var e=sr.call(arguments,1);return this.union.apply(this,e)}, -Le.prototype.sort=function(t){return Je(we(this,t))},Le.prototype.sortBy=function(t,e){return Je(we(this,e,t))},Le.prototype.wasAltered=function(){return this._map.wasAltered()},Le.prototype.__iterate=function(t,e){var r=this;return this._map.__iterate(function(e,n){return t(n,n,r)},e)},Le.prototype.__iterator=function(t,e){return this._map.map(function(t,e){return e}).__iterator(t,e)},Le.prototype.__ensureOwner=function(t){if(t===this.__ownerID)return this;var e=this._map.__ensureOwner(t);return t?this.__make(e,t):(this.__ownerID=t,this._map=e,this)},Le.isSet=Te;var Zr="@@__IMMUTABLE_SET__@@",$r=Le.prototype;$r[Zr]=!0,$r[_r]=$r.remove,$r.mergeDeep=$r.merge,$r.mergeDeepWith=$r.mergeWith,$r.withMutations=Cr.withMutations,$r.asMutable=Cr.asMutable,$r.asImmutable=Cr.asImmutable,$r.__empty=Ce,$r.__make=We;var tn;t(Je,Le),Je.of=function(){return this(arguments)},Je.fromKeys=function(t){return this(r(t).keySeq())},Je.prototype.toString=function(){return this.__toString("OrderedSet {","}")},Je.isOrderedSet=Ne;var en=Je.prototype;en[cr]=!0,en.__empty=He,en.__make=Pe;var rn;t(Ve,rt),Ve.of=function(){return this(arguments)},Ve.prototype.toString=function(){return this.__toString("Stack [","]")},Ve.prototype.get=function(t,e){var r=this._head;for(t=l(this,t);r&&t--;)r=r.next;return r?r.value:e},Ve.prototype.peek=function(){return this._head&&this._head.value},Ve.prototype.push=function(){if(0===arguments.length)return this;for(var t=this.size+arguments.length,e=this._head,r=arguments.length-1;r>=0;r--)e={value:arguments[r],next:e};return this.__ownerID?(this.size=t,this._head=e,this.__hash=void 0,this.__altered=!0,this):Qe(t,e)},Ve.prototype.pushAll=function(t){if(t=n(t),0===t.size)return this;ft(t.size);var e=this.size,r=this._head;return t.reverse().forEach(function(t){e++,r={value:t,next:r}}),this.__ownerID?(this.size=e,this._head=r,this.__hash=void 0,this.__altered=!0,this):Qe(e,r)},Ve.prototype.pop=function(){return this.slice(1)},Ve.prototype.unshift=function(){return this.push.apply(this,arguments)},Ve.prototype.unshiftAll=function(t){ -return this.pushAll(t)},Ve.prototype.shift=function(){return this.pop.apply(this,arguments)},Ve.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Xe()},Ve.prototype.slice=function(t,e){if(d(t,e,this.size))return this;var r=m(t,this.size),n=g(e,this.size);if(n!==this.size)return rt.prototype.slice.call(this,t,e);for(var i=this.size-r,o=this._head;r--;)o=o.next;return this.__ownerID?(this.size=i,this._head=o,this.__hash=void 0,this.__altered=!0,this):Qe(i,o)},Ve.prototype.__ensureOwner=function(t){return t===this.__ownerID?this:t?Qe(this.size,this._head,t,this.__hash):(this.__ownerID=t,this.__altered=!1,this)},Ve.prototype.__iterate=function(t,e){if(e)return this.reverse().__iterate(t);for(var r=0,n=this._head;n&&t(n.value,r++,this)!==!1;)n=n.next;return r},Ve.prototype.__iterator=function(t,e){if(e)return this.reverse().__iterator(t);var r=0,n=this._head;return new S(function(){if(n){var e=n.value;return n=n.next,z(t,r++,e)}return I()})},Ve.isStack=Ye;var nn="@@__IMMUTABLE_STACK__@@",on=Ve.prototype;on[nn]=!0,on.withMutations=Cr.withMutations,on.asMutable=Cr.asMutable,on.asImmutable=Cr.asImmutable,on.wasAltered=Cr.wasAltered;var un;e.Iterator=S,Fe(e,{toArray:function(){ft(this.size);var t=Array(this.size||0);return this.valueSeq().__iterate(function(e,r){t[r]=e}),t},toIndexedSeq:function(){return new ie(this)},toJS:function(){return this.toSeq().map(function(t){return t&&"function"==typeof t.toJS?t.toJS():t}).__toJS()},toJSON:function(){return this.toSeq().map(function(t){return t&&"function"==typeof t.toJSON?t.toJSON():t}).__toJS()},toKeyedSeq:function(){return new ne(this,!0)},toMap:function(){return ct(this.toKeyedSeq())},toObject:function(){ft(this.size);var t={};return this.__iterate(function(e,r){t[r]=e}),t},toOrderedMap:function(){return Zt(this.toKeyedSeq())},toOrderedSet:function(){return Je(u(this)?this.valueSeq():this)},toSet:function(){return Le(u(this)?this.valueSeq():this)},toSetSeq:function(){return new oe(this); -},toSeq:function(){return s(this)?this.toIndexedSeq():u(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return Ve(u(this)?this.valueSeq():this)},toList:function(){return Bt(u(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(t,e){return 0===this.size?t+e:t+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+e},concat:function(){var t=sr.call(arguments,0);return be(this,ye(this,t))},includes:function(t){return this.some(function(e){return X(e,t)})},entries:function(){return this.__iterator(Sr)},every:function(t,e){ft(this.size);var r=!0;return this.__iterate(function(n,i,o){return t.call(e,n,i,o)?void 0:(r=!1,!1)}),r},filter:function(t,e){return be(this,fe(this,t,e,!0))},find:function(t,e,r){var n=this.findEntry(t,e);return n?n[1]:r},forEach:function(t,e){return ft(this.size),this.__iterate(e?t.bind(e):t)},join:function(t){ft(this.size),t=void 0!==t?""+t:",";var e="",r=!0;return this.__iterate(function(n){r?r=!1:e+=t,e+=null!==n&&void 0!==n?""+n:""}),e},keys:function(){return this.__iterator(gr)},map:function(t,e){return be(this,ae(this,t,e))},reduce:function(t,e,r){ft(this.size);var n,i;return arguments.length<2?i=!0:n=e,this.__iterate(function(e,o,u){i?(i=!1,n=e):n=t.call(r,n,e,o,u)}),n},reduceRight:function(t,e,r){var n=this.toKeyedSeq().reverse();return n.reduce.apply(n,arguments)},reverse:function(){return be(this,he(this,!0))},slice:function(t,e){return be(this,pe(this,t,e,!0))},some:function(t,e){return!this.every($e(t),e)},sort:function(t){return be(this,we(this,t))},values:function(){return this.__iterator(wr)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some(function(){return!0})},count:function(t,e){return v(t?this.toSeq().filter(t,e):this)},countBy:function(t,e){return ce(this,t,e)},equals:function(t){return F(this,t)},entrySeq:function(){var t=this;if(t._cache)return new j(t._cache);var e=t.toSeq().map(Ze).toIndexedSeq();return e.fromEntrySeq=function(){return t.toSeq()},e},filterNot:function(t,e){ -return this.filter($e(t),e)},findEntry:function(t,e,r){var n=r;return this.__iterate(function(r,i,o){return t.call(e,r,i,o)?(n=[i,r],!1):void 0}),n},findKey:function(t,e){var r=this.findEntry(t,e);return r&&r[0]},findLast:function(t,e,r){return this.toKeyedSeq().reverse().find(t,e,r)},findLastEntry:function(t,e,r){return this.toKeyedSeq().reverse().findEntry(t,e,r)},findLastKey:function(t,e){return this.toKeyedSeq().reverse().findKey(t,e)},first:function(){return this.find(y)},flatMap:function(t,e){return be(this,me(this,t,e))},flatten:function(t){return be(this,de(this,t,!0))},fromEntrySeq:function(){return new ue(this)},get:function(t,e){return this.find(function(e,r){return X(r,t)},void 0,e)},getIn:function(t,e){for(var r,n=this,i=ke(t);!(r=i.next()).done;){var o=r.value;if(n=n&&n.get?n.get(o,yr):yr,n===yr)return e}return n},groupBy:function(t,e){return _e(this,t,e)},has:function(t){return this.get(t,yr)!==yr},hasIn:function(t){return this.getIn(t,yr)!==yr},isSubset:function(t){return t="function"==typeof t.includes?t:e(t),this.every(function(e){return t.includes(e)})},isSuperset:function(t){return t="function"==typeof t.isSubset?t:e(t),t.isSubset(this)},keyOf:function(t){return this.findKey(function(e){return X(e,t)})},keySeq:function(){return this.toSeq().map(Ge).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(t){return this.toKeyedSeq().reverse().keyOf(t)},max:function(t){return Se(this,t)},maxBy:function(t,e){return Se(this,e,t)},min:function(t){return Se(this,t?tr(t):nr)},minBy:function(t,e){return Se(this,e?tr(e):nr,t)},rest:function(){return this.slice(1)},skip:function(t){return this.slice(Math.max(0,t))},skipLast:function(t){return be(this,this.toSeq().reverse().skip(t).reverse())},skipWhile:function(t,e){return be(this,le(this,t,e,!0))},skipUntil:function(t,e){return this.skipWhile($e(t),e)},sortBy:function(t,e){return be(this,we(this,e,t))},take:function(t){return this.slice(0,Math.max(0,t))},takeLast:function(t){return be(this,this.toSeq().reverse().take(t).reverse()); -},takeWhile:function(t,e){return be(this,ve(this,t,e))},takeUntil:function(t,e){return this.takeWhile($e(t),e)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=ir(this))}});var sn=e.prototype;sn[ar]=!0,sn[br]=sn.values,sn.__toJS=sn.toArray,sn.__toStringMapper=er,sn.inspect=sn.toSource=function(){return""+this},sn.chain=sn.flatMap,sn.contains=sn.includes,Fe(r,{flip:function(){return be(this,se(this))},mapEntries:function(t,e){var r=this,n=0;return be(this,this.toSeq().map(function(i,o){return t.call(e,[o,i],n++,r)}).fromEntrySeq())},mapKeys:function(t,e){var r=this;return be(this,this.toSeq().flip().map(function(n,i){return t.call(e,n,i,r)}).flip())}});var an=r.prototype;an[hr]=!0,an[br]=sn.entries,an.__toJS=sn.toObject,an.__toStringMapper=function(t,e){return JSON.stringify(e)+": "+er(t)},Fe(n,{toKeyedSeq:function(){return new ne(this,!1)},filter:function(t,e){return be(this,fe(this,t,e,!1))},findIndex:function(t,e){var r=this.findEntry(t,e);return r?r[0]:-1},indexOf:function(t){var e=this.keyOf(t);return void 0===e?-1:e},lastIndexOf:function(t){var e=this.lastKeyOf(t);return void 0===e?-1:e},reverse:function(){return be(this,he(this,!1))},slice:function(t,e){return be(this,pe(this,t,e,!1))},splice:function(t,e){var r=arguments.length;if(e=Math.max(0|e,0),0===r||2===r&&!e)return this;t=m(t,0>t?this.count():this.size);var n=this.slice(0,t);return be(this,1===r?n:n.concat(p(arguments,2),this.slice(t+e)))},findLastIndex:function(t,e){var r=this.findLastEntry(t,e);return r?r[0]:-1},first:function(){return this.get(0)},flatten:function(t){return be(this,de(this,t,!1))},get:function(t,e){return t=l(this,t),0>t||this.size===1/0||void 0!==this.size&&t>this.size?e:this.find(function(e,r){return r===t},void 0,e)},has:function(t){return t=l(this,t),t>=0&&(void 0!==this.size?this.size===1/0||this.size>t:-1!==this.indexOf(t))},interpose:function(t){return be(this,ge(this,t))},interleave:function(){var t=[this].concat(p(arguments)),e=Ie(this.toSeq(),k.of,t),r=e.flatten(!0);return e.size&&(r.size=e.size*t.length), -be(this,r)},keySeq:function(){return $(0,this.size)},last:function(){return this.get(-1)},skipWhile:function(t,e){return be(this,le(this,t,e,!1))},zip:function(){var t=[this].concat(p(arguments));return be(this,Ie(this,rr,t))},zipWith:function(t){var e=p(arguments);return e[0]=this,be(this,Ie(this,t,e))}}),n.prototype[fr]=!0,n.prototype[cr]=!0,Fe(i,{get:function(t,e){return this.has(t)?t:e},includes:function(t){return this.has(t)},keySeq:function(){return this.valueSeq()}}),i.prototype.has=sn.includes,i.prototype.contains=i.prototype.includes,Fe(x,r.prototype),Fe(k,n.prototype),Fe(A,i.prototype),Fe(et,r.prototype),Fe(rt,n.prototype),Fe(nt,i.prototype);var hn={Iterable:e,Seq:O,Collection:tt,Map:ct,OrderedMap:Zt,List:Bt,Stack:Ve,Set:Le,OrderedSet:Je,Record:Ae,Range:$,Repeat:G,is:X,fromJS:H};return hn}); \ No newline at end of file diff --git a/third_party/immer/extra/js/lib/lodash.js b/third_party/immer/extra/js/lib/lodash.js deleted file mode 100644 index 22e73749bda6..000000000000 --- a/third_party/immer/extra/js/lib/lodash.js +++ /dev/null @@ -1,16607 +0,0 @@ -/** - * @license - * lodash <https://lodash.com/> - * Copyright jQuery Foundation and other contributors <https://jquery.org/> - * Released under MIT license <https://lodash.com/license> - * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> - * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - */ -;(function() { - - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; - - /** Used as the semantic version number. */ - var VERSION = '4.14.1'; - - /** Used as the size to enable large array optimizations. */ - var LARGE_ARRAY_SIZE = 200; - - /** Used as the `TypeError` message for "Functions" methods. */ - var FUNC_ERROR_TEXT = 'Expected a function'; - - /** Used to stand-in for `undefined` hash values. */ - var HASH_UNDEFINED = '__lodash_hash_undefined__'; - - /** Used as the internal argument placeholder. */ - var PLACEHOLDER = '__lodash_placeholder__'; - - /** Used to compose bitmasks for function metadata. */ - var BIND_FLAG = 1, - BIND_KEY_FLAG = 2, - CURRY_BOUND_FLAG = 4, - CURRY_FLAG = 8, - CURRY_RIGHT_FLAG = 16, - PARTIAL_FLAG = 32, - PARTIAL_RIGHT_FLAG = 64, - ARY_FLAG = 128, - REARG_FLAG = 256, - FLIP_FLAG = 512; - - /** Used to compose bitmasks for comparison styles. */ - var UNORDERED_COMPARE_FLAG = 1, - PARTIAL_COMPARE_FLAG = 2; - - /** Used as default options for `_.truncate`. */ - var DEFAULT_TRUNC_LENGTH = 30, - DEFAULT_TRUNC_OMISSION = '...'; - - /** Used to detect hot functions by number of calls within a span of milliseconds. */ - var HOT_COUNT = 150, - HOT_SPAN = 16; - - /** Used to indicate the type of lazy iteratees. */ - var LAZY_FILTER_FLAG = 1, - LAZY_MAP_FLAG = 2, - LAZY_WHILE_FLAG = 3; - - /** Used as references for various `Number` constants. */ - var INFINITY = 1 / 0, - MAX_SAFE_INTEGER = 9007199254740991, - MAX_INTEGER = 1.7976931348623157e+308, - NAN = 0 / 0; - - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = 4294967295, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - - /** Used to associate wrap methods with their bit flags. */ - var wrapFlags = [ - ['ary', ARY_FLAG], - ['bind', BIND_FLAG], - ['bindKey', BIND_KEY_FLAG], - ['curry', CURRY_FLAG], - ['curryRight', CURRY_RIGHT_FLAG], - ['flip', FLIP_FLAG], - ['partial', PARTIAL_FLAG], - ['partialRight', PARTIAL_RIGHT_FLAG], - ['rearg', REARG_FLAG] - ]; - - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - genTag = '[object GeneratorFunction]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - promiseTag = '[object Promise]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - symbolTag = '[object Symbol]', - weakMapTag = '[object WeakMap]', - weakSetTag = '[object WeakSet]'; - - var arrayBufferTag = '[object ArrayBuffer]', - dataViewTag = '[object DataView]', - float32Tag = '[object Float32Array]', - float64Tag = '[object Float64Array]', - int8Tag = '[object Int8Array]', - int16Tag = '[object Int16Array]', - int32Tag = '[object Int32Array]', - uint8Tag = '[object Uint8Array]', - uint8ClampedTag = '[object Uint8ClampedArray]', - uint16Tag = '[object Uint16Array]', - uint32Tag = '[object Uint32Array]'; - - /** Used to match empty string literals in compiled template source. */ - var reEmptyStringLeading = /\b__p \+= '';/g, - reEmptyStringMiddle = /\b(__p \+=) '' \+/g, - reEmptyStringTrailing = /(__e\(.*?\)|\b__t\)) \+\n'';/g; - - /** Used to match HTML entities and HTML characters. */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, - reUnescapedHtml = /[&<>"'`]/g, - reHasEscapedHtml = RegExp(reEscapedHtml.source), - reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - - /** Used to match template delimiters. */ - var reEscape = /<%-([\s\S]+?)%>/g, - reEvaluate = /<%([\s\S]+?)%>/g, - reInterpolate = /<%=([\s\S]+?)%>/g; - - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/, - reIsPlainProp = /^\w*$/, - reLeadingDot = /^\./, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; - - /** - * Used to match `RegExp` - * [syntax characters](http://ecma-international.org/ecma-262/6.0/#sec-patterns). - */ - var reRegExpChar = /[\\^$.*+?()[\]{}|]/g, - reHasRegExpChar = RegExp(reRegExpChar.source); - - /** Used to match leading and trailing whitespace. */ - var reTrim = /^\s+|\s+$/g, - reTrimStart = /^\s+/, - reTrimEnd = /\s+$/; - - /** Used to match wrap detail comments. */ - var reWrapComment = /\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/, - reWrapDetails = /\{\n\/\* \[wrapped with (.+)\] \*/, - reSplitDetails = /,? & /; - - /** Used to match non-compound words composed of alphanumeric characters. */ - var reBasicWord = /[a-zA-Z0-9]+/g; - - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; - - /** - * Used to match - * [ES template delimiters](http://ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components). - */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; - - /** Used to match `RegExp` flags from their coerced string values. */ - var reFlags = /\w*$/; - - /** Used to detect hexadecimal string values. */ - var reHasHexPrefix = /^0x/i; - - /** Used to detect bad signed hexadecimal string values. */ - var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; - - /** Used to detect binary string values. */ - var reIsBinary = /^0b[01]+$/i; - - /** Used to detect host constructors (Safari). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; - - /** Used to detect octal string values. */ - var reIsOctal = /^0o[0-7]+$/i; - - /** Used to detect unsigned integer values. */ - var reIsUint = /^(?:0|[1-9]\d*)$/; - - /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ - var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; - - /** Used to ensure capturing order of template delimiters. */ - var reNoMatch = /($^)/; - - /** Used to match unescaped characters in compiled string literals. */ - var reUnescapedString = /['\n\r\u2028\u2029\\]/g; - - /** Used to compose unicode character classes. */ - var rsAstralRange = '\\ud800-\\udfff', - rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23', - rsComboSymbolsRange = '\\u20d0-\\u20f0', - rsDingbatRange = '\\u2700-\\u27bf', - rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff', - rsMathOpRange = '\\xac\\xb1\\xd7\\xf7', - rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf', - rsPunctuationRange = '\\u2000-\\u206f', - rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000', - rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde', - rsVarRange = '\\ufe0e\\ufe0f', - rsBreakRange = rsMathOpRange + rsNonCharRange + rsPunctuationRange + rsSpaceRange; - - /** Used to compose unicode capture groups. */ - var rsApos = "['\u2019]", - rsAstral = '[' + rsAstralRange + ']', - rsBreak = '[' + rsBreakRange + ']', - rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']', - rsDigits = '\\d+', - rsDingbat = '[' + rsDingbatRange + ']', - rsLower = '[' + rsLowerRange + ']', - rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']', - rsFitz = '\\ud83c[\\udffb-\\udfff]', - rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')', - rsNonAstral = '[^' + rsAstralRange + ']', - rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}', - rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]', - rsUpper = '[' + rsUpperRange + ']', - rsZWJ = '\\u200d'; - - /** Used to compose unicode regexes. */ - var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')', - rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')', - rsOptLowerContr = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', - rsOptUpperContr = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', - reOptMod = rsModifier + '?', - rsOptVar = '[' + rsVarRange + ']?', - rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', - rsSeq = rsOptVar + reOptMod + rsOptJoin, - rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq, - rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - - /** Used to match apostrophes. */ - var reApos = RegExp(rsApos, 'g'); - - /** - * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and - * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). - */ - var reComboMark = RegExp(rsCombo, 'g'); - - /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ - var reComplexSymbol = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - - /** Used to match complex or compound words. */ - var reComplexWord = RegExp([ - rsUpper + '?' + rsLower + '+' + rsOptLowerContr + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', - rsUpperMisc + '+' + rsOptUpperContr + '(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')', - rsUpper + '?' + rsLowerMisc + '+' + rsOptLowerContr, - rsUpper + '+' + rsOptUpperContr, - rsDigits, - rsEmoji - ].join('|'), 'g'); - - /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ - var reHasComplexSymbol = RegExp('[' + rsZWJ + rsAstralRange + rsComboMarksRange + rsComboSymbolsRange + rsVarRange + ']'); - - /** Used to detect strings that need a more robust regexp to match words. */ - var reHasComplexWord = /[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/; - - /** Used to assign default `context` object properties. */ - var contextProps = [ - 'Array', 'Buffer', 'DataView', 'Date', 'Error', 'Float32Array', 'Float64Array', - 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Map', 'Math', 'Object', - 'Promise', 'Reflect', 'RegExp', 'Set', 'String', 'Symbol', 'TypeError', - 'Uint8Array', 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', - '_', 'clearTimeout', 'isFinite', 'parseInt', 'setTimeout' - ]; - - /** Used to make template sourceURLs easier to identify. */ - var templateCounter = -1; - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = - typedArrayTags[errorTag] = typedArrayTags[funcTag] = - typedArrayTags[mapTag] = typedArrayTags[numberTag] = - typedArrayTags[objectTag] = typedArrayTags[regexpTag] = - typedArrayTags[setTag] = typedArrayTags[stringTag] = - typedArrayTags[weakMapTag] = false; - - /** Used to identify `toStringTag` values supported by `_.clone`. */ - var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = - cloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] = - cloneableTags[boolTag] = cloneableTags[dateTag] = - cloneableTags[float32Tag] = cloneableTags[float64Tag] = - cloneableTags[int8Tag] = cloneableTags[int16Tag] = - cloneableTags[int32Tag] = cloneableTags[mapTag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[setTag] = - cloneableTags[stringTag] = cloneableTags[symbolTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[weakMapTag] = false; - - /** Used to map latin-1 supplementary letters to basic latin letters. */ - var deburredLetters = { - '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', - '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', - '\xc7': 'C', '\xe7': 'c', - '\xd0': 'D', '\xf0': 'd', - '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', - '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', - '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', - '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', - '\xd1': 'N', '\xf1': 'n', - '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', - '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', - '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', - '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', - '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', - '\xc6': 'Ae', '\xe6': 'ae', - '\xde': 'Th', '\xfe': 'th', - '\xdf': 'ss' - }; - - /** Used to map characters to HTML entities. */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; - - /** Used to map HTML entities to characters. */ - var htmlUnescapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'", - '`': '`' - }; - - /** Used to escape characters for inclusion in compiled string literals. */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; - - /** Built-in method references without a dependency on `root`. */ - var freeParseFloat = parseFloat, - freeParseInt = parseInt; - - /** Detect free variable `global` from Node.js. */ - var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - - /** Detect free variable `self`. */ - var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - - /** Used as a reference to the global object. */ - var root = freeGlobal || freeSelf || Function('return this')(); - - /** Detect free variable `exports`. */ - var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; - - /** Detect free variable `process` from Node.js. */ - var freeProcess = moduleExports && freeGlobal.process; - - /** Used to access faster Node.js helpers. */ - var nodeUtil = (function() { - try { - return freeProcess && freeProcess.binding('util'); - } catch (e) {} - }()); - - /* Node.js helper references. */ - var nodeIsArrayBuffer = nodeUtil && nodeUtil.isArrayBuffer, - nodeIsDate = nodeUtil && nodeUtil.isDate, - nodeIsMap = nodeUtil && nodeUtil.isMap, - nodeIsRegExp = nodeUtil && nodeUtil.isRegExp, - nodeIsSet = nodeUtil && nodeUtil.isSet, - nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - - /*--------------------------------------------------------------------------*/ - - /** - * Adds the key-value `pair` to `map`. - * - * @private - * @param {Object} map The map to modify. - * @param {Array} pair The key-value pair to add. - * @returns {Object} Returns `map`. - */ - function addMapEntry(map, pair) { - // Don't return `map.set` because it's not chainable in IE 11. - map.set(pair[0], pair[1]); - return map; - } - - /** - * Adds `value` to `set`. - * - * @private - * @param {Object} set The set to modify. - * @param {*} value The value to add. - * @returns {Object} Returns `set`. - */ - function addSetEntry(set, value) { - // Don't return `set.add` because it's not chainable in IE 11. - set.add(value); - return set; - } - - /** - * A faster alternative to `Function#apply`, this function invokes `func` - * with the `this` binding of `thisArg` and the arguments of `args`. - * - * @private - * @param {Function} func The function to invoke. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} args The arguments to invoke `func` with. - * @returns {*} Returns the result of `func`. - */ - function apply(func, thisArg, args) { - switch (args.length) { - case 0: return func.call(thisArg); - case 1: return func.call(thisArg, args[0]); - case 2: return func.call(thisArg, args[0], args[1]); - case 3: return func.call(thisArg, args[0], args[1], args[2]); - } - return func.apply(thisArg, args); - } - - /** - * A specialized version of `baseAggregator` for arrays. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function arrayAggregator(array, setter, iteratee, accumulator) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - var value = array[index]; - setter(accumulator, value, iteratee(value), array); - } - return accumulator; - } - - /** - * A specialized version of `_.forEach` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.forEachRight` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEachRight(array, iteratee) { - var length = array ? array.length : 0; - - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; - } - } - return array; - } - - /** - * A specialized version of `_.every` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - */ - function arrayEvery(array, predicate) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } - } - return true; - } - - /** - * A specialized version of `_.filter` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function arrayFilter(array, predicate) { - var index = -1, - length = array ? array.length : 0, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * A specialized version of `_.includes` for arrays without support for - * specifying an index to search from. - * - * @private - * @param {Array} [array] The array to search. - * @param {*} target The value to search for. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludes(array, value) { - var length = array ? array.length : 0; - return !!length && baseIndexOf(array, value, 0) > -1; - } - - /** - * This function is like `arrayIncludes` except that it accepts a comparator. - * - * @private - * @param {Array} [array] The array to search. - * @param {*} target The value to search for. - * @param {Function} comparator The comparator invoked per element. - * @returns {boolean} Returns `true` if `target` is found, else `false`. - */ - function arrayIncludesWith(array, value, comparator) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (comparator(value, array[index])) { - return true; - } - } - return false; - } - - /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array ? array.length : 0, - result = Array(length); - - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } - - /** - * Appends the elements of `values` to `array`. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to append. - * @returns {Array} Returns `array`. - */ - function arrayPush(array, values) { - var index = -1, - length = values.length, - offset = array.length; - - while (++index < length) { - array[offset + index] = values[index]; - } - return array; - } - - /** - * A specialized version of `_.reduce` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the first element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduce(array, iteratee, accumulator, initAccum) { - var index = -1, - length = array ? array.length : 0; - - if (initAccum && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; - } - - /** - * A specialized version of `_.reduceRight` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initAccum] Specify using the last element of `array` as - * the initial value. - * @returns {*} Returns the accumulated value. - */ - function arrayReduceRight(array, iteratee, accumulator, initAccum) { - var length = array ? array.length : 0; - if (initAccum && length) { - accumulator = array[--length]; - } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); - } - return accumulator; - } - - /** - * A specialized version of `_.some` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function arraySome(array, predicate) { - var index = -1, - length = array ? array.length : 0; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; - } - - /** - * The base implementation of methods like `_.findKey` and `_.findLastKey`, - * without support for iteratee shorthands, which iterates over `collection` - * using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to search. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the found element or its key, else `undefined`. - */ - function baseFindKey(collection, predicate, eachFunc) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = key; - return false; - } - }); - return result; - } - - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to search. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - if (value !== value) { - return baseFindIndex(array, baseIsNaN, fromIndex); - } - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * This function is like `baseIndexOf` except that it accepts a comparator. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @param {Function} comparator The comparator invoked per element. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOfWith(array, value, fromIndex, comparator) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (comparator(array[index], value)) { - return index; - } - } - return -1; - } - - /** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ - function baseIsNaN(value) { - return value !== value; - } - - /** - * The base implementation of `_.mean` and `_.meanBy` without support for - * iteratee shorthands. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the mean. - */ - function baseMean(array, iteratee) { - var length = array ? array.length : 0; - return length ? (baseSum(array, iteratee) / length) : NAN; - } - - /** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; - } - - /** - * The base implementation of `_.propertyOf` without support for deep paths. - * - * @private - * @param {Object} object The object to query. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyOf(object) { - return function(key) { - return object == null ? undefined : object[key]; - }; - } - - /** - * The base implementation of `_.reduce` and `_.reduceRight`, without support - * for iteratee shorthands, which iterates over `collection` using `eachFunc`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initAccum Specify using the first or last element of - * `collection` as the initial value. - * @param {Function} eachFunc The function to iterate over `collection`. - * @returns {*} Returns the accumulated value. - */ - function baseReduce(collection, iteratee, accumulator, initAccum, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initAccum - ? (initAccum = false, value) - : iteratee(accumulator, value, index, collection); - }); - return accumulator; - } - - /** - * The base implementation of `_.sortBy` which uses `comparer` to define the - * sort order of `array` and replaces criteria objects with their corresponding - * values. - * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. - */ - function baseSortBy(array, comparer) { - var length = array.length; - - array.sort(comparer); - while (length--) { - array[length] = array[length].value; - } - return array; - } - - /** - * The base implementation of `_.sum` and `_.sumBy` without support for - * iteratee shorthands. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. - */ - function baseSum(array, iteratee) { - var result, - index = -1, - length = array.length; - - while (++index < length) { - var current = iteratee(array[index]); - if (current !== undefined) { - result = result === undefined ? current : (result + current); - } - } - return result; - } - - /** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ - function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); - - while (++index < n) { - result[index] = iteratee(index); - } - return result; - } - - /** - * The base implementation of `_.toPairs` and `_.toPairsIn` which creates an array - * of key-value pairs for `object` corresponding to the property names of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the key-value pairs. - */ - function baseToPairs(object, props) { - return arrayMap(props, function(key) { - return [key, object[key]]; - }); - } - - /** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ - function baseUnary(func) { - return function(value) { - return func(value); - }; - } - - /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} props The property names to get values for. - * @returns {Object} Returns the array of property values. - */ - function baseValues(object, props) { - return arrayMap(props, function(key) { - return object[key]; - }); - } - - /** - * Checks if a cache value for `key` exists. - * - * @private - * @param {Object} cache The cache to query. - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function cacheHas(cache, key) { - return cache.has(key); - } - - /** - * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the first unmatched string symbol. - */ - function charsStartIndex(strSymbols, chrSymbols) { - var index = -1, - length = strSymbols.length; - - while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the last unmatched string symbol. - */ - function charsEndIndex(strSymbols, chrSymbols) { - var index = strSymbols.length; - - while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} - return index; - } - - /** - * Gets the number of `placeholder` occurrences in `array`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} placeholder The placeholder to search for. - * @returns {number} Returns the placeholder count. - */ - function countHolders(array, placeholder) { - var length = array.length, - result = 0; - - while (length--) { - if (array[length] === placeholder) { - result++; - } - } - return result; - } - - /** - * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. - * - * @private - * @param {string} letter The matched letter to deburr. - * @returns {string} Returns the deburred letter. - */ - var deburrLetter = basePropertyOf(deburredLetters); - - /** - * Used by `_.escape` to convert characters to HTML entities. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - var escapeHtmlChar = basePropertyOf(htmlEscapes); - - /** - * Used by `_.template` to escape characters for inclusion in compiled string literals. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeStringChar(chr) { - return '\\' + stringEscapes[chr]; - } - - /** - * Gets the value at `key` of `object`. - * - * @private - * @param {Object} [object] The object to query. - * @param {string} key The key of the property to get. - * @returns {*} Returns the property value. - */ - function getValue(object, key) { - return object == null ? undefined : object[key]; - } - - /** - * Checks if `value` is a host object in IE < 9. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a host object, else `false`. - */ - function isHostObject(value) { - // Many host objects are `Object` objects that can coerce to strings - // despite having improperly defined `toString` methods. - var result = false; - if (value != null && typeof value.toString != 'function') { - try { - result = !!(value + ''); - } catch (e) {} - } - return result; - } - - /** - * Converts `iterator` to an array. - * - * @private - * @param {Object} iterator The iterator to convert. - * @returns {Array} Returns the converted array. - */ - function iteratorToArray(iterator) { - var data, - result = []; - - while (!(data = iterator.next()).done) { - result.push(data.value); - } - return result; - } - - /** - * Converts `map` to its key-value pairs. - * - * @private - * @param {Object} map The map to convert. - * @returns {Array} Returns the key-value pairs. - */ - function mapToArray(map) { - var index = -1, - result = Array(map.size); - - map.forEach(function(value, key) { - result[++index] = [key, value]; - }); - return result; - } - - /** - * Creates a function that invokes `func` with its first argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ - function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; - } - - /** - * Replaces all `placeholder` elements in `array` with an internal placeholder - * and returns an array of their indexes. - * - * @private - * @param {Array} array The array to modify. - * @param {*} placeholder The placeholder to replace. - * @returns {Array} Returns the new array of placeholder indexes. - */ - function replaceHolders(array, placeholder) { - var index = -1, - length = array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value === placeholder || value === PLACEHOLDER) { - array[index] = PLACEHOLDER; - result[resIndex++] = index; - } - } - return result; - } - - /** - * Converts `set` to an array of its values. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the values. - */ - function setToArray(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = value; - }); - return result; - } - - /** - * Converts `set` to its value-value pairs. - * - * @private - * @param {Object} set The set to convert. - * @returns {Array} Returns the value-value pairs. - */ - function setToPairs(set) { - var index = -1, - result = Array(set.size); - - set.forEach(function(value) { - result[++index] = [value, value]; - }); - return result; - } - - /** - * Gets the number of symbols in `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the string size. - */ - function stringSize(string) { - if (!(string && reHasComplexSymbol.test(string))) { - return string.length; - } - var result = reComplexSymbol.lastIndex = 0; - while (reComplexSymbol.test(string)) { - result++; - } - return result; - } - - /** - * Converts `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function stringToArray(string) { - return string.match(reComplexSymbol); - } - - /** - * Used by `_.unescape` to convert HTML entities to characters. - * - * @private - * @param {string} chr The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - var unescapeHtmlChar = basePropertyOf(htmlUnescapes); - - /*--------------------------------------------------------------------------*/ - - /** - * Create a new pristine `lodash` function using the `context` object. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Util - * @param {Object} [context=root] The context object. - * @returns {Function} Returns a new `lodash` function. - * @example - * - * _.mixin({ 'foo': _.constant('foo') }); - * - * var lodash = _.runInContext(); - * lodash.mixin({ 'bar': lodash.constant('bar') }); - * - * _.isFunction(_.foo); - * // => true - * _.isFunction(_.bar); - * // => false - * - * lodash.isFunction(lodash.foo); - * // => false - * lodash.isFunction(lodash.bar); - * // => true - * - * // Use `context` to stub `Date#getTime` use in `_.now`. - * var stubbed = _.runInContext({ - * 'Date': function() { - * return { 'getTime': stubGetTime }; - * } - * }); - * - * // Create a suped-up `defer` in Node.js. - * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; - */ - function runInContext(context) { - context = context ? _.defaults({}, context, _.pick(root, contextProps)) : root; - - /** Built-in constructor references. */ - var Array = context.Array, - Date = context.Date, - Error = context.Error, - Math = context.Math, - RegExp = context.RegExp, - TypeError = context.TypeError; - - /** Used for built-in method references. */ - var arrayProto = context.Array.prototype, - objectProto = context.Object.prototype, - stringProto = context.String.prototype; - - /** Used to detect overreaching core-js shims. */ - var coreJsData = context['__core-js_shared__']; - - /** Used to detect methods masquerading as native. */ - var maskSrcKey = (function() { - var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ''); - return uid ? ('Symbol(src)_1.' + uid) : ''; - }()); - - /** Used to resolve the decompiled source of functions. */ - var funcToString = context.Function.prototype.toString; - - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to generate unique IDs. */ - var idCounter = 0; - - /** Used to infer the `Object` constructor. */ - var objectCtorString = funcToString.call(Object); - - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) - * of values. - */ - var objectToString = objectProto.toString; - - /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = root._; - - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\$&') - .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** Built-in value references. */ - var Buffer = moduleExports ? context.Buffer : undefined, - Reflect = context.Reflect, - Symbol = context.Symbol, - Uint8Array = context.Uint8Array, - enumerate = Reflect ? Reflect.enumerate : undefined, - iteratorSymbol = Symbol ? Symbol.iterator : undefined, - objectCreate = context.Object.create, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - splice = arrayProto.splice, - spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined; - - /** Built-in method references that are mockable. */ - var clearTimeout = function(id) { return context.clearTimeout.call(root, id); }, - setTimeout = function(func, wait) { return context.setTimeout.call(root, func, wait); }; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeCeil = Math.ceil, - nativeFloor = Math.floor, - nativeGetPrototype = Object.getPrototypeOf, - nativeGetSymbols = Object.getOwnPropertySymbols, - nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, - nativeIsFinite = context.isFinite, - nativeJoin = arrayProto.join, - nativeKeys = Object.keys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeParseInt = context.parseInt, - nativeRandom = Math.random, - nativeReplace = stringProto.replace, - nativeReverse = arrayProto.reverse, - nativeSplit = stringProto.split; - - /* Built-in method references that are verified to be native. */ - var DataView = getNative(context, 'DataView'), - Map = getNative(context, 'Map'), - Promise = getNative(context, 'Promise'), - Set = getNative(context, 'Set'), - WeakMap = getNative(context, 'WeakMap'), - nativeCreate = getNative(context.Object, 'create'); - - /* Used to set `toString` methods. */ - var defineProperty = (function() { - var func = getNative(context.Object, 'defineProperty'), - name = getNative.name; - - return (name && name.length > 2) ? func : undefined; - }()); - - /** Used to store function metadata. */ - var metaMap = WeakMap && new WeakMap; - - /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ - var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); - - /** Used to lookup unminified function names. */ - var realNames = {}; - - /** Used to detect maps, sets, and weakmaps. */ - var dataViewCtorString = toSource(DataView), - mapCtorString = toSource(Map), - promiseCtorString = toSource(Promise), - setCtorString = toSource(Set), - weakMapCtorString = toSource(WeakMap); - - /** Used to convert symbols to primitives and strings. */ - var symbolProto = Symbol ? Symbol.prototype : undefined, - symbolValueOf = symbolProto ? symbolProto.valueOf : undefined, - symbolToString = symbolProto ? symbolProto.toString : undefined; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` object which wraps `value` to enable implicit method - * chain sequences. Methods that operate on and return arrays, collections, - * and functions can be chained together. Methods that retrieve a single value - * or may return a primitive value will automatically end the chain sequence - * and return the unwrapped value. Otherwise, the value must be unwrapped - * with `_#value`. - * - * Explicit chain sequences, which must be unwrapped with `_#value`, may be - * enabled using `_.chain`. - * - * The execution of chained methods is lazy, that is, it's deferred until - * `_#value` is implicitly or explicitly called. - * - * Lazy evaluation allows several methods to support shortcut fusion. - * Shortcut fusion is an optimization to merge iteratee calls; this avoids - * the creation of intermediate arrays and can greatly reduce the number of - * iteratee executions. Sections of a chain sequence qualify for shortcut - * fusion if the section is applied to an array of at least `200` elements - * and any iteratees accept only one argument. The heuristic for whether a - * section qualifies for shortcut fusion is subject to change. - * - * Chaining is supported in custom builds as long as the `_#value` method is - * directly or indirectly included in the build. - * - * In addition to lodash methods, wrappers have `Array` and `String` methods. - * - * The wrapper `Array` methods are: - * `concat`, `join`, `pop`, `push`, `shift`, `sort`, `splice`, and `unshift` - * - * The wrapper `String` methods are: - * `replace` and `split` - * - * The wrapper methods that support shortcut fusion are: - * `at`, `compact`, `drop`, `dropRight`, `dropWhile`, `filter`, `find`, - * `findLast`, `head`, `initial`, `last`, `map`, `reject`, `reverse`, `slice`, - * `tail`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, and `toArray` - * - * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `assignIn`, `assignInWith`, `assignWith`, `at`, - * `before`, `bind`, `bindAll`, `bindKey`, `castArray`, `chain`, `chunk`, - * `commit`, `compact`, `concat`, `conforms`, `constant`, `countBy`, `create`, - * `curry`, `debounce`, `defaults`, `defaultsDeep`, `defer`, `delay`, - * `difference`, `differenceBy`, `differenceWith`, `drop`, `dropRight`, - * `dropRightWhile`, `dropWhile`, `extend`, `extendWith`, `fill`, `filter`, - * `flatMap`, `flatMapDeep`, `flatMapDepth`, `flatten`, `flattenDeep`, - * `flattenDepth`, `flip`, `flow`, `flowRight`, `fromPairs`, `functions`, - * `functionsIn`, `groupBy`, `initial`, `intersection`, `intersectionBy`, - * `intersectionWith`, `invert`, `invertBy`, `invokeMap`, `iteratee`, `keyBy`, - * `keys`, `keysIn`, `map`, `mapKeys`, `mapValues`, `matches`, `matchesProperty`, - * `memoize`, `merge`, `mergeWith`, `method`, `methodOf`, `mixin`, `negate`, - * `nthArg`, `omit`, `omitBy`, `once`, `orderBy`, `over`, `overArgs`, - * `overEvery`, `overSome`, `partial`, `partialRight`, `partition`, `pick`, - * `pickBy`, `plant`, `property`, `propertyOf`, `pull`, `pullAll`, `pullAllBy`, - * `pullAllWith`, `pullAt`, `push`, `range`, `rangeRight`, `rearg`, `reject`, - * `remove`, `rest`, `reverse`, `sampleSize`, `set`, `setWith`, `shuffle`, - * `slice`, `sort`, `sortBy`, `splice`, `spread`, `tail`, `take`, `takeRight`, - * `takeRightWhile`, `takeWhile`, `tap`, `throttle`, `thru`, `toArray`, - * `toPairs`, `toPairsIn`, `toPath`, `toPlainObject`, `transform`, `unary`, - * `union`, `unionBy`, `unionWith`, `uniq`, `uniqBy`, `uniqWith`, `unset`, - * `unshift`, `unzip`, `unzipWith`, `update`, `updateWith`, `values`, - * `valuesIn`, `without`, `wrap`, `xor`, `xorBy`, `xorWith`, `zip`, - * `zipObject`, `zipObjectDeep`, and `zipWith` - * - * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `ceil`, `clamp`, `clone`, - * `cloneDeep`, `cloneDeepWith`, `cloneWith`, `conformsTo`, `deburr`, - * `defaultTo`, `divide`, `each`, `eachRight`, `endsWith`, `eq`, `escape`, - * `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, `findLast`, - * `findLastIndex`, `findLastKey`, `first`, `floor`, `forEach`, `forEachRight`, - * `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `get`, `gt`, `gte`, `has`, - * `hasIn`, `head`, `identity`, `includes`, `indexOf`, `inRange`, `invoke`, - * `isArguments`, `isArray`, `isArrayBuffer`, `isArrayLike`, `isArrayLikeObject`, - * `isBoolean`, `isBuffer`, `isDate`, `isElement`, `isEmpty`, `isEqual`, - * `isEqualWith`, `isError`, `isFinite`, `isFunction`, `isInteger`, `isLength`, - * `isMap`, `isMatch`, `isMatchWith`, `isNaN`, `isNative`, `isNil`, `isNull`, - * `isNumber`, `isObject`, `isObjectLike`, `isPlainObject`, `isRegExp`, - * `isSafeInteger`, `isSet`, `isString`, `isUndefined`, `isTypedArray`, - * `isWeakMap`, `isWeakSet`, `join`, `kebabCase`, `last`, `lastIndexOf`, - * `lowerCase`, `lowerFirst`, `lt`, `lte`, `max`, `maxBy`, `mean`, `meanBy`, - * `min`, `minBy`, `multiply`, `noConflict`, `noop`, `now`, `nth`, `pad`, - * `padEnd`, `padStart`, `parseInt`, `pop`, `random`, `reduce`, `reduceRight`, - * `repeat`, `result`, `round`, `runInContext`, `sample`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedIndexBy`, `sortedLastIndex`, - * `sortedLastIndexBy`, `startCase`, `startsWith`, `stubArray`, `stubFalse`, - * `stubObject`, `stubString`, `stubTrue`, `subtract`, `sum`, `sumBy`, - * `template`, `times`, `toFinite`, `toInteger`, `toJSON`, `toLength`, - * `toLower`, `toNumber`, `toSafeInteger`, `toString`, `toUpper`, `trim`, - * `trimEnd`, `trimStart`, `truncate`, `unescape`, `uniqueId`, `upperCase`, - * `upperFirst`, `value`, and `words` - * - * @name _ - * @constructor - * @category Seq - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2, 3]); - * - * // Returns an unwrapped value. - * wrapped.reduce(_.add); - * // => 6 - * - * // Returns a wrapped value. - * var squares = wrapped.map(square); - * - * _.isArray(squares); - * // => false - * - * _.isArray(squares.value()); - * // => true - */ - function lodash(value) { - if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { - if (value instanceof LodashWrapper) { - return value; - } - if (hasOwnProperty.call(value, '__wrapped__')) { - return wrapperClone(value); - } - } - return new LodashWrapper(value); - } - - /** - * The function whose prototype chain sequence wrappers inherit from. - * - * @private - */ - function baseLodash() { - // No operation performed. - } - - /** - * The base constructor for creating `lodash` wrapper objects. - * - * @private - * @param {*} value The value to wrap. - * @param {boolean} [chainAll] Enable explicit method chain sequences. - */ - function LodashWrapper(value, chainAll) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__chain__ = !!chainAll; - this.__index__ = 0; - this.__values__ = undefined; - } - - /** - * By default, the template delimiters used by lodash are like those in - * embedded Ruby (ERB). Change the following template settings to use - * alternative delimiters. - * - * @static - * @memberOf _ - * @type {Object} - */ - lodash.templateSettings = { - - /** - * Used to detect `data` property values to be HTML-escaped. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'escape': reEscape, - - /** - * Used to detect code to be evaluated. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'evaluate': reEvaluate, - - /** - * Used to detect `data` property values to inject. - * - * @memberOf _.templateSettings - * @type {RegExp} - */ - 'interpolate': reInterpolate, - - /** - * Used to reference the data object in the template text. - * - * @memberOf _.templateSettings - * @type {string} - */ - 'variable': '', - - /** - * Used to import variables into the compiled template. - * - * @memberOf _.templateSettings - * @type {Object} - */ - 'imports': { - - /** - * A reference to the `lodash` function. - * - * @memberOf _.templateSettings.imports - * @type {Function} - */ - '_': lodash - } - }; - - // Ensure wrappers are instances of `baseLodash`. - lodash.prototype = baseLodash.prototype; - lodash.prototype.constructor = lodash; - - LodashWrapper.prototype = baseCreate(baseLodash.prototype); - LodashWrapper.prototype.constructor = LodashWrapper; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. - * - * @private - * @constructor - * @param {*} value The value to wrap. - */ - function LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = []; - this.__dir__ = 1; - this.__filtered__ = false; - this.__iteratees__ = []; - this.__takeCount__ = MAX_ARRAY_LENGTH; - this.__views__ = []; - } - - /** - * Creates a clone of the lazy wrapper object. - * - * @private - * @name clone - * @memberOf LazyWrapper - * @returns {Object} Returns the cloned `LazyWrapper` object. - */ - function lazyClone() { - var result = new LazyWrapper(this.__wrapped__); - result.__actions__ = copyArray(this.__actions__); - result.__dir__ = this.__dir__; - result.__filtered__ = this.__filtered__; - result.__iteratees__ = copyArray(this.__iteratees__); - result.__takeCount__ = this.__takeCount__; - result.__views__ = copyArray(this.__views__); - return result; - } - - /** - * Reverses the direction of lazy iteration. - * - * @private - * @name reverse - * @memberOf LazyWrapper - * @returns {Object} Returns the new reversed `LazyWrapper` object. - */ - function lazyReverse() { - if (this.__filtered__) { - var result = new LazyWrapper(this); - result.__dir__ = -1; - result.__filtered__ = true; - } else { - result = this.clone(); - result.__dir__ *= -1; - } - return result; - } - - /** - * Extracts the unwrapped value from its lazy wrapper. - * - * @private - * @name value - * @memberOf LazyWrapper - * @returns {*} Returns the unwrapped value. - */ - function lazyValue() { - var array = this.__wrapped__.value(), - dir = this.__dir__, - isArr = isArray(array), - isRight = dir < 0, - arrLength = isArr ? array.length : 0, - view = getView(0, arrLength, this.__views__), - start = view.start, - end = view.end, - length = end - start, - index = isRight ? end : (start - 1), - iteratees = this.__iteratees__, - iterLength = iteratees.length, - resIndex = 0, - takeCount = nativeMin(length, this.__takeCount__); - - if (!isArr || arrLength < LARGE_ARRAY_SIZE || - (arrLength == length && takeCount == length)) { - return baseWrapperValue(array, this.__actions__); - } - var result = []; - - outer: - while (length-- && resIndex < takeCount) { - index += dir; - - var iterIndex = -1, - value = array[index]; - - while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], - iteratee = data.iteratee, - type = data.type, - computed = iteratee(value); - - if (type == LAZY_MAP_FLAG) { - value = computed; - } else if (!computed) { - if (type == LAZY_FILTER_FLAG) { - continue outer; - } else { - break outer; - } - } - } - result[resIndex++] = value; - } - return result; - } - - // Ensure `LazyWrapper` is an instance of `baseLodash`. - LazyWrapper.prototype = baseCreate(baseLodash.prototype); - LazyWrapper.prototype.constructor = LazyWrapper; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a hash object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Hash(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the hash. - * - * @private - * @name clear - * @memberOf Hash - */ - function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; - } - - /** - * Removes `key` and its value from the hash. - * - * @private - * @name delete - * @memberOf Hash - * @param {Object} hash The hash to modify. - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function hashDelete(key) { - return this.has(key) && delete this.__data__[key]; - } - - /** - * Gets the hash value for `key`. - * - * @private - * @name get - * @memberOf Hash - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function hashGet(key) { - var data = this.__data__; - if (nativeCreate) { - var result = data[key]; - return result === HASH_UNDEFINED ? undefined : result; - } - return hasOwnProperty.call(data, key) ? data[key] : undefined; - } - - /** - * Checks if a hash value for `key` exists. - * - * @private - * @name has - * @memberOf Hash - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function hashHas(key) { - var data = this.__data__; - return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key); - } - - /** - * Sets the hash `key` to `value`. - * - * @private - * @name set - * @memberOf Hash - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the hash instance. - */ - function hashSet(key, value) { - var data = this.__data__; - data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value; - return this; - } - - // Add methods to `Hash`. - Hash.prototype.clear = hashClear; - Hash.prototype['delete'] = hashDelete; - Hash.prototype.get = hashGet; - Hash.prototype.has = hashHas; - Hash.prototype.set = hashSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates an list cache object. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function ListCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the list cache. - * - * @private - * @name clear - * @memberOf ListCache - */ - function listCacheClear() { - this.__data__ = []; - } - - /** - * Removes `key` and its value from the list cache. - * - * @private - * @name delete - * @memberOf ListCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function listCacheDelete(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - return false; - } - var lastIndex = data.length - 1; - if (index == lastIndex) { - data.pop(); - } else { - splice.call(data, index, 1); - } - return true; - } - - /** - * Gets the list cache value for `key`. - * - * @private - * @name get - * @memberOf ListCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function listCacheGet(key) { - var data = this.__data__, - index = assocIndexOf(data, key); - - return index < 0 ? undefined : data[index][1]; - } - - /** - * Checks if a list cache value for `key` exists. - * - * @private - * @name has - * @memberOf ListCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; - } - - /** - * Sets the list cache `key` to `value`. - * - * @private - * @name set - * @memberOf ListCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the list cache instance. - */ - function listCacheSet(key, value) { - var data = this.__data__, - index = assocIndexOf(data, key); - - if (index < 0) { - data.push([key, value]); - } else { - data[index][1] = value; - } - return this; - } - - // Add methods to `ListCache`. - ListCache.prototype.clear = listCacheClear; - ListCache.prototype['delete'] = listCacheDelete; - ListCache.prototype.get = listCacheGet; - ListCache.prototype.has = listCacheHas; - ListCache.prototype.set = listCacheSet; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a map cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function MapCache(entries) { - var index = -1, - length = entries ? entries.length : 0; - - this.clear(); - while (++index < length) { - var entry = entries[index]; - this.set(entry[0], entry[1]); - } - } - - /** - * Removes all key-value entries from the map. - * - * @private - * @name clear - * @memberOf MapCache - */ - function mapCacheClear() { - this.__data__ = { - 'hash': new Hash, - 'map': new (Map || ListCache), - 'string': new Hash - }; - } - - /** - * Removes `key` and its value from the map. - * - * @private - * @name delete - * @memberOf MapCache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function mapCacheDelete(key) { - return getMapData(this, key)['delete'](key); - } - - /** - * Gets the map value for `key`. - * - * @private - * @name get - * @memberOf MapCache - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function mapCacheGet(key) { - return getMapData(this, key).get(key); - } - - /** - * Checks if a map value for `key` exists. - * - * @private - * @name has - * @memberOf MapCache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function mapCacheHas(key) { - return getMapData(this, key).has(key); - } - - /** - * Sets the map `key` to `value`. - * - * @private - * @name set - * @memberOf MapCache - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the map cache instance. - */ - function mapCacheSet(key, value) { - getMapData(this, key).set(key, value); - return this; - } - - // Add methods to `MapCache`. - MapCache.prototype.clear = mapCacheClear; - MapCache.prototype['delete'] = mapCacheDelete; - MapCache.prototype.get = mapCacheGet; - MapCache.prototype.has = mapCacheHas; - MapCache.prototype.set = mapCacheSet; - - /*------------------------------------------------------------------------*/ - - /** - * - * Creates an array cache object to store unique values. - * - * @private - * @constructor - * @param {Array} [values] The values to cache. - */ - function SetCache(values) { - var index = -1, - length = values ? values.length : 0; - - this.__data__ = new MapCache; - while (++index < length) { - this.add(values[index]); - } - } - - /** - * Adds `value` to the array cache. - * - * @private - * @name add - * @memberOf SetCache - * @alias push - * @param {*} value The value to cache. - * @returns {Object} Returns the cache instance. - */ - function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; - } - - /** - * Checks if `value` is in the array cache. - * - * @private - * @name has - * @memberOf SetCache - * @param {*} value The value to search for. - * @returns {number} Returns `true` if `value` is found, else `false`. - */ - function setCacheHas(value) { - return this.__data__.has(value); - } - - // Add methods to `SetCache`. - SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; - SetCache.prototype.has = setCacheHas; - - /*------------------------------------------------------------------------*/ - - /** - * Creates a stack cache object to store key-value pairs. - * - * @private - * @constructor - * @param {Array} [entries] The key-value pairs to cache. - */ - function Stack(entries) { - this.__data__ = new ListCache(entries); - } - - /** - * Removes all key-value entries from the stack. - * - * @private - * @name clear - * @memberOf Stack - */ - function stackClear() { - this.__data__ = new ListCache; - } - - /** - * Removes `key` and its value from the stack. - * - * @private - * @name delete - * @memberOf Stack - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed, else `false`. - */ - function stackDelete(key) { - return this.__data__['delete'](key); - } - - /** - * Gets the stack value for `key`. - * - * @private - * @name get - * @memberOf Stack - * @param {string} key The key of the value to get. - * @returns {*} Returns the entry value. - */ - function stackGet(key) { - return this.__data__.get(key); - } - - /** - * Checks if a stack value for `key` exists. - * - * @private - * @name has - * @memberOf Stack - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. - */ - function stackHas(key) { - return this.__data__.has(key); - } - - /** - * Sets the stack `key` to `value`. - * - * @private - * @name set - * @memberOf Stack - * @param {string} key The key of the value to set. - * @param {*} value The value to set. - * @returns {Object} Returns the stack cache instance. - */ - function stackSet(key, value) { - var cache = this.__data__; - if (cache instanceof ListCache) { - var pairs = cache.__data__; - if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { - pairs.push([key, value]); - return this; - } - cache = this.__data__ = new MapCache(pairs); - } - cache.set(key, value); - return this; - } - - // Add methods to `Stack`. - Stack.prototype.clear = stackClear; - Stack.prototype['delete'] = stackDelete; - Stack.prototype.get = stackGet; - Stack.prototype.has = stackHas; - Stack.prototype.set = stackSet; - - /*------------------------------------------------------------------------*/ - - /** - * Used by `_.defaults` to customize its `_.assignIn` use. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to assign. - * @param {Object} object The parent object of `objValue`. - * @returns {*} Returns the value to assign. - */ - function assignInDefaults(objValue, srcValue, key, object) { - if (objValue === undefined || - (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { - return srcValue; - } - return objValue; - } - - /** - * This function is like `assignValue` except that it doesn't assign - * `undefined` values. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignMergeValue(object, key, value) { - if ((value !== undefined && !eq(object[key], value)) || - (typeof key == 'number' && value === undefined && !(key in object))) { - object[key] = value; - } - } - - /** - * Assigns `value` to `key` of `object` if the existing value is not equivalent - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * @private - * @param {Object} object The object to modify. - * @param {string} key The key of the property to assign. - * @param {*} value The value to assign. - */ - function assignValue(object, key, value) { - var objValue = object[key]; - if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || - (value === undefined && !(key in object))) { - object[key] = value; - } - } - - /** - * Gets the index at which the `key` is found in `array` of key-value pairs. - * - * @private - * @param {Array} array The array to search. - * @param {*} key The key to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function assocIndexOf(array, key) { - var length = array.length; - while (length--) { - if (eq(array[length][0], key)) { - return length; - } - } - return -1; - } - - /** - * Aggregates elements of `collection` on `accumulator` with keys transformed - * by `iteratee` and values set by `setter`. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform keys. - * @param {Object} accumulator The initial aggregated object. - * @returns {Function} Returns `accumulator`. - */ - function baseAggregator(collection, setter, iteratee, accumulator) { - baseEach(collection, function(value, key, collection) { - setter(accumulator, value, iteratee(value), collection); - }); - return accumulator; - } - - /** - * The base implementation of `_.assign` without support for multiple sources - * or `customizer` functions. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. - */ - function baseAssign(object, source) { - return object && copyObject(source, keys(source), object); - } - - /** - * The base implementation of `_.at` without support for individual paths. - * - * @private - * @param {Object} object The object to iterate over. - * @param {string[]} paths The property paths of elements to pick. - * @returns {Array} Returns the picked elements. - */ - function baseAt(object, paths) { - var index = -1, - isNil = object == null, - length = paths.length, - result = Array(length); - - while (++index < length) { - result[index] = isNil ? undefined : get(object, paths[index]); - } - return result; - } - - /** - * The base implementation of `_.clamp` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - */ - function baseClamp(number, lower, upper) { - if (number === number) { - if (upper !== undefined) { - number = number <= upper ? number : upper; - } - if (lower !== undefined) { - number = number >= lower ? number : lower; - } - } - return number; - } - - /** - * The base implementation of `_.clone` and `_.cloneDeep` which tracks - * traversed objects. - * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {boolean} [isFull] Specify a clone including symbols. - * @param {Function} [customizer] The function to customize cloning. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The parent object of `value`. - * @param {Object} [stack] Tracks traversed objects and their clone counterparts. - * @returns {*} Returns the cloned value. - */ - function baseClone(value, isDeep, isFull, customizer, key, object, stack) { - var result; - if (customizer) { - result = object ? customizer(value, key, object, stack) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return copyArray(value, result); - } - } else { - var tag = getTag(value), - isFunc = tag == funcTag || tag == genTag; - - if (isBuffer(value)) { - return cloneBuffer(value, isDeep); - } - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - if (isHostObject(value)) { - return object ? value : {}; - } - result = initCloneObject(isFunc ? {} : value); - if (!isDeep) { - return copySymbols(value, baseAssign(result, value)); - } - } else { - if (!cloneableTags[tag]) { - return object ? value : {}; - } - result = initCloneByTag(value, tag, baseClone, isDeep); - } - } - // Check for circular references and return its corresponding clone. - stack || (stack = new Stack); - var stacked = stack.get(value); - if (stacked) { - return stacked; - } - stack.set(value, result); - - if (!isArr) { - var props = isFull ? getAllKeys(value) : keys(value); - } - arrayEach(props || value, function(subValue, key) { - if (props) { - key = subValue; - subValue = value[key]; - } - // Recursively populate clone (susceptible to call stack limits). - assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack)); - }); - return result; - } - - /** - * The base implementation of `_.conforms` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property predicates to conform to. - * @returns {Function} Returns the new spec function. - */ - function baseConforms(source) { - var props = keys(source); - return function(object) { - return baseConformsTo(object, source, props); - }; - } - - /** - * The base implementation of `_.conformsTo` which accepts `props` to check. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property predicates to conform to. - * @returns {boolean} Returns `true` if `object` conforms, else `false`. - */ - function baseConformsTo(object, source, props) { - var length = props.length; - if (object == null) { - return !length; - } - var index = length; - while (index--) { - var key = props[index], - predicate = source[key], - value = object[key]; - - if ((value === undefined && - !(key in Object(object))) || !predicate(value)) { - return false; - } - } - return true; - } - - /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. - * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. - */ - function baseCreate(proto) { - return isObject(proto) ? objectCreate(proto) : {}; - } - - /** - * The base implementation of `_.delay` and `_.defer` which accepts `args` - * to provide to `func`. - * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {Array} args The arguments to provide to `func`. - * @returns {number} Returns the timer id. - */ - function baseDelay(func, wait, args) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * The base implementation of methods like `_.difference` without support - * for excluding multiple arrays or iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - */ - function baseDifference(array, values, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - isCommon = true, - length = array.length, - result = [], - valuesLength = values.length; - - if (!length) { - return result; - } - if (iteratee) { - values = arrayMap(values, baseUnary(iteratee)); - } - if (comparator) { - includes = arrayIncludesWith; - isCommon = false; - } - else if (values.length >= LARGE_ARRAY_SIZE) { - includes = cacheHas; - isCommon = false; - values = new SetCache(values); - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === computed) { - continue outer; - } - } - result.push(value); - } - else if (!includes(values, computed, comparator)) { - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.forEach` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ - var baseEach = createBaseEach(baseForOwn); - - /** - * The base implementation of `_.forEachRight` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - */ - var baseEachRight = createBaseEach(baseForOwnRight, true); - - /** - * The base implementation of `_.every` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false` - */ - function baseEvery(collection, predicate) { - var result = true; - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); - return result; - }); - return result; - } - - /** - * The base implementation of methods like `_.max` and `_.min` which accepts a - * `comparator` to determine the extremum value. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The iteratee invoked per iteration. - * @param {Function} comparator The comparator used to compare values. - * @returns {*} Returns the extremum value. - */ - function baseExtremum(array, iteratee, comparator) { - var index = -1, - length = array.length; - - while (++index < length) { - var value = array[index], - current = iteratee(value); - - if (current != null && (computed === undefined - ? (current === current && !isSymbol(current)) - : comparator(current, computed) - )) { - var computed = current, - result = value; - } - } - return result; - } - - /** - * The base implementation of `_.fill` without an iteratee call guard. - * - * @private - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - */ - function baseFill(array, value, start, end) { - var length = array.length; - - start = toInteger(start); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : toInteger(end); - if (end < 0) { - end += length; - } - end = start > end ? 0 : toLength(end); - while (start < end) { - array[start++] = value; - } - return array; - } - - /** - * The base implementation of `_.filter` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - */ - function baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); - } - }); - return result; - } - - /** - * The base implementation of `_.flatten` with support for restricting flattening. - * - * @private - * @param {Array} array The array to flatten. - * @param {number} depth The maximum recursion depth. - * @param {boolean} [predicate=isFlattenable] The function invoked per iteration. - * @param {boolean} [isStrict] Restrict to values that pass `predicate` checks. - * @param {Array} [result=[]] The initial result value. - * @returns {Array} Returns the new flattened array. - */ - function baseFlatten(array, depth, predicate, isStrict, result) { - var index = -1, - length = array.length; - - predicate || (predicate = isFlattenable); - result || (result = []); - - while (++index < length) { - var value = array[index]; - if (depth > 0 && predicate(value)) { - if (depth > 1) { - // Recursively flatten arrays (susceptible to call stack limits). - baseFlatten(value, depth - 1, predicate, isStrict, result); - } else { - arrayPush(result, value); - } - } else if (!isStrict) { - result[result.length] = value; - } - } - return result; - } - - /** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseFor = createBaseFor(); - - /** - * This function is like `baseFor` except that it iterates over properties - * in the opposite order. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseForRight = createBaseFor(true); - - /** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return object && baseFor(object, iteratee, keys); - } - - /** - * The base implementation of `_.forOwnRight` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwnRight(object, iteratee) { - return object && baseForRight(object, iteratee, keys); - } - - /** - * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from `props`. - * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The property names to filter. - * @returns {Array} Returns the function names. - */ - function baseFunctions(object, props) { - return arrayFilter(props, function(key) { - return isFunction(object[key]); - }); - } - - /** - * The base implementation of `_.get` without support for default values. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @returns {*} Returns the resolved value. - */ - function baseGet(object, path) { - path = isKey(path, object) ? [path] : castPath(path); - - var index = 0, - length = path.length; - - while (object != null && index < length) { - object = object[toKey(path[index++])]; - } - return (index && index == length) ? object : undefined; - } - - /** - * The base implementation of `getAllKeys` and `getAllKeysIn` which uses - * `keysFunc` and `symbolsFunc` to get the enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Function} keysFunc The function to get the keys of `object`. - * @param {Function} symbolsFunc The function to get the symbols of `object`. - * @returns {Array} Returns the array of property names and symbols. - */ - function baseGetAllKeys(object, keysFunc, symbolsFunc) { - var result = keysFunc(object); - return isArray(object) ? result : arrayPush(result, symbolsFunc(object)); - } - - /** - * The base implementation of `getTag`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - function baseGetTag(value) { - return objectToString.call(value); - } - - /** - * The base implementation of `_.gt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, - * else `false`. - */ - function baseGt(value, other) { - return value > other; - } - - /** - * The base implementation of `_.has` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHas(object, key) { - // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, - // that are composed entirely of index properties, return `false` for - // `hasOwnProperty` checks of them. - return object != null && - (hasOwnProperty.call(object, key) || - (typeof object == 'object' && key in object && getPrototype(object) === null)); - } - - /** - * The base implementation of `_.hasIn` without support for deep paths. - * - * @private - * @param {Object} [object] The object to query. - * @param {Array|string} key The key to check. - * @returns {boolean} Returns `true` if `key` exists, else `false`. - */ - function baseHasIn(object, key) { - return object != null && key in Object(object); - } - - /** - * The base implementation of `_.inRange` which doesn't coerce arguments. - * - * @private - * @param {number} number The number to check. - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `number` is in the range, else `false`. - */ - function baseInRange(number, start, end) { - return number >= nativeMin(start, end) && number < nativeMax(start, end); - } - - /** - * The base implementation of methods like `_.intersection`, without support - * for iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of shared values. - */ - function baseIntersection(arrays, iteratee, comparator) { - var includes = comparator ? arrayIncludesWith : arrayIncludes, - length = arrays[0].length, - othLength = arrays.length, - othIndex = othLength, - caches = Array(othLength), - maxLength = Infinity, - result = []; - - while (othIndex--) { - var array = arrays[othIndex]; - if (othIndex && iteratee) { - array = arrayMap(array, baseUnary(iteratee)); - } - maxLength = nativeMin(array.length, maxLength); - caches[othIndex] = !comparator && (iteratee || (length >= 120 && array.length >= 120)) - ? new SetCache(othIndex && array) - : undefined; - } - array = arrays[0]; - - var index = -1, - seen = caches[0]; - - outer: - while (++index < length && result.length < maxLength) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (!(seen - ? cacheHas(seen, computed) - : includes(result, computed, comparator) - )) { - othIndex = othLength; - while (--othIndex) { - var cache = caches[othIndex]; - if (!(cache - ? cacheHas(cache, computed) - : includes(arrays[othIndex], computed, comparator)) - ) { - continue outer; - } - } - if (seen) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.invert` and `_.invertBy` which inverts - * `object` with values transformed by `iteratee` and set by `setter`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} setter The function to set `accumulator` values. - * @param {Function} iteratee The iteratee to transform values. - * @param {Object} accumulator The initial inverted object. - * @returns {Function} Returns `accumulator`. - */ - function baseInverter(object, setter, iteratee, accumulator) { - baseForOwn(object, function(value, key, object) { - setter(accumulator, iteratee(value), key, object); - }); - return accumulator; - } - - /** - * The base implementation of `_.invoke` without support for individual - * method arguments. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {Array} args The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - */ - function baseInvoke(object, path, args) { - if (!isKey(path, object)) { - path = castPath(path); - object = parent(object, path); - path = last(path); - } - var func = object == null ? object : object[toKey(path)]; - return func == null ? undefined : apply(func, object, args); - } - - /** - * The base implementation of `_.isArrayBuffer` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. - */ - function baseIsArrayBuffer(value) { - return isObjectLike(value) && objectToString.call(value) == arrayBufferTag; - } - - /** - * The base implementation of `_.isDate` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - */ - function baseIsDate(value) { - return isObjectLike(value) && objectToString.call(value) == dateTag; - } - - /** - * The base implementation of `_.isEqual` which supports partial comparisons - * and tracks traversed objects. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparisons. - * @param {boolean} [bitmask] The bitmask of comparison flags. - * The bitmask may be composed of the following flags: - * 1 - Unordered comparison - * 2 - Partial comparison - * @param {Object} [stack] Tracks traversed `value` and `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - */ - function baseIsEqual(value, other, customizer, bitmask, stack) { - if (value === other) { - return true; - } - if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, bitmask, stack); - } - - /** - * A specialized version of `baseIsEqual` for arrays and objects which performs - * deep comparisons and tracks traversed objects enabling objects with circular - * references to be compared. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparisons. - * @param {number} [bitmask] The bitmask of comparison flags. See `baseIsEqual` - * for more details. - * @param {Object} [stack] Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, equalFunc, customizer, bitmask, stack) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = arrayTag, - othTag = arrayTag; - - if (!objIsArr) { - objTag = getTag(object); - objTag = objTag == argsTag ? objectTag : objTag; - } - if (!othIsArr) { - othTag = getTag(other); - othTag = othTag == argsTag ? objectTag : othTag; - } - var objIsObj = objTag == objectTag && !isHostObject(object), - othIsObj = othTag == objectTag && !isHostObject(other), - isSameTag = objTag == othTag; - - if (isSameTag && !objIsObj) { - stack || (stack = new Stack); - return (objIsArr || isTypedArray(object)) - ? equalArrays(object, other, equalFunc, customizer, bitmask, stack) - : equalByTag(object, other, objTag, equalFunc, customizer, bitmask, stack); - } - if (!(bitmask & PARTIAL_COMPARE_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object.value() : object, - othUnwrapped = othIsWrapped ? other.value() : other; - - stack || (stack = new Stack); - return equalFunc(objUnwrapped, othUnwrapped, customizer, bitmask, stack); - } - } - if (!isSameTag) { - return false; - } - stack || (stack = new Stack); - return equalObjects(object, other, equalFunc, customizer, bitmask, stack); - } - - /** - * The base implementation of `_.isMap` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - */ - function baseIsMap(value) { - return isObjectLike(value) && getTag(value) == mapTag; - } - - /** - * The base implementation of `_.isMatch` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Array} matchData The property names, values, and compare flags to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - */ - function baseIsMatch(object, source, matchData, customizer) { - var index = matchData.length, - length = index, - noCustomizer = !customizer; - - if (object == null) { - return !length; - } - object = Object(object); - while (index--) { - var data = matchData[index]; - if ((noCustomizer && data[2]) - ? data[1] !== object[data[0]] - : !(data[0] in object) - ) { - return false; - } - } - while (++index < length) { - data = matchData[index]; - var key = data[0], - objValue = object[key], - srcValue = data[1]; - - if (noCustomizer && data[2]) { - if (objValue === undefined && !(key in object)) { - return false; - } - } else { - var stack = new Stack; - if (customizer) { - var result = customizer(objValue, srcValue, key, object, source, stack); - } - if (!(result === undefined - ? baseIsEqual(srcValue, objValue, customizer, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG, stack) - : result - )) { - return false; - } - } - } - return true; - } - - /** - * The base implementation of `_.isNative` without bad shim checks. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - */ - function baseIsNative(value) { - if (!isObject(value) || isMasked(value)) { - return false; - } - var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); - } - - /** - * The base implementation of `_.isRegExp` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - */ - function baseIsRegExp(value) { - return isObject(value) && objectToString.call(value) == regexpTag; - } - - /** - * The base implementation of `_.isSet` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - */ - function baseIsSet(value) { - return isObjectLike(value) && getTag(value) == setTag; - } - - /** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ - function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[objectToString.call(value)]; - } - - /** - * The base implementation of `_.iteratee`. - * - * @private - * @param {*} [value=_.identity] The value to convert to an iteratee. - * @returns {Function} Returns the iteratee. - */ - function baseIteratee(value) { - // Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9. - // See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details. - if (typeof value == 'function') { - return value; - } - if (value == null) { - return identity; - } - if (typeof value == 'object') { - return isArray(value) - ? baseMatchesProperty(value[0], value[1]) - : baseMatches(value); - } - return property(value); - } - - /** - * The base implementation of `_.keys` which doesn't skip the constructor - * property of prototypes or treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - var baseKeys = overArg(nativeKeys, Object); - - /** - * The base implementation of `_.keysIn` which doesn't skip the constructor - * property of prototypes or treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeysIn(object) { - object = object == null ? object : Object(object); - - var result = []; - for (var key in object) { - result.push(key); - } - return result; - } - - // Fallback for IE < 9 with es6-shim. - if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) { - baseKeysIn = function(object) { - return iteratorToArray(enumerate(object)); - }; - } - - /** - * The base implementation of `_.lt` which doesn't coerce arguments. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, - * else `false`. - */ - function baseLt(value, other) { - return value < other; - } - - /** - * The base implementation of `_.map` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function baseMap(collection, iteratee) { - var index = -1, - result = isArrayLike(collection) ? Array(collection.length) : []; - - baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); - return result; - } - - /** - * The base implementation of `_.matches` which doesn't clone `source`. - * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatches(source) { - var matchData = getMatchData(source); - if (matchData.length == 1 && matchData[0][2]) { - return matchesStrictComparable(matchData[0][0], matchData[0][1]); - } - return function(object) { - return object === source || baseIsMatch(object, source, matchData); - }; - } - - /** - * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`. - * - * @private - * @param {string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function baseMatchesProperty(path, srcValue) { - if (isKey(path) && isStrictComparable(srcValue)) { - return matchesStrictComparable(toKey(path), srcValue); - } - return function(object) { - var objValue = get(object, path); - return (objValue === undefined && objValue === srcValue) - ? hasIn(object, path) - : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG); - }; - } - - /** - * The base implementation of `_.merge` without support for multiple sources. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {number} srcIndex The index of `source`. - * @param {Function} [customizer] The function to customize merged values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMerge(object, source, srcIndex, customizer, stack) { - if (object === source) { - return; - } - if (!(isArray(source) || isTypedArray(source))) { - var props = keysIn(source); - } - arrayEach(props || source, function(srcValue, key) { - if (props) { - key = srcValue; - srcValue = source[key]; - } - if (isObject(srcValue)) { - stack || (stack = new Stack); - baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); - } - else { - var newValue = customizer - ? customizer(object[key], srcValue, (key + ''), object, source, stack) - : undefined; - - if (newValue === undefined) { - newValue = srcValue; - } - assignMergeValue(object, key, newValue); - } - }); - } - - /** - * A specialized version of `baseMerge` for arrays and objects which performs - * deep merges and tracks traversed objects enabling objects with circular - * references to be merged. - * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {number} srcIndex The index of `source`. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize assigned values. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - */ - function baseMergeDeep(object, source, key, srcIndex, mergeFunc, customizer, stack) { - var objValue = object[key], - srcValue = source[key], - stacked = stack.get(srcValue); - - if (stacked) { - assignMergeValue(object, key, stacked); - return; - } - var newValue = customizer - ? customizer(objValue, srcValue, (key + ''), object, source, stack) - : undefined; - - var isCommon = newValue === undefined; - - if (isCommon) { - newValue = srcValue; - if (isArray(srcValue) || isTypedArray(srcValue)) { - if (isArray(objValue)) { - newValue = objValue; - } - else if (isArrayLikeObject(objValue)) { - newValue = copyArray(objValue); - } - else { - isCommon = false; - newValue = baseClone(srcValue, true); - } - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - if (isArguments(objValue)) { - newValue = toPlainObject(objValue); - } - else if (!isObject(objValue) || (srcIndex && isFunction(objValue))) { - isCommon = false; - newValue = baseClone(srcValue, true); - } - else { - newValue = objValue; - } - } - else { - isCommon = false; - } - } - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, newValue); - mergeFunc(newValue, srcValue, srcIndex, customizer, stack); - stack['delete'](srcValue); - } - assignMergeValue(object, key, newValue); - } - - /** - * The base implementation of `_.nth` which doesn't coerce arguments. - * - * @private - * @param {Array} array The array to query. - * @param {number} n The index of the element to return. - * @returns {*} Returns the nth element of `array`. - */ - function baseNth(array, n) { - var length = array.length; - if (!length) { - return; - } - n += n < 0 ? length : 0; - return isIndex(n, length) ? array[n] : undefined; - } - - /** - * The base implementation of `_.orderBy` without param guards. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {string[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. - */ - function baseOrderBy(collection, iteratees, orders) { - var index = -1; - iteratees = arrayMap(iteratees.length ? iteratees : [identity], baseUnary(getIteratee())); - - var result = baseMap(collection, function(value, key, collection) { - var criteria = arrayMap(iteratees, function(iteratee) { - return iteratee(value); - }); - return { 'criteria': criteria, 'index': ++index, 'value': value }; - }); - - return baseSortBy(result, function(object, other) { - return compareMultiple(object, other, orders); - }); - } - - /** - * The base implementation of `_.pick` without support for individual - * property identifiers. - * - * @private - * @param {Object} object The source object. - * @param {string[]} props The property identifiers to pick. - * @returns {Object} Returns the new object. - */ - function basePick(object, props) { - object = Object(object); - return basePickBy(object, props, function(value, key) { - return key in object; - }); - } - - /** - * The base implementation of `_.pickBy` without support for iteratee shorthands. - * - * @private - * @param {Object} object The source object. - * @param {string[]} props The property identifiers to pick from. - * @param {Function} predicate The function invoked per property. - * @returns {Object} Returns the new object. - */ - function basePickBy(object, props, predicate) { - var index = -1, - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index], - value = object[key]; - - if (predicate(value, key)) { - result[key] = value; - } - } - return result; - } - - /** - * A specialized version of `baseProperty` which supports deep paths. - * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function basePropertyDeep(path) { - return function(object) { - return baseGet(object, path); - }; - } - - /** - * The base implementation of `_.pullAllBy` without support for iteratee - * shorthands. - * - * @private - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns `array`. - */ - function basePullAll(array, values, iteratee, comparator) { - var indexOf = comparator ? baseIndexOfWith : baseIndexOf, - index = -1, - length = values.length, - seen = array; - - if (array === values) { - values = copyArray(values); - } - if (iteratee) { - seen = arrayMap(array, baseUnary(iteratee)); - } - while (++index < length) { - var fromIndex = 0, - value = values[index], - computed = iteratee ? iteratee(value) : value; - - while ((fromIndex = indexOf(seen, computed, fromIndex, comparator)) > -1) { - if (seen !== array) { - splice.call(seen, fromIndex, 1); - } - splice.call(array, fromIndex, 1); - } - } - return array; - } - - /** - * The base implementation of `_.pullAt` without support for individual - * indexes or capturing the removed elements. - * - * @private - * @param {Array} array The array to modify. - * @param {number[]} indexes The indexes of elements to remove. - * @returns {Array} Returns `array`. - */ - function basePullAt(array, indexes) { - var length = array ? indexes.length : 0, - lastIndex = length - 1; - - while (length--) { - var index = indexes[length]; - if (length == lastIndex || index !== previous) { - var previous = index; - if (isIndex(index)) { - splice.call(array, index, 1); - } - else if (!isKey(index, array)) { - var path = castPath(index), - object = parent(array, path); - - if (object != null) { - delete object[toKey(last(path))]; - } - } - else { - delete array[toKey(index)]; - } - } - } - return array; - } - - /** - * The base implementation of `_.random` without support for returning - * floating-point numbers. - * - * @private - * @param {number} lower The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the random number. - */ - function baseRandom(lower, upper) { - return lower + nativeFloor(nativeRandom() * (upper - lower + 1)); - } - - /** - * The base implementation of `_.range` and `_.rangeRight` which doesn't - * coerce arguments. - * - * @private - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @param {number} step The value to increment or decrement by. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the range of numbers. - */ - function baseRange(start, end, step, fromRight) { - var index = -1, - length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), - result = Array(length); - - while (length--) { - result[fromRight ? length : ++index] = start; - start += step; - } - return result; - } - - /** - * The base implementation of `_.repeat` which doesn't coerce arguments. - * - * @private - * @param {string} string The string to repeat. - * @param {number} n The number of times to repeat the string. - * @returns {string} Returns the repeated string. - */ - function baseRepeat(string, n) { - var result = ''; - if (!string || n < 1 || n > MAX_SAFE_INTEGER) { - return result; - } - // Leverage the exponentiation by squaring algorithm for a faster repeat. - // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. - do { - if (n % 2) { - result += string; - } - n = nativeFloor(n / 2); - if (n) { - string += string; - } - } while (n); - - return result; - } - - /** - * The base implementation of `_.rest` which doesn't validate or coerce arguments. - * - * @private - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - */ - function baseRest(func, start) { - start = nativeMax(start === undefined ? (func.length - 1) : start, 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - array = Array(length); - - while (++index < length) { - array[index] = args[start + index]; - } - index = -1; - var otherArgs = Array(start + 1); - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = array; - return apply(func, this, otherArgs); - }; - } - - /** - * The base implementation of `_.set`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseSet(object, path, value, customizer) { - path = isKey(path, object) ? [path] : castPath(path); - - var index = -1, - length = path.length, - lastIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = toKey(path[index]); - if (isObject(nested)) { - var newValue = value; - if (index != lastIndex) { - var objValue = nested[key]; - newValue = customizer ? customizer(objValue, key, nested) : undefined; - if (newValue === undefined) { - newValue = objValue == null - ? (isIndex(path[index + 1]) ? [] : {}) - : objValue; - } - } - assignValue(nested, key, newValue); - } - nested = nested[key]; - } - return object; - } - - /** - * The base implementation of `setData` without support for hot loop detection. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var baseSetData = !metaMap ? identity : function(func, data) { - metaMap.set(func, data); - return func; - }; - - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; - - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; - - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; - } - - /** - * The base implementation of `_.some` without support for iteratee shorthands. - * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - */ - function baseSome(collection, predicate) { - var result; - - baseEach(collection, function(value, index, collection) { - result = predicate(value, index, collection); - return !result; - }); - return !!result; - } - - /** - * The base implementation of `_.sortedIndex` and `_.sortedLastIndex` which - * performs a binary search of `array` to determine the index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function baseSortedIndex(array, value, retHighest) { - var low = 0, - high = array ? array.length : low; - - if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { - while (low < high) { - var mid = (low + high) >>> 1, - computed = array[mid]; - - if (computed !== null && !isSymbol(computed) && - (retHighest ? (computed <= value) : (computed < value))) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - return baseSortedIndexBy(array, value, identity, retHighest); - } - - /** - * The base implementation of `_.sortedIndexBy` and `_.sortedLastIndexBy` - * which invokes `iteratee` for `value` and each element of `array` to compute - * their sort ranking. The iteratee is invoked with one argument; (value). - * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} iteratee The iteratee invoked per element. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - */ - function baseSortedIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); - - var low = 0, - high = array ? array.length : 0, - valIsNaN = value !== value, - valIsNull = value === null, - valIsSymbol = isSymbol(value), - valIsUndefined = value === undefined; - - while (low < high) { - var mid = nativeFloor((low + high) / 2), - computed = iteratee(array[mid]), - othIsDefined = computed !== undefined, - othIsNull = computed === null, - othIsReflexive = computed === computed, - othIsSymbol = isSymbol(computed); - - if (valIsNaN) { - var setLow = retHighest || othIsReflexive; - } else if (valIsUndefined) { - setLow = othIsReflexive && (retHighest || othIsDefined); - } else if (valIsNull) { - setLow = othIsReflexive && othIsDefined && (retHighest || !othIsNull); - } else if (valIsSymbol) { - setLow = othIsReflexive && othIsDefined && !othIsNull && (retHighest || !othIsSymbol); - } else if (othIsNull || othIsSymbol) { - setLow = false; - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; - } else { - high = mid; - } - } - return nativeMin(high, MAX_ARRAY_INDEX); - } - - /** - * The base implementation of `_.sortedUniq` and `_.sortedUniqBy` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ - function baseSortedUniq(array, iteratee) { - var index = -1, - length = array.length, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - if (!index || !eq(computed, seen)) { - var seen = computed; - result[resIndex++] = value === 0 ? 0 : value; - } - } - return result; - } - - /** - * The base implementation of `_.toNumber` which doesn't ensure correct - * conversions of binary, hexadecimal, or octal string values. - * - * @private - * @param {*} value The value to process. - * @returns {number} Returns the number. - */ - function baseToNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - return +value; - } - - /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * The base implementation of `_.uniqBy` without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - */ - function baseUniq(array, iteratee, comparator) { - var index = -1, - includes = arrayIncludes, - length = array.length, - isCommon = true, - result = [], - seen = result; - - if (comparator) { - isCommon = false; - includes = arrayIncludesWith; - } - else if (length >= LARGE_ARRAY_SIZE) { - var set = iteratee ? null : createSet(array); - if (set) { - return setToArray(set); - } - isCommon = false; - includes = cacheHas; - seen = new SetCache; - } - else { - seen = iteratee ? [] : result; - } - outer: - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value) : value; - - value = (comparator || value !== 0) ? value : 0; - if (isCommon && computed === computed) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (!includes(seen, computed, comparator)) { - if (seen !== result) { - seen.push(computed); - } - result.push(value); - } - } - return result; - } - - /** - * The base implementation of `_.unset`. - * - * @private - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - */ - function baseUnset(object, path) { - path = isKey(path, object) ? [path] : castPath(path); - object = parent(object, path); - - var key = toKey(last(path)); - return !(object != null && baseHas(object, key)) || delete object[key]; - } - - /** - * The base implementation of `_.update`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to update. - * @param {Function} updater The function to produce the updated value. - * @param {Function} [customizer] The function to customize path creation. - * @returns {Object} Returns `object`. - */ - function baseUpdate(object, path, updater, customizer) { - return baseSet(object, path, updater(baseGet(object, path)), customizer); - } - - /** - * The base implementation of methods like `_.dropWhile` and `_.takeWhile` - * without support for iteratee shorthands. - * - * @private - * @param {Array} array The array to query. - * @param {Function} predicate The function invoked per iteration. - * @param {boolean} [isDrop] Specify dropping elements instead of taking them. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the slice of `array`. - */ - function baseWhile(array, predicate, isDrop, fromRight) { - var length = array.length, - index = fromRight ? length : -1; - - while ((fromRight ? index-- : ++index < length) && - predicate(array[index], index, array)) {} - - return isDrop - ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) - : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); - } - - /** - * The base implementation of `wrapperValue` which returns the result of - * performing a sequence of actions on the unwrapped `value`, where each - * successive action is supplied the return value of the previous. - * - * @private - * @param {*} value The unwrapped value. - * @param {Array} actions Actions to perform to resolve the unwrapped value. - * @returns {*} Returns the resolved value. - */ - function baseWrapperValue(value, actions) { - var result = value; - if (result instanceof LazyWrapper) { - result = result.value(); - } - return arrayReduce(actions, function(result, action) { - return action.func.apply(action.thisArg, arrayPush([result], action.args)); - }, result); - } - - /** - * The base implementation of methods like `_.xor`, without support for - * iteratee shorthands, that accepts an array of arrays to inspect. - * - * @private - * @param {Array} arrays The arrays to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of values. - */ - function baseXor(arrays, iteratee, comparator) { - var index = -1, - length = arrays.length; - - while (++index < length) { - var result = result - ? arrayPush( - baseDifference(result, arrays[index], iteratee, comparator), - baseDifference(arrays[index], result, iteratee, comparator) - ) - : arrays[index]; - } - return (result && result.length) ? baseUniq(result, iteratee, comparator) : []; - } - - /** - * This base implementation of `_.zipObject` which assigns values using `assignFunc`. - * - * @private - * @param {Array} props The property identifiers. - * @param {Array} values The property values. - * @param {Function} assignFunc The function to assign values. - * @returns {Object} Returns the new object. - */ - function baseZipObject(props, values, assignFunc) { - var index = -1, - length = props.length, - valsLength = values.length, - result = {}; - - while (++index < length) { - var value = index < valsLength ? values[index] : undefined; - assignFunc(result, props[index], value); - } - return result; - } - - /** - * Casts `value` to an empty array if it's not an array like object. - * - * @private - * @param {*} value The value to inspect. - * @returns {Array|Object} Returns the cast array-like object. - */ - function castArrayLikeObject(value) { - return isArrayLikeObject(value) ? value : []; - } - - /** - * Casts `value` to `identity` if it's not a function. - * - * @private - * @param {*} value The value to inspect. - * @returns {Function} Returns cast function. - */ - function castFunction(value) { - return typeof value == 'function' ? value : identity; - } - - /** - * Casts `value` to a path array if it's not one. - * - * @private - * @param {*} value The value to inspect. - * @returns {Array} Returns the cast property path array. - */ - function castPath(value) { - return isArray(value) ? value : stringToPath(value); - } - - /** - * Casts `array` to a slice if it's needed. - * - * @private - * @param {Array} array The array to inspect. - * @param {number} start The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the cast slice. - */ - function castSlice(array, start, end) { - var length = array.length; - end = end === undefined ? length : end; - return (!start && end >= length) ? array : baseSlice(array, start, end); - } - - /** - * Creates a clone of `buffer`. - * - * @private - * @param {Buffer} buffer The buffer to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Buffer} Returns the cloned buffer. - */ - function cloneBuffer(buffer, isDeep) { - if (isDeep) { - return buffer.slice(); - } - var result = new buffer.constructor(buffer.length); - buffer.copy(result); - return result; - } - - /** - * Creates a clone of `arrayBuffer`. - * - * @private - * @param {ArrayBuffer} arrayBuffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. - */ - function cloneArrayBuffer(arrayBuffer) { - var result = new arrayBuffer.constructor(arrayBuffer.byteLength); - new Uint8Array(result).set(new Uint8Array(arrayBuffer)); - return result; - } - - /** - * Creates a clone of `dataView`. - * - * @private - * @param {Object} dataView The data view to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned data view. - */ - function cloneDataView(dataView, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer; - return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength); - } - - /** - * Creates a clone of `map`. - * - * @private - * @param {Object} map The map to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned map. - */ - function cloneMap(map, isDeep, cloneFunc) { - var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map); - return arrayReduce(array, addMapEntry, new map.constructor); - } - - /** - * Creates a clone of `regexp`. - * - * @private - * @param {Object} regexp The regexp to clone. - * @returns {Object} Returns the cloned regexp. - */ - function cloneRegExp(regexp) { - var result = new regexp.constructor(regexp.source, reFlags.exec(regexp)); - result.lastIndex = regexp.lastIndex; - return result; - } - - /** - * Creates a clone of `set`. - * - * @private - * @param {Object} set The set to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned set. - */ - function cloneSet(set, isDeep, cloneFunc) { - var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set); - return arrayReduce(array, addSetEntry, new set.constructor); - } - - /** - * Creates a clone of the `symbol` object. - * - * @private - * @param {Object} symbol The symbol object to clone. - * @returns {Object} Returns the cloned symbol object. - */ - function cloneSymbol(symbol) { - return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {}; - } - - /** - * Creates a clone of `typedArray`. - * - * @private - * @param {Object} typedArray The typed array to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the cloned typed array. - */ - function cloneTypedArray(typedArray, isDeep) { - var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer; - return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length); - } - - /** - * Compares values to sort them in ascending order. - * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {number} Returns the sort order indicator for `value`. - */ - function compareAscending(value, other) { - if (value !== other) { - var valIsDefined = value !== undefined, - valIsNull = value === null, - valIsReflexive = value === value, - valIsSymbol = isSymbol(value); - - var othIsDefined = other !== undefined, - othIsNull = other === null, - othIsReflexive = other === other, - othIsSymbol = isSymbol(other); - - if ((!othIsNull && !othIsSymbol && !valIsSymbol && value > other) || - (valIsSymbol && othIsDefined && othIsReflexive && !othIsNull && !othIsSymbol) || - (valIsNull && othIsDefined && othIsReflexive) || - (!valIsDefined && othIsReflexive) || - !valIsReflexive) { - return 1; - } - if ((!valIsNull && !valIsSymbol && !othIsSymbol && value < other) || - (othIsSymbol && valIsDefined && valIsReflexive && !valIsNull && !valIsSymbol) || - (othIsNull && valIsDefined && valIsReflexive) || - (!othIsDefined && valIsReflexive) || - !othIsReflexive) { - return -1; - } - } - return 0; - } - - /** - * Used by `_.orderBy` to compare multiple properties of a value to another - * and stable sort them. - * - * If `orders` is unspecified, all values are sorted in ascending order. Otherwise, - * specify an order of "desc" for descending or "asc" for ascending sort order - * of corresponding values. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {boolean[]|string[]} orders The order to sort by for each property. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareMultiple(object, other, orders) { - var index = -1, - objCriteria = object.criteria, - othCriteria = other.criteria, - length = objCriteria.length, - ordersLength = orders.length; - - while (++index < length) { - var result = compareAscending(objCriteria[index], othCriteria[index]); - if (result) { - if (index >= ordersLength) { - return result; - } - var order = orders[index]; - return result * (order == 'desc' ? -1 : 1); - } - } - // Fixes an `Array#sort` bug in the JS engine embedded in Adobe applications - // that causes it, under certain circumstances, to provide the same value for - // `object` and `other`. See https://github.com/jashkenas/underscore/pull/1247 - // for more details. - // - // This also ensures a stable sort in V8 and other engines. - // See https://bugs.chromium.org/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; - } - - /** - * Creates an array that is the composition of partially applied arguments, - * placeholders, and provided arguments into a single array of arguments. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to prepend to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgs(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersLength = holders.length, - leftIndex = -1, - leftLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(leftLength + rangeLength), - isUncurried = !isCurried; - - while (++leftIndex < leftLength) { - result[leftIndex] = partials[leftIndex]; - } - while (++argsIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[holders[argsIndex]] = args[argsIndex]; - } - } - while (rangeLength--) { - result[leftIndex++] = args[argsIndex++]; - } - return result; - } - - /** - * This function is like `composeArgs` except that the arguments composition - * is tailored for `_.partialRight`. - * - * @private - * @param {Array} args The provided arguments. - * @param {Array} partials The arguments to append to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @params {boolean} [isCurried] Specify composing for a curried function. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgsRight(args, partials, holders, isCurried) { - var argsIndex = -1, - argsLength = args.length, - holdersIndex = -1, - holdersLength = holders.length, - rightIndex = -1, - rightLength = partials.length, - rangeLength = nativeMax(argsLength - holdersLength, 0), - result = Array(rangeLength + rightLength), - isUncurried = !isCurried; - - while (++argsIndex < rangeLength) { - result[argsIndex] = args[argsIndex]; - } - var offset = argsIndex; - while (++rightIndex < rightLength) { - result[offset + rightIndex] = partials[rightIndex]; - } - while (++holdersIndex < holdersLength) { - if (isUncurried || argsIndex < argsLength) { - result[offset + holders[holdersIndex]] = args[argsIndex++]; - } - } - return result; - } - - /** - * Copies the values of `source` to `array`. - * - * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. - */ - function copyArray(source, array) { - var index = -1, - length = source.length; - - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; - } - return array; - } - - /** - * Copies properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property identifiers to copy. - * @param {Object} [object={}] The object to copy properties to. - * @param {Function} [customizer] The function to customize copied values. - * @returns {Object} Returns `object`. - */ - function copyObject(source, props, object, customizer) { - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - - var newValue = customizer - ? customizer(object[key], source[key], key, object, source) - : undefined; - - assignValue(object, key, newValue === undefined ? source[key] : newValue); - } - return object; - } - - /** - * Copies own symbol properties of `source` to `object`. - * - * @private - * @param {Object} source The object to copy symbols from. - * @param {Object} [object={}] The object to copy symbols to. - * @returns {Object} Returns `object`. - */ - function copySymbols(source, object) { - return copyObject(source, getSymbols(source), object); - } - - /** - * Creates a function like `_.groupBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} [initializer] The accumulator object initializer. - * @returns {Function} Returns the new aggregator function. - */ - function createAggregator(setter, initializer) { - return function(collection, iteratee) { - var func = isArray(collection) ? arrayAggregator : baseAggregator, - accumulator = initializer ? initializer() : {}; - - return func(collection, setter, getIteratee(iteratee, 2), accumulator); - }; - } - - /** - * Creates a function like `_.assign`. - * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return baseRest(function(object, sources) { - var index = -1, - length = sources.length, - customizer = length > 1 ? sources[length - 1] : undefined, - guard = length > 2 ? sources[2] : undefined; - - customizer = (assigner.length > 3 && typeof customizer == 'function') - ? (length--, customizer) - : undefined; - - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? undefined : customizer; - length = 1; - } - object = Object(object); - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, index, customizer); - } - } - return object; - }); - } - - /** - * Creates a `baseEach` or `baseEachRight` function. - * - * @private - * @param {Function} eachFunc The function to iterate over a collection. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseEach(eachFunc, fromRight) { - return function(collection, iteratee) { - if (collection == null) { - return collection; - } - if (!isArrayLike(collection)) { - return eachFunc(collection, iteratee); - } - var length = collection.length, - index = fromRight ? length : -1, - iterable = Object(collection); - - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; - } - - /** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } - - /** - * Creates a function that wraps `func` to invoke it with the optional `this` - * binding of `thisArg`. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createBind(func, bitmask, thisArg) { - var isBind = bitmask & BIND_FLAG, - Ctor = createCtor(func); - - function wrapper() { - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(isBind ? thisArg : this, arguments); - } - return wrapper; - } - - /** - * Creates a function like `_.lowerFirst`. - * - * @private - * @param {string} methodName The name of the `String` case method to use. - * @returns {Function} Returns the new case function. - */ - function createCaseFirst(methodName) { - return function(string) { - string = toString(string); - - var strSymbols = reHasComplexSymbol.test(string) - ? stringToArray(string) - : undefined; - - var chr = strSymbols - ? strSymbols[0] - : string.charAt(0); - - var trailing = strSymbols - ? castSlice(strSymbols, 1).join('') - : string.slice(1); - - return chr[methodName]() + trailing; - }; - } - - /** - * Creates a function like `_.camelCase`. - * - * @private - * @param {Function} callback The function to combine each word. - * @returns {Function} Returns the new compounder function. - */ - function createCompounder(callback) { - return function(string) { - return arrayReduce(words(deburr(string).replace(reApos, '')), callback, ''); - }; - } - - /** - * Creates a function that produces an instance of `Ctor` regardless of - * whether it was invoked as part of a `new` expression or by `call` or `apply`. - * - * @private - * @param {Function} Ctor The constructor to wrap. - * @returns {Function} Returns the new wrapped function. - */ - function createCtor(Ctor) { - return function() { - // Use a `switch` statement to work with class constructors. See - // http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist - // for more details. - var args = arguments; - switch (args.length) { - case 0: return new Ctor; - case 1: return new Ctor(args[0]); - case 2: return new Ctor(args[0], args[1]); - case 3: return new Ctor(args[0], args[1], args[2]); - case 4: return new Ctor(args[0], args[1], args[2], args[3]); - case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); - case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); - case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); - } - var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, args); - - // Mimic the constructor's `return` behavior. - // See https://es5.github.io/#x13.2.2 for more details. - return isObject(result) ? result : thisBinding; - }; - } - - /** - * Creates a function that wraps `func` to enable currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {number} arity The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createCurry(func, bitmask, arity) { - var Ctor = createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length, - placeholder = getHolder(wrapper); - - while (index--) { - args[index] = arguments[index]; - } - var holders = (length < 3 && args[0] !== placeholder && args[length - 1] !== placeholder) - ? [] - : replaceHolders(args, placeholder); - - length -= holders.length; - if (length < arity) { - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, undefined, - args, holders, undefined, undefined, arity - length); - } - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return apply(fn, this, args); - } - return wrapper; - } - - /** - * Creates a `_.find` or `_.findLast` function. - * - * @private - * @param {Function} findIndexFunc The function to find the collection index. - * @returns {Function} Returns the new find function. - */ - function createFind(findIndexFunc) { - return function(collection, predicate, fromIndex) { - var iterable = Object(collection); - if (!isArrayLike(collection)) { - var iteratee = getIteratee(predicate, 3); - collection = keys(collection); - predicate = function(key) { return iteratee(iterable[key], key, iterable); }; - } - var index = findIndexFunc(collection, predicate, fromIndex); - return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined; - }; - } - - /** - * Creates a `_.flow` or `_.flowRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new flow function. - */ - function createFlow(fromRight) { - return baseRest(function(funcs) { - funcs = baseFlatten(funcs, 1); - - var length = funcs.length, - index = length, - prereq = LodashWrapper.prototype.thru; - - if (fromRight) { - funcs.reverse(); - } - while (index--) { - var func = funcs[index]; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (prereq && !wrapper && getFuncName(func) == 'wrapper') { - var wrapper = new LodashWrapper([], true); - } - } - index = wrapper ? index : length; - while (++index < length) { - func = funcs[index]; - - var funcName = getFuncName(func), - data = funcName == 'wrapper' ? getData(func) : undefined; - - if (data && isLaziable(data[0]) && - data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && - !data[4].length && data[9] == 1 - ) { - wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); - } else { - wrapper = (func.length == 1 && isLaziable(func)) - ? wrapper[funcName]() - : wrapper.thru(func); - } - } - return function() { - var args = arguments, - value = args[0]; - - if (wrapper && args.length == 1 && - isArray(value) && value.length >= LARGE_ARRAY_SIZE) { - return wrapper.plant(value).value(); - } - var index = 0, - result = length ? funcs[index].apply(this, args) : value; - - while (++index < length) { - result = funcs[index].call(this, result); - } - return result; - }; - }); - } - - /** - * Creates a function that wraps `func` to invoke it with optional `this` - * binding of `thisArg`, partial application, and currying. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [partialsRight] The arguments to append to those provided - * to the new function. - * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { - var isAry = bitmask & ARY_FLAG, - isBind = bitmask & BIND_FLAG, - isBindKey = bitmask & BIND_KEY_FLAG, - isCurried = bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG), - isFlip = bitmask & FLIP_FLAG, - Ctor = isBindKey ? undefined : createCtor(func); - - function wrapper() { - var length = arguments.length, - args = Array(length), - index = length; - - while (index--) { - args[index] = arguments[index]; - } - if (isCurried) { - var placeholder = getHolder(wrapper), - holdersCount = countHolders(args, placeholder); - } - if (partials) { - args = composeArgs(args, partials, holders, isCurried); - } - if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight, isCurried); - } - length -= holdersCount; - if (isCurried && length < arity) { - var newHolders = replaceHolders(args, placeholder); - return createRecurry( - func, bitmask, createHybrid, wrapper.placeholder, thisArg, - args, newHolders, argPos, ary, arity - length - ); - } - var thisBinding = isBind ? thisArg : this, - fn = isBindKey ? thisBinding[func] : func; - - length = args.length; - if (argPos) { - args = reorder(args, argPos); - } else if (isFlip && length > 1) { - args.reverse(); - } - if (isAry && ary < length) { - args.length = ary; - } - if (this && this !== root && this instanceof wrapper) { - fn = Ctor || createCtor(fn); - } - return fn.apply(thisBinding, args); - } - return wrapper; - } - - /** - * Creates a function like `_.invertBy`. - * - * @private - * @param {Function} setter The function to set accumulator values. - * @param {Function} toIteratee The function to resolve iteratees. - * @returns {Function} Returns the new inverter function. - */ - function createInverter(setter, toIteratee) { - return function(object, iteratee) { - return baseInverter(object, setter, toIteratee(iteratee), {}); - }; - } - - /** - * Creates a function that performs a mathematical operation on two values. - * - * @private - * @param {Function} operator The function to perform the operation. - * @param {number} [defaultValue] The value used for `undefined` arguments. - * @returns {Function} Returns the new mathematical operation function. - */ - function createMathOperation(operator, defaultValue) { - return function(value, other) { - var result; - if (value === undefined && other === undefined) { - return defaultValue; - } - if (value !== undefined) { - result = value; - } - if (other !== undefined) { - if (result === undefined) { - return other; - } - if (typeof value == 'string' || typeof other == 'string') { - value = baseToString(value); - other = baseToString(other); - } else { - value = baseToNumber(value); - other = baseToNumber(other); - } - result = operator(value, other); - } - return result; - }; - } - - /** - * Creates a function like `_.over`. - * - * @private - * @param {Function} arrayFunc The function to iterate over iteratees. - * @returns {Function} Returns the new over function. - */ - function createOver(arrayFunc) { - return baseRest(function(iteratees) { - iteratees = (iteratees.length == 1 && isArray(iteratees[0])) - ? arrayMap(iteratees[0], baseUnary(getIteratee())) - : arrayMap(baseFlatten(iteratees, 1), baseUnary(getIteratee())); - - return baseRest(function(args) { - var thisArg = this; - return arrayFunc(iteratees, function(iteratee) { - return apply(iteratee, thisArg, args); - }); - }); - }); - } - - /** - * Creates the padding for `string` based on `length`. The `chars` string - * is truncated if the number of characters exceeds `length`. - * - * @private - * @param {number} length The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padding for `string`. - */ - function createPadding(length, chars) { - chars = chars === undefined ? ' ' : baseToString(chars); - - var charsLength = chars.length; - if (charsLength < 2) { - return charsLength ? baseRepeat(chars, length) : chars; - } - var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); - return reHasComplexSymbol.test(chars) - ? castSlice(stringToArray(result), 0, length).join('') - : result.slice(0, length); - } - - /** - * Creates a function that wraps `func` to invoke it with the `this` binding - * of `thisArg` and `partials` prepended to the arguments it receives. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {*} thisArg The `this` binding of `func`. - * @param {Array} partials The arguments to prepend to those provided to - * the new function. - * @returns {Function} Returns the new wrapped function. - */ - function createPartial(func, bitmask, thisArg, partials) { - var isBind = bitmask & BIND_FLAG, - Ctor = createCtor(func); - - function wrapper() { - var argsIndex = -1, - argsLength = arguments.length, - leftIndex = -1, - leftLength = partials.length, - args = Array(leftLength + argsLength), - fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - - while (++leftIndex < leftLength) { - args[leftIndex] = partials[leftIndex]; - } - while (argsLength--) { - args[leftIndex++] = arguments[++argsIndex]; - } - return apply(fn, isBind ? thisArg : this, args); - } - return wrapper; - } - - /** - * Creates a `_.range` or `_.rangeRight` function. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new range function. - */ - function createRange(fromRight) { - return function(start, end, step) { - if (step && typeof step != 'number' && isIterateeCall(start, end, step)) { - end = step = undefined; - } - // Ensure the sign of `-0` is preserved. - start = toFinite(start); - if (end === undefined) { - end = start; - start = 0; - } else { - end = toFinite(end); - } - step = step === undefined ? (start < end ? 1 : -1) : toFinite(step); - return baseRange(start, end, step, fromRight); - }; - } - - /** - * Creates a function that performs a relational operation on two values. - * - * @private - * @param {Function} operator The function to perform the operation. - * @returns {Function} Returns the new relational operation function. - */ - function createRelationalOperation(operator) { - return function(value, other) { - if (!(typeof value == 'string' && typeof other == 'string')) { - value = toNumber(value); - other = toNumber(other); - } - return operator(value, other); - }; - } - - /** - * Creates a function that wraps `func` to continue currying. - * - * @private - * @param {Function} func The function to wrap. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @param {Function} wrapFunc The function to create the `func` wrapper. - * @param {*} placeholder The placeholder value. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to prepend to those provided to - * the new function. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createRecurry(func, bitmask, wrapFunc, placeholder, thisArg, partials, holders, argPos, ary, arity) { - var isCurry = bitmask & CURRY_FLAG, - newHolders = isCurry ? holders : undefined, - newHoldersRight = isCurry ? undefined : holders, - newPartials = isCurry ? partials : undefined, - newPartialsRight = isCurry ? undefined : partials; - - bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); - - if (!(bitmask & CURRY_BOUND_FLAG)) { - bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); - } - var newData = [ - func, bitmask, thisArg, newPartials, newHolders, newPartialsRight, - newHoldersRight, argPos, ary, arity - ]; - - var result = wrapFunc.apply(undefined, newData); - if (isLaziable(func)) { - setData(result, newData); - } - result.placeholder = placeholder; - return setWrapToString(result, func, bitmask); - } - - /** - * Creates a function like `_.round`. - * - * @private - * @param {string} methodName The name of the `Math` method to use when rounding. - * @returns {Function} Returns the new round function. - */ - function createRound(methodName) { - var func = Math[methodName]; - return function(number, precision) { - number = toNumber(number); - precision = nativeMin(toInteger(precision), 292); - if (precision) { - // Shift with exponential notation to avoid floating-point issues. - // See [MDN](https://mdn.io/round#Examples) for more details. - var pair = (toString(number) + 'e').split('e'), - value = func(pair[0] + 'e' + (+pair[1] + precision)); - - pair = (toString(value) + 'e').split('e'); - return +(pair[0] + 'e' + (+pair[1] - precision)); - } - return func(number); - }; - } - - /** - * Creates a set object of `values`. - * - * @private - * @param {Array} values The values to add to the set. - * @returns {Object} Returns the new set. - */ - var createSet = !(Set && (1 / setToArray(new Set([,-0]))[1]) == INFINITY) ? noop : function(values) { - return new Set(values); - }; - - /** - * Creates a `_.toPairs` or `_.toPairsIn` function. - * - * @private - * @param {Function} keysFunc The function to get the keys of a given object. - * @returns {Function} Returns the new pairs function. - */ - function createToPairs(keysFunc) { - return function(object) { - var tag = getTag(object); - if (tag == mapTag) { - return mapToArray(object); - } - if (tag == setTag) { - return setToPairs(object); - } - return baseToPairs(object, keysFunc(object)); - }; - } - - /** - * Creates a function that either curries or invokes `func` with optional - * `this` binding and partially applied arguments. - * - * @private - * @param {Function|string} func The function or method name to wrap. - * @param {number} bitmask The bitmask flags. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` or `_.curryRight` of a bound function - * 8 - `_.curry` - * 16 - `_.curryRight` - * 32 - `_.partial` - * 64 - `_.partialRight` - * 128 - `_.rearg` - * 256 - `_.ary` - * 512 - `_.flip` - * @param {*} [thisArg] The `this` binding of `func`. - * @param {Array} [partials] The arguments to be partially applied. - * @param {Array} [holders] The `partials` placeholder indexes. - * @param {Array} [argPos] The argument positions of the new function. - * @param {number} [ary] The arity cap of `func`. - * @param {number} [arity] The arity of `func`. - * @returns {Function} Returns the new wrapped function. - */ - function createWrap(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { - var isBindKey = bitmask & BIND_KEY_FLAG; - if (!isBindKey && typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = partials ? partials.length : 0; - if (!length) { - bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); - partials = holders = undefined; - } - ary = ary === undefined ? ary : nativeMax(toInteger(ary), 0); - arity = arity === undefined ? arity : toInteger(arity); - length -= holders ? holders.length : 0; - - if (bitmask & PARTIAL_RIGHT_FLAG) { - var partialsRight = partials, - holdersRight = holders; - - partials = holders = undefined; - } - var data = isBindKey ? undefined : getData(func); - - var newData = [ - func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, - argPos, ary, arity - ]; - - if (data) { - mergeData(newData, data); - } - func = newData[0]; - bitmask = newData[1]; - thisArg = newData[2]; - partials = newData[3]; - holders = newData[4]; - arity = newData[9] = newData[9] == null - ? (isBindKey ? 0 : func.length) - : nativeMax(newData[9] - length, 0); - - if (!arity && bitmask & (CURRY_FLAG | CURRY_RIGHT_FLAG)) { - bitmask &= ~(CURRY_FLAG | CURRY_RIGHT_FLAG); - } - if (!bitmask || bitmask == BIND_FLAG) { - var result = createBind(func, bitmask, thisArg); - } else if (bitmask == CURRY_FLAG || bitmask == CURRY_RIGHT_FLAG) { - result = createCurry(func, bitmask, arity); - } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !holders.length) { - result = createPartial(func, bitmask, thisArg, partials); - } else { - result = createHybrid.apply(undefined, newData); - } - var setter = data ? baseSetData : setData; - return setWrapToString(setter(result, newData), func, bitmask); - } - - /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. - * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} customizer The function to customize comparisons. - * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` - * for more details. - * @param {Object} stack Tracks traversed `array` and `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. - */ - function equalArrays(array, other, equalFunc, customizer, bitmask, stack) { - var isPartial = bitmask & PARTIAL_COMPARE_FLAG, - arrLength = array.length, - othLength = other.length; - - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(array); - if (stacked && stack.get(other)) { - return stacked == other; - } - var index = -1, - result = true, - seen = (bitmask & UNORDERED_COMPARE_FLAG) ? new SetCache : undefined; - - stack.set(array, other); - stack.set(other, array); - - // Ignore non-index properties. - while (++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, arrValue, index, other, array, stack) - : customizer(arrValue, othValue, index, array, other, stack); - } - if (compared !== undefined) { - if (compared) { - continue; - } - result = false; - break; - } - // Recursively compare arrays (susceptible to call stack limits). - if (seen) { - if (!arraySome(other, function(othValue, othIndex) { - if (!seen.has(othIndex) && - (arrValue === othValue || equalFunc(arrValue, othValue, customizer, bitmask, stack))) { - return seen.add(othIndex); - } - })) { - result = false; - break; - } - } else if (!( - arrValue === othValue || - equalFunc(arrValue, othValue, customizer, bitmask, stack) - )) { - result = false; - break; - } - } - stack['delete'](array); - stack['delete'](other); - return result; - } - - /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. - * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} customizer The function to customize comparisons. - * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` - * for more details. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalByTag(object, other, tag, equalFunc, customizer, bitmask, stack) { - switch (tag) { - case dataViewTag: - if ((object.byteLength != other.byteLength) || - (object.byteOffset != other.byteOffset)) { - return false; - } - object = object.buffer; - other = other.buffer; - - case arrayBufferTag: - if ((object.byteLength != other.byteLength) || - !equalFunc(new Uint8Array(object), new Uint8Array(other))) { - return false; - } - return true; - - case boolTag: - case dateTag: - case numberTag: - // Coerce booleans to `1` or `0` and dates to milliseconds. - // Invalid dates are coerced to `NaN`. - return eq(+object, +other); - - case errorTag: - return object.name == other.name && object.message == other.message; - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings, primitives and objects, - // as equal. See http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.tostring - // for more details. - return object == (other + ''); - - case mapTag: - var convert = mapToArray; - - case setTag: - var isPartial = bitmask & PARTIAL_COMPARE_FLAG; - convert || (convert = setToArray); - - if (object.size != other.size && !isPartial) { - return false; - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked) { - return stacked == other; - } - bitmask |= UNORDERED_COMPARE_FLAG; - - // Recursively compare objects (susceptible to call stack limits). - stack.set(object, other); - var result = equalArrays(convert(object), convert(other), equalFunc, customizer, bitmask, stack); - stack['delete'](object); - return result; - - case symbolTag: - if (symbolValueOf) { - return symbolValueOf.call(object) == symbolValueOf.call(other); - } - } - return false; - } - - /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. - * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} customizer The function to customize comparisons. - * @param {number} bitmask The bitmask of comparison flags. See `baseIsEqual` - * for more details. - * @param {Object} stack Tracks traversed `object` and `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function equalObjects(object, other, equalFunc, customizer, bitmask, stack) { - var isPartial = bitmask & PARTIAL_COMPARE_FLAG, - objProps = keys(object), - objLength = objProps.length, - othProps = keys(other), - othLength = othProps.length; - - if (objLength != othLength && !isPartial) { - return false; - } - var index = objLength; - while (index--) { - var key = objProps[index]; - if (!(isPartial ? key in other : baseHas(other, key))) { - return false; - } - } - // Assume cyclic values are equal. - var stacked = stack.get(object); - if (stacked && stack.get(other)) { - return stacked == other; - } - var result = true; - stack.set(object, other); - stack.set(other, object); - - var skipCtor = isPartial; - while (++index < objLength) { - key = objProps[index]; - var objValue = object[key], - othValue = other[key]; - - if (customizer) { - var compared = isPartial - ? customizer(othValue, objValue, key, other, object, stack) - : customizer(objValue, othValue, key, object, other, stack); - } - // Recursively compare objects (susceptible to call stack limits). - if (!(compared === undefined - ? (objValue === othValue || equalFunc(objValue, othValue, customizer, bitmask, stack)) - : compared - )) { - result = false; - break; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (result && !skipCtor) { - var objCtor = object.constructor, - othCtor = other.constructor; - - // Non `Object` object instances with different constructors are not equal. - if (objCtor != othCtor && - ('constructor' in object && 'constructor' in other) && - !(typeof objCtor == 'function' && objCtor instanceof objCtor && - typeof othCtor == 'function' && othCtor instanceof othCtor)) { - result = false; - } - } - stack['delete'](object); - stack['delete'](other); - return result; - } - - /** - * Creates an array of own enumerable property names and symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeys(object) { - return baseGetAllKeys(object, keys, getSymbols); - } - - /** - * Creates an array of own and inherited enumerable property names and - * symbols of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names and symbols. - */ - function getAllKeysIn(object) { - return baseGetAllKeys(object, keysIn, getSymbolsIn); - } - - /** - * Gets metadata for `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {*} Returns the metadata for `func`. - */ - var getData = !metaMap ? noop : function(func) { - return metaMap.get(func); - }; - - /** - * Gets the name of `func`. - * - * @private - * @param {Function} func The function to query. - * @returns {string} Returns the function name. - */ - function getFuncName(func) { - var result = (func.name + ''), - array = realNames[result], - length = hasOwnProperty.call(realNames, result) ? array.length : 0; - - while (length--) { - var data = array[length], - otherFunc = data.func; - if (otherFunc == null || otherFunc == func) { - return data.name; - } - } - return result; - } - - /** - * Gets the argument placeholder value for `func`. - * - * @private - * @param {Function} func The function to inspect. - * @returns {*} Returns the placeholder value. - */ - function getHolder(func) { - var object = hasOwnProperty.call(lodash, 'placeholder') ? lodash : func; - return object.placeholder; - } - - /** - * Gets the appropriate "iteratee" function. If `_.iteratee` is customized, - * this function returns the custom method, otherwise it returns `baseIteratee`. - * If arguments are provided, the chosen function is invoked with them and - * its result is returned. - * - * @private - * @param {*} [value] The value to convert to an iteratee. - * @param {number} [arity] The arity of the created iteratee. - * @returns {Function} Returns the chosen function or its result. - */ - function getIteratee() { - var result = lodash.iteratee || iteratee; - result = result === iteratee ? baseIteratee : result; - return arguments.length ? result(arguments[0], arguments[1]) : result; - } - - /** - * Gets the "length" property value of `object`. - * - * **Note:** This function is used to avoid a - * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects - * Safari on at least iOS 8.1-8.3 ARM64. - * - * @private - * @param {Object} object The object to query. - * @returns {*} Returns the "length" value. - */ - var getLength = baseProperty('length'); - - /** - * Gets the data for `map`. - * - * @private - * @param {Object} map The map to query. - * @param {string} key The reference key. - * @returns {*} Returns the map data. - */ - function getMapData(map, key) { - var data = map.__data__; - return isKeyable(key) - ? data[typeof key == 'string' ? 'string' : 'hash'] - : data.map; - } - - /** - * Gets the property names, values, and compare flags of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the match data of `object`. - */ - function getMatchData(object) { - var result = keys(object), - length = result.length; - - while (length--) { - var key = result[length], - value = object[key]; - - result[length] = [key, value, isStrictComparable(value)]; - } - return result; - } - - /** - * Gets the native function at `key` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {string} key The key of the method to get. - * @returns {*} Returns the function if it's native, else `undefined`. - */ - function getNative(object, key) { - var value = getValue(object, key); - return baseIsNative(value) ? value : undefined; - } - - /** - * Gets the `[[Prototype]]` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {null|Object} Returns the `[[Prototype]]`. - */ - var getPrototype = overArg(nativeGetPrototype, Object); - - /** - * Creates an array of the own enumerable symbol properties of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray; - - /** - * Creates an array of the own and inherited enumerable symbol properties - * of `object`. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbolsIn = !nativeGetSymbols ? stubArray : function(object) { - var result = []; - while (object) { - arrayPush(result, getSymbols(object)); - object = getPrototype(object); - } - return result; - }; - - /** - * Gets the `toStringTag` of `value`. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - var getTag = baseGetTag; - - // Fallback for data views, maps, sets, and weak maps in IE 11, - // for data views in Edge, and promises in Node.js. - if ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) || - (Map && getTag(new Map) != mapTag) || - (Promise && getTag(Promise.resolve()) != promiseTag) || - (Set && getTag(new Set) != setTag) || - (WeakMap && getTag(new WeakMap) != weakMapTag)) { - getTag = function(value) { - var result = objectToString.call(value), - Ctor = result == objectTag ? value.constructor : undefined, - ctorString = Ctor ? toSource(Ctor) : undefined; - - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: return dataViewTag; - case mapCtorString: return mapTag; - case promiseCtorString: return promiseTag; - case setCtorString: return setTag; - case weakMapCtorString: return weakMapTag; - } - } - return result; - }; - } - - /** - * Gets the view, applying any `transforms` to the `start` and `end` positions. - * - * @private - * @param {number} start The start of the view. - * @param {number} end The end of the view. - * @param {Array} transforms The transformations to apply to the view. - * @returns {Object} Returns an object containing the `start` and `end` - * positions of the view. - */ - function getView(start, end, transforms) { - var index = -1, - length = transforms.length; - - while (++index < length) { - var data = transforms[index], - size = data.size; - - switch (data.type) { - case 'drop': start += size; break; - case 'dropRight': end -= size; break; - case 'take': end = nativeMin(end, start + size); break; - case 'takeRight': start = nativeMax(start, end - size); break; - } - } - return { 'start': start, 'end': end }; - } - - /** - * Extracts wrapper details from the `source` body comment. - * - * @private - * @param {string} source The source to inspect. - * @returns {Array} Returns the wrapper details. - */ - function getWrapDetails(source) { - var match = source.match(reWrapDetails); - return match ? match[1].split(reSplitDetails) : []; - } - - /** - * Checks if `path` exists on `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @param {Function} hasFunc The function to check properties. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - */ - function hasPath(object, path, hasFunc) { - path = isKey(path, object) ? [path] : castPath(path); - - var result, - index = -1, - length = path.length; - - while (++index < length) { - var key = toKey(path[index]); - if (!(result = object != null && hasFunc(object, key))) { - break; - } - object = object[key]; - } - if (result) { - return result; - } - var length = object ? object.length : 0; - return !!length && isLength(length) && isIndex(key, length) && - (isArray(object) || isString(object) || isArguments(object)); - } - - /** - * Initializes an array clone. - * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. - */ - function initCloneArray(array) { - var length = array.length, - result = array.constructor(length); - - // Add properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; - } - return result; - } - - /** - * Initializes an object clone. - * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneObject(object) { - return (typeof object.constructor == 'function' && !isPrototype(object)) - ? baseCreate(getPrototype(object)) - : {}; - } - - /** - * Initializes an object clone based on its `toStringTag`. - * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. - * - * @private - * @param {Object} object The object to clone. - * @param {string} tag The `toStringTag` of the object to clone. - * @param {Function} cloneFunc The function to clone values. - * @param {boolean} [isDeep] Specify a deep clone. - * @returns {Object} Returns the initialized clone. - */ - function initCloneByTag(object, tag, cloneFunc, isDeep) { - var Ctor = object.constructor; - switch (tag) { - case arrayBufferTag: - return cloneArrayBuffer(object); - - case boolTag: - case dateTag: - return new Ctor(+object); - - case dataViewTag: - return cloneDataView(object, isDeep); - - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - return cloneTypedArray(object, isDeep); - - case mapTag: - return cloneMap(object, isDeep, cloneFunc); - - case numberTag: - case stringTag: - return new Ctor(object); - - case regexpTag: - return cloneRegExp(object); - - case setTag: - return cloneSet(object, isDeep, cloneFunc); - - case symbolTag: - return cloneSymbol(object); - } - } - - /** - * Creates an array of index keys for `object` values of arrays, - * `arguments` objects, and strings, otherwise `null` is returned. - * - * @private - * @param {Object} object The object to query. - * @returns {Array|null} Returns index keys, else `null`. - */ - function indexKeys(object) { - var length = object ? object.length : undefined; - if (isLength(length) && - (isArray(object) || isString(object) || isArguments(object))) { - return baseTimes(length, String); - } - return null; - } - - /** - * Inserts wrapper `details` in a comment at the top of the `source` body. - * - * @private - * @param {string} source The source to modify. - * @returns {Array} details The details to insert. - * @returns {string} Returns the modified source. - */ - function insertWrapDetails(source, details) { - var length = details.length, - lastIndex = length - 1; - - details[lastIndex] = (length > 1 ? '& ' : '') + details[lastIndex]; - details = details.join(length > 2 ? ', ' : ' '); - return source.replace(reWrapComment, '{\n/* [wrapped with ' + details + '] */\n'); - } - - /** - * Checks if `value` is a flattenable `arguments` object or array. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is flattenable, else `false`. - */ - function isFlattenable(value) { - return isArray(value) || isArguments(value) || - !!(spreadableSymbol && value && value[spreadableSymbol]); - } - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - length = length == null ? MAX_SAFE_INTEGER : length; - return !!length && - (typeof value == 'number' || reIsUint.test(value)) && - (value > -1 && value % 1 == 0 && value < length); - } - - /** - * Checks if the given arguments are from an iteratee call. - * - * @private - * @param {*} value The potential iteratee value argument. - * @param {*} index The potential iteratee index or key argument. - * @param {*} object The potential iteratee object argument. - * @returns {boolean} Returns `true` if the arguments are from an iteratee call, - * else `false`. - */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; - } - var type = typeof index; - if (type == 'number' - ? (isArrayLike(object) && isIndex(index, object.length)) - : (type == 'string' && index in object) - ) { - return eq(object[index], value); - } - return false; - } - - /** - * Checks if `value` is a property name and not a property path. - * - * @private - * @param {*} value The value to check. - * @param {Object} [object] The object to query keys on. - * @returns {boolean} Returns `true` if `value` is a property name, else `false`. - */ - function isKey(value, object) { - if (isArray(value)) { - return false; - } - var type = typeof value; - if (type == 'number' || type == 'symbol' || type == 'boolean' || - value == null || isSymbol(value)) { - return true; - } - return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || - (object != null && value in Object(object)); - } - - /** - * Checks if `value` is suitable for use as unique object key. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is suitable, else `false`. - */ - function isKeyable(value) { - var type = typeof value; - return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean') - ? (value !== '__proto__') - : (value === null); - } - - /** - * Checks if `func` has a lazy counterpart. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` has a lazy counterpart, - * else `false`. - */ - function isLaziable(func) { - var funcName = getFuncName(func), - other = lodash[funcName]; - - if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { - return false; - } - if (func === other) { - return true; - } - var data = getData(other); - return !!data && func === data[0]; - } - - /** - * Checks if `func` has its source masked. - * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` is masked, else `false`. - */ - function isMasked(func) { - return !!maskSrcKey && (maskSrcKey in func); - } - - /** - * Checks if `func` is capable of being masked. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `func` is maskable, else `false`. - */ - var isMaskable = coreJsData ? isFunction : stubFalse; - - /** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ - function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; - - return value === proto; - } - - /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. - */ - function isStrictComparable(value) { - return value === value && !isObject(value); - } - - /** - * A specialized version of `matchesProperty` for source values suitable - * for strict equality comparisons, i.e. `===`. - * - * @private - * @param {string} key The key of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - */ - function matchesStrictComparable(key, srcValue) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === srcValue && - (srcValue !== undefined || (key in Object(object))); - }; - } - - /** - * Merges the function metadata of `source` into `data`. - * - * Merging metadata reduces the number of wrappers used to invoke a function. - * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` - * may be applied regardless of execution order. Methods like `_.ary` and - * `_.rearg` modify function arguments, making the order in which they are - * executed important, preventing the merging of metadata. However, we make - * an exception for a safe combined case where curried functions have `_.ary` - * and or `_.rearg` applied. - * - * @private - * @param {Array} data The destination metadata. - * @param {Array} source The source metadata. - * @returns {Array} Returns `data`. - */ - function mergeData(data, source) { - var bitmask = data[1], - srcBitmask = source[1], - newBitmask = bitmask | srcBitmask, - isCommon = newBitmask < (BIND_FLAG | BIND_KEY_FLAG | ARY_FLAG); - - var isCombo = - ((srcBitmask == ARY_FLAG) && (bitmask == CURRY_FLAG)) || - ((srcBitmask == ARY_FLAG) && (bitmask == REARG_FLAG) && (data[7].length <= source[8])) || - ((srcBitmask == (ARY_FLAG | REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == CURRY_FLAG)); - - // Exit early if metadata can't be merged. - if (!(isCommon || isCombo)) { - return data; - } - // Use source `thisArg` if available. - if (srcBitmask & BIND_FLAG) { - data[2] = source[2]; - // Set when currying a bound function. - newBitmask |= bitmask & BIND_FLAG ? 0 : CURRY_BOUND_FLAG; - } - // Compose partial arguments. - var value = source[3]; - if (value) { - var partials = data[3]; - data[3] = partials ? composeArgs(partials, value, source[4]) : value; - data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : source[4]; - } - // Compose partial right arguments. - value = source[5]; - if (value) { - partials = data[5]; - data[5] = partials ? composeArgsRight(partials, value, source[6]) : value; - data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : source[6]; - } - // Use source `argPos` if available. - value = source[7]; - if (value) { - data[7] = value; - } - // Use source `ary` if it's smaller. - if (srcBitmask & ARY_FLAG) { - data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); - } - // Use source `arity` if one is not provided. - if (data[9] == null) { - data[9] = source[9]; - } - // Use source `func` and merge bitmasks. - data[0] = source[0]; - data[1] = newBitmask; - - return data; - } - - /** - * Used by `_.defaultsDeep` to customize its `_.merge` use. - * - * @private - * @param {*} objValue The destination value. - * @param {*} srcValue The source value. - * @param {string} key The key of the property to merge. - * @param {Object} object The parent object of `objValue`. - * @param {Object} source The parent object of `srcValue`. - * @param {Object} [stack] Tracks traversed source values and their merged - * counterparts. - * @returns {*} Returns the value to assign. - */ - function mergeDefaults(objValue, srcValue, key, object, source, stack) { - if (isObject(objValue) && isObject(srcValue)) { - // Recursively merge objects and arrays (susceptible to call stack limits). - stack.set(srcValue, objValue); - baseMerge(objValue, srcValue, undefined, mergeDefaults, stack); - stack['delete'](srcValue); - } - return objValue; - } - - /** - * Gets the parent value at `path` of `object`. - * - * @private - * @param {Object} object The object to query. - * @param {Array} path The path to get the parent value of. - * @returns {*} Returns the parent value. - */ - function parent(object, path) { - return path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - } - - /** - * Reorder `array` according to the specified indexes where the element at - * the first index is assigned as the first element, the element at - * the second index is assigned as the second element, and so on. - * - * @private - * @param {Array} array The array to reorder. - * @param {Array} indexes The arranged array indexes. - * @returns {Array} Returns `array`. - */ - function reorder(array, indexes) { - var arrLength = array.length, - length = nativeMin(indexes.length, arrLength), - oldArray = copyArray(array); - - while (length--) { - var index = indexes[length]; - array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; - } - return array; - } - - /** - * Sets metadata for `func`. - * - * **Note:** If this function becomes hot, i.e. is invoked a lot in a short - * period of time, it will trip its breaker and transition to an identity - * function to avoid garbage collection pauses in V8. See - * [V8 issue 2070](https://bugs.chromium.org/p/v8/issues/detail?id=2070) - * for more details. - * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var setData = (function() { - var count = 0, - lastCalled = 0; - - return function(key, value) { - var stamp = now(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return key; - } - } else { - count = 0; - } - return baseSetData(key, value); - }; - }()); - - /** - * Sets the `toString` method of `wrapper` to mimic the source of `reference` - * with wrapper details in a comment at the top of the source body. - * - * @private - * @param {Function} wrapper The function to modify. - * @param {Function} reference The reference function. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Function} Returns `wrapper`. - */ - var setWrapToString = !defineProperty ? identity : function(wrapper, reference, bitmask) { - var source = (reference + ''); - return defineProperty(wrapper, 'toString', { - 'configurable': true, - 'enumerable': false, - 'value': constant(insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))) - }); - }; - - /** - * Converts `string` to a property path array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the property path array. - */ - var stringToPath = memoize(function(string) { - string = toString(string); - - var result = []; - if (reLeadingDot.test(string)) { - result.push(''); - } - string.replace(rePropName, function(match, number, quote, string) { - result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; - }); - - /** - * Converts `value` to a string key if it's not a string or symbol. - * - * @private - * @param {*} value The value to inspect. - * @returns {string|symbol} Returns the key. - */ - function toKey(value) { - if (typeof value == 'string' || isSymbol(value)) { - return value; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * Converts `func` to its source code. - * - * @private - * @param {Function} func The function to process. - * @returns {string} Returns the source code. - */ - function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e) {} - try { - return (func + ''); - } catch (e) {} - } - return ''; - } - - /** - * Updates wrapper `details` based on `bitmask` flags. - * - * @private - * @returns {Array} details The details to modify. - * @param {number} bitmask The bitmask flags. See `createWrap` for more details. - * @returns {Array} Returns `details`. - */ - function updateWrapDetails(details, bitmask) { - arrayEach(wrapFlags, function(pair) { - var value = '_.' + pair[0]; - if ((bitmask & pair[1]) && !arrayIncludes(details, value)) { - details.push(value); - } - }); - return details.sort(); - } - - /** - * Creates a clone of `wrapper`. - * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. - */ - function wrapperClone(wrapper) { - if (wrapper instanceof LazyWrapper) { - return wrapper.clone(); - } - var result = new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__); - result.__actions__ = copyArray(wrapper.__actions__); - result.__index__ = wrapper.__index__; - result.__values__ = wrapper.__values__; - return result; - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of elements split into groups the length of `size`. - * If `array` can't be split evenly, the final chunk will be the remaining - * elements. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to process. - * @param {number} [size=1] The length of each chunk - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the new array of chunks. - * @example - * - * _.chunk(['a', 'b', 'c', 'd'], 2); - * // => [['a', 'b'], ['c', 'd']] - * - * _.chunk(['a', 'b', 'c', 'd'], 3); - * // => [['a', 'b', 'c'], ['d']] - */ - function chunk(array, size, guard) { - if ((guard ? isIterateeCall(array, size, guard) : size === undefined)) { - size = 1; - } else { - size = nativeMax(toInteger(size), 0); - } - var length = array ? array.length : 0; - if (!length || size < 1) { - return []; - } - var index = 0, - resIndex = 0, - result = Array(nativeCeil(length / size)); - - while (index < length) { - result[resIndex++] = baseSlice(array, index, (index += size)); - } - return result; - } - - /** - * Creates an array with all falsey values removed. The values `false`, `null`, - * `0`, `""`, `undefined`, and `NaN` are falsey. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to compact. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.compact([0, 1, false, 2, '', 3]); - * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - resIndex = 0, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result[resIndex++] = value; - } - } - return result; - } - - /** - * Creates a new array concatenating `array` with any additional arrays - * and/or values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to concatenate. - * @param {...*} [values] The values to concatenate. - * @returns {Array} Returns the new concatenated array. - * @example - * - * var array = [1]; - * var other = _.concat(array, 2, [3], [[4]]); - * - * console.log(other); - * // => [1, 2, 3, [4]] - * - * console.log(array); - * // => [1] - */ - function concat() { - var length = arguments.length, - args = Array(length ? length - 1 : 0), - array = arguments[0], - index = length; - - while (index--) { - args[index - 1] = arguments[index]; - } - return length - ? arrayPush(isArray(array) ? copyArray(array) : [array], baseFlatten(args, 1)) - : []; - } - - /** - * Creates an array of `array` values not included in the other given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. The order of result values is determined by the - * order they occur in the first array. - * - * **Note:** Unlike `_.pullAll`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.without, _.xor - * @example - * - * _.difference([2, 1], [2, 3]); - * // => [1] - */ - var difference = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true)) - : []; - }); - - /** - * This method is like `_.difference` except that it accepts `iteratee` which - * is invoked for each element of `array` and `values` to generate the criterion - * by which they're compared. Result values are chosen from the first array. - * The iteratee is invoked with one argument: (value). - * - * **Note:** Unlike `_.pullAllBy`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.differenceBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [1.2] - * - * // The `_.property` iteratee shorthand. - * _.differenceBy([{ 'x': 2 }, { 'x': 1 }], [{ 'x': 1 }], 'x'); - * // => [{ 'x': 2 }] - */ - var differenceBy = baseRest(function(array, values) { - var iteratee = last(values); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)) - : []; - }); - - /** - * This method is like `_.difference` except that it accepts `comparator` - * which is invoked to compare elements of `array` to `values`. Result values - * are chosen from the first array. The comparator is invoked with two arguments: - * (arrVal, othVal). - * - * **Note:** Unlike `_.pullAllWith`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The values to exclude. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * - * _.differenceWith(objects, [{ 'x': 1, 'y': 2 }], _.isEqual); - * // => [{ 'x': 2, 'y': 1 }] - */ - var differenceWith = baseRest(function(array, values) { - var comparator = last(values); - if (isArrayLikeObject(comparator)) { - comparator = undefined; - } - return isArrayLikeObject(array) - ? baseDifference(array, baseFlatten(values, 1, isArrayLikeObject, true), undefined, comparator) - : []; - }); - - /** - * Creates a slice of `array` with `n` elements dropped from the beginning. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.drop([1, 2, 3]); - * // => [2, 3] - * - * _.drop([1, 2, 3], 2); - * // => [3] - * - * _.drop([1, 2, 3], 5); - * // => [] - * - * _.drop([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function drop(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, n < 0 ? 0 : n, length); - } - - /** - * Creates a slice of `array` with `n` elements dropped from the end. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.dropRight([1, 2, 3]); - * // => [1, 2] - * - * _.dropRight([1, 2, 3], 2); - * // => [1] - * - * _.dropRight([1, 2, 3], 5); - * // => [] - * - * _.dropRight([1, 2, 3], 0); - * // => [1, 2, 3] - */ - function dropRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - n = length - n; - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` excluding elements dropped from the end. - * Elements are dropped until `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.dropRightWhile(users, function(o) { return !o.active; }); - * // => objects for ['barney'] - * - * // The `_.matches` iteratee shorthand. - * _.dropRightWhile(users, { 'user': 'pebbles', 'active': false }); - * // => objects for ['barney', 'fred'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.dropRightWhile(users, ['active', false]); - * // => objects for ['barney'] - * - * // The `_.property` iteratee shorthand. - * _.dropRightWhile(users, 'active'); - * // => objects for ['barney', 'fred', 'pebbles'] - */ - function dropRightWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), true, true) - : []; - } - - /** - * Creates a slice of `array` excluding elements dropped from the beginning. - * Elements are dropped until `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.dropWhile(users, function(o) { return !o.active; }); - * // => objects for ['pebbles'] - * - * // The `_.matches` iteratee shorthand. - * _.dropWhile(users, { 'user': 'barney', 'active': false }); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.dropWhile(users, ['active', false]); - * // => objects for ['pebbles'] - * - * // The `_.property` iteratee shorthand. - * _.dropWhile(users, 'active'); - * // => objects for ['barney', 'fred', 'pebbles'] - */ - function dropWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), true) - : []; - } - - /** - * Fills elements of `array` with `value` from `start` up to, but not - * including, `end`. - * - * **Note:** This method mutates `array`. - * - * @static - * @memberOf _ - * @since 3.2.0 - * @category Array - * @param {Array} array The array to fill. - * @param {*} value The value to fill `array` with. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.fill(array, 'a'); - * console.log(array); - * // => ['a', 'a', 'a'] - * - * _.fill(Array(3), 2); - * // => [2, 2, 2] - * - * _.fill([4, 6, 8, 10], '*', 1, 3); - * // => [4, '*', '*', 10] - */ - function fill(array, value, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { - start = 0; - end = length; - } - return baseFill(array, value, start, end); - } - - /** - * This method is like `_.find` except that it returns the index of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Array - * @param {Array} array The array to search. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.findIndex(users, function(o) { return o.user == 'barney'; }); - * // => 0 - * - * // The `_.matches` iteratee shorthand. - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findIndex(users, ['active', false]); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.findIndex(users, 'active'); - * // => 2 - */ - function findIndex(array, predicate, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseFindIndex(array, getIteratee(predicate, 3), index); - } - - /** - * This method is like `_.findIndex` except that it iterates over elements - * of `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to search. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the found element, else `-1`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.findLastIndex(users, function(o) { return o.user == 'pebbles'; }); - * // => 2 - * - * // The `_.matches` iteratee shorthand. - * _.findLastIndex(users, { 'user': 'barney', 'active': true }); - * // => 0 - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastIndex(users, ['active', false]); - * // => 2 - * - * // The `_.property` iteratee shorthand. - * _.findLastIndex(users, 'active'); - * // => 0 - */ - function findLastIndex(array, predicate, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = length - 1; - if (fromIndex !== undefined) { - index = toInteger(fromIndex); - index = fromIndex < 0 - ? nativeMax(length + index, 0) - : nativeMin(index, length - 1); - } - return baseFindIndex(array, getIteratee(predicate, 3), index, true); - } - - /** - * Flattens `array` a single level deep. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flatten([1, [2, [3, [4]], 5]]); - * // => [1, 2, [3, [4]], 5] - */ - function flatten(array) { - var length = array ? array.length : 0; - return length ? baseFlatten(array, 1) : []; - } - - /** - * Recursively flattens `array`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to flatten. - * @returns {Array} Returns the new flattened array. - * @example - * - * _.flattenDeep([1, [2, [3, [4]], 5]]); - * // => [1, 2, 3, 4, 5] - */ - function flattenDeep(array) { - var length = array ? array.length : 0; - return length ? baseFlatten(array, INFINITY) : []; - } - - /** - * Recursively flatten `array` up to `depth` times. - * - * @static - * @memberOf _ - * @since 4.4.0 - * @category Array - * @param {Array} array The array to flatten. - * @param {number} [depth=1] The maximum recursion depth. - * @returns {Array} Returns the new flattened array. - * @example - * - * var array = [1, [2, [3, [4]], 5]]; - * - * _.flattenDepth(array, 1); - * // => [1, 2, [3, [4]], 5] - * - * _.flattenDepth(array, 2); - * // => [1, 2, 3, [4], 5] - */ - function flattenDepth(array, depth) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - depth = depth === undefined ? 1 : toInteger(depth); - return baseFlatten(array, depth); - } - - /** - * The inverse of `_.toPairs`; this method returns an object composed - * from key-value `pairs`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} pairs The key-value pairs. - * @returns {Object} Returns the new object. - * @example - * - * _.fromPairs([['a', 1], ['b', 2]]); - * // => { 'a': 1, 'b': 2 } - */ - function fromPairs(pairs) { - var index = -1, - length = pairs ? pairs.length : 0, - result = {}; - - while (++index < length) { - var pair = pairs[index]; - result[pair[0]] = pair[1]; - } - return result; - } - - /** - * Gets the first element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias first - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. - * @example - * - * _.head([1, 2, 3]); - * // => 1 - * - * _.head([]); - * // => undefined - */ - function head(array) { - return (array && array.length) ? array[0] : undefined; - } - - /** - * Gets the index at which the first occurrence of `value` is found in `array` - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. If `fromIndex` is negative, it's used as the - * offset from the end of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.indexOf([1, 2, 1, 2], 2); - * // => 1 - * - * // Search from the `fromIndex`. - * _.indexOf([1, 2, 1, 2], 2, 2); - * // => 3 - */ - function indexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = fromIndex == null ? 0 : toInteger(fromIndex); - if (index < 0) { - index = nativeMax(length + index, 0); - } - return baseIndexOf(array, value, index); - } - - /** - * Gets all but the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.initial([1, 2, 3]); - * // => [1, 2] - */ - function initial(array) { - return dropRight(array, 1); - } - - /** - * Creates an array of unique values that are included in all given arrays - * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. The order of result values is determined by the - * order they occur in the first array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * _.intersection([2, 1], [2, 3]); - * // => [2] - */ - var intersection = baseRest(function(arrays) { - var mapped = arrayMap(arrays, castArrayLikeObject); - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped) - : []; - }); - - /** - * This method is like `_.intersection` except that it accepts `iteratee` - * which is invoked for each element of each `arrays` to generate the criterion - * by which they're compared. Result values are chosen from the first array. - * The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * _.intersectionBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [2.1] - * - * // The `_.property` iteratee shorthand. - * _.intersectionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }] - */ - var intersectionBy = baseRest(function(arrays) { - var iteratee = last(arrays), - mapped = arrayMap(arrays, castArrayLikeObject); - - if (iteratee === last(mapped)) { - iteratee = undefined; - } else { - mapped.pop(); - } - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped, getIteratee(iteratee, 2)) - : []; - }); - - /** - * This method is like `_.intersection` except that it accepts `comparator` - * which is invoked to compare elements of `arrays`. Result values are chosen - * from the first array. The comparator is invoked with two arguments: - * (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of intersecting values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.intersectionWith(objects, others, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }] - */ - var intersectionWith = baseRest(function(arrays) { - var comparator = last(arrays), - mapped = arrayMap(arrays, castArrayLikeObject); - - if (comparator === last(mapped)) { - comparator = undefined; - } else { - mapped.pop(); - } - return (mapped.length && mapped[0] === arrays[0]) - ? baseIntersection(mapped, undefined, comparator) - : []; - }); - - /** - * Converts all elements in `array` into a string separated by `separator`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to convert. - * @param {string} [separator=','] The element separator. - * @returns {string} Returns the joined string. - * @example - * - * _.join(['a', 'b', 'c'], '~'); - * // => 'a~b~c' - */ - function join(array, separator) { - return array ? nativeJoin.call(array, separator) : ''; - } - - /** - * Gets the last element of `array`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. - * @example - * - * _.last([1, 2, 3]); - * // => 3 - */ - function last(array) { - var length = array ? array.length : 0; - return length ? array[length - 1] : undefined; - } - - /** - * This method is like `_.indexOf` except that it iterates over elements of - * `array` from right to left. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=array.length-1] The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.lastIndexOf([1, 2, 1, 2], 2); - * // => 3 - * - * // Search from the `fromIndex`. - * _.lastIndexOf([1, 2, 1, 2], 2, 2); - * // => 1 - */ - function lastIndexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = length; - if (fromIndex !== undefined) { - index = toInteger(fromIndex); - index = ( - index < 0 - ? nativeMax(length + index, 0) - : nativeMin(index, length - 1) - ) + 1; - } - if (value !== value) { - return baseFindIndex(array, baseIsNaN, index - 1, true); - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Gets the element at index `n` of `array`. If `n` is negative, the nth - * element from the end is returned. - * - * @static - * @memberOf _ - * @since 4.11.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=0] The index of the element to return. - * @returns {*} Returns the nth element of `array`. - * @example - * - * var array = ['a', 'b', 'c', 'd']; - * - * _.nth(array, 1); - * // => 'b' - * - * _.nth(array, -2); - * // => 'c'; - */ - function nth(array, n) { - return (array && array.length) ? baseNth(array, toInteger(n)) : undefined; - } - - /** - * Removes all given values from `array` using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.without`, this method mutates `array`. Use `_.remove` - * to remove elements from an array by predicate. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {...*} [values] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = ['a', 'b', 'c', 'a', 'b', 'c']; - * - * _.pull(array, 'a', 'c'); - * console.log(array); - * // => ['b', 'b'] - */ - var pull = baseRest(pullAll); - - /** - * This method is like `_.pull` except that it accepts an array of values to remove. - * - * **Note:** Unlike `_.difference`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = ['a', 'b', 'c', 'a', 'b', 'c']; - * - * _.pullAll(array, ['a', 'c']); - * console.log(array); - * // => ['b', 'b'] - */ - function pullAll(array, values) { - return (array && array.length && values && values.length) - ? basePullAll(array, values) - : array; - } - - /** - * This method is like `_.pullAll` except that it accepts `iteratee` which is - * invoked for each element of `array` and `values` to generate the criterion - * by which they're compared. The iteratee is invoked with one argument: (value). - * - * **Note:** Unlike `_.differenceBy`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {Array} Returns `array`. - * @example - * - * var array = [{ 'x': 1 }, { 'x': 2 }, { 'x': 3 }, { 'x': 1 }]; - * - * _.pullAllBy(array, [{ 'x': 1 }, { 'x': 3 }], 'x'); - * console.log(array); - * // => [{ 'x': 2 }] - */ - function pullAllBy(array, values, iteratee) { - return (array && array.length && values && values.length) - ? basePullAll(array, values, getIteratee(iteratee, 2)) - : array; - } - - /** - * This method is like `_.pullAll` except that it accepts `comparator` which - * is invoked to compare elements of `array` to `values`. The comparator is - * invoked with two arguments: (arrVal, othVal). - * - * **Note:** Unlike `_.differenceWith`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Array} values The values to remove. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns `array`. - * @example - * - * var array = [{ 'x': 1, 'y': 2 }, { 'x': 3, 'y': 4 }, { 'x': 5, 'y': 6 }]; - * - * _.pullAllWith(array, [{ 'x': 3, 'y': 4 }], _.isEqual); - * console.log(array); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 5, 'y': 6 }] - */ - function pullAllWith(array, values, comparator) { - return (array && array.length && values && values.length) - ? basePullAll(array, values, undefined, comparator) - : array; - } - - /** - * Removes elements from `array` corresponding to `indexes` and returns an - * array of removed elements. - * - * **Note:** Unlike `_.at`, this method mutates `array`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {...(number|number[])} [indexes] The indexes of elements to remove. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = ['a', 'b', 'c', 'd']; - * var pulled = _.pullAt(array, [1, 3]); - * - * console.log(array); - * // => ['a', 'c'] - * - * console.log(pulled); - * // => ['b', 'd'] - */ - var pullAt = baseRest(function(array, indexes) { - indexes = baseFlatten(indexes, 1); - - var length = array ? array.length : 0, - result = baseAt(array, indexes); - - basePullAt(array, arrayMap(indexes, function(index) { - return isIndex(index, length) ? +index : index; - }).sort(compareAscending)); - - return result; - }); - - /** - * Removes all elements from `array` that `predicate` returns truthy for - * and returns an array of the removed elements. The predicate is invoked - * with three arguments: (value, index, array). - * - * **Note:** Unlike `_.filter`, this method mutates `array`. Use `_.pull` - * to pull elements from an array by value. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Array - * @param {Array} array The array to modify. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the new array of removed elements. - * @example - * - * var array = [1, 2, 3, 4]; - * var evens = _.remove(array, function(n) { - * return n % 2 == 0; - * }); - * - * console.log(array); - * // => [1, 3] - * - * console.log(evens); - * // => [2, 4] - */ - function remove(array, predicate) { - var result = []; - if (!(array && array.length)) { - return result; - } - var index = -1, - indexes = [], - length = array.length; - - predicate = getIteratee(predicate, 3); - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result.push(value); - indexes.push(index); - } - } - basePullAt(array, indexes); - return result; - } - - /** - * Reverses `array` so that the first element becomes the last, the second - * element becomes the second to last, and so on. - * - * **Note:** This method mutates `array` and is based on - * [`Array#reverse`](https://mdn.io/Array/reverse). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to modify. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3]; - * - * _.reverse(array); - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function reverse(array) { - return array ? nativeReverse.call(array) : array; - } - - /** - * Creates a slice of `array` from `start` up to, but not including, `end`. - * - * **Note:** This method is used instead of - * [`Array#slice`](https://mdn.io/Array/slice) to ensure dense arrays are - * returned. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function slice(array, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { - start = 0; - end = length; - } - else { - start = start == null ? 0 : toInteger(start); - end = end === undefined ? length : toInteger(end); - } - return baseSlice(array, start, end); - } - - /** - * Uses a binary search to determine the lowest index at which `value` - * should be inserted into `array` in order to maintain its sort order. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedIndex([30, 50], 40); - * // => 1 - */ - function sortedIndex(array, value) { - return baseSortedIndex(array, value); - } - - /** - * This method is like `_.sortedIndex` except that it accepts `iteratee` - * which is invoked for `value` and each element of `array` to compute their - * sort ranking. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * var objects = [{ 'x': 4 }, { 'x': 5 }]; - * - * _.sortedIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); - * // => 0 - * - * // The `_.property` iteratee shorthand. - * _.sortedIndexBy(objects, { 'x': 4 }, 'x'); - * // => 0 - */ - function sortedIndexBy(array, value, iteratee) { - return baseSortedIndexBy(array, value, getIteratee(iteratee, 2)); - } - - /** - * This method is like `_.indexOf` except that it performs a binary - * search on a sorted `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.sortedIndexOf([4, 5, 5, 5, 6], 5); - * // => 1 - */ - function sortedIndexOf(array, value) { - var length = array ? array.length : 0; - if (length) { - var index = baseSortedIndex(array, value); - if (index < length && eq(array[index], value)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.sortedIndex` except that it returns the highest - * index at which `value` should be inserted into `array` in order to - * maintain its sort order. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * _.sortedLastIndex([4, 5, 5, 5, 6], 5); - * // => 4 - */ - function sortedLastIndex(array, value) { - return baseSortedIndex(array, value, true); - } - - /** - * This method is like `_.sortedLastIndex` except that it accepts `iteratee` - * which is invoked for `value` and each element of `array` to compute their - * sort ranking. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. - * @example - * - * var objects = [{ 'x': 4 }, { 'x': 5 }]; - * - * _.sortedLastIndexBy(objects, { 'x': 4 }, function(o) { return o.x; }); - * // => 1 - * - * // The `_.property` iteratee shorthand. - * _.sortedLastIndexBy(objects, { 'x': 4 }, 'x'); - * // => 1 - */ - function sortedLastIndexBy(array, value, iteratee) { - return baseSortedIndexBy(array, value, getIteratee(iteratee, 2), true); - } - - /** - * This method is like `_.lastIndexOf` except that it performs a binary - * search on a sorted `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example - * - * _.sortedLastIndexOf([4, 5, 5, 5, 6], 5); - * // => 3 - */ - function sortedLastIndexOf(array, value) { - var length = array ? array.length : 0; - if (length) { - var index = baseSortedIndex(array, value, true) - 1; - if (eq(array[index], value)) { - return index; - } - } - return -1; - } - - /** - * This method is like `_.uniq` except that it's designed and optimized - * for sorted arrays. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.sortedUniq([1, 1, 2]); - * // => [1, 2] - */ - function sortedUniq(array) { - return (array && array.length) - ? baseSortedUniq(array) - : []; - } - - /** - * This method is like `_.uniqBy` except that it's designed and optimized - * for sorted arrays. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.sortedUniqBy([1.1, 1.2, 2.3, 2.4], Math.floor); - * // => [1.1, 2.3] - */ - function sortedUniqBy(array, iteratee) { - return (array && array.length) - ? baseSortedUniq(array, getIteratee(iteratee, 2)) - : []; - } - - /** - * Gets all but the first element of `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.tail([1, 2, 3]); - * // => [2, 3] - */ - function tail(array) { - return drop(array, 1); - } - - /** - * Creates a slice of `array` with `n` elements taken from the beginning. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.take([1, 2, 3]); - * // => [1] - * - * _.take([1, 2, 3], 2); - * // => [1, 2] - * - * _.take([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.take([1, 2, 3], 0); - * // => [] - */ - function take(array, n, guard) { - if (!(array && array.length)) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - return baseSlice(array, 0, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with `n` elements taken from the end. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to take. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example - * - * _.takeRight([1, 2, 3]); - * // => [3] - * - * _.takeRight([1, 2, 3], 2); - * // => [2, 3] - * - * _.takeRight([1, 2, 3], 5); - * // => [1, 2, 3] - * - * _.takeRight([1, 2, 3], 0); - * // => [] - */ - function takeRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - n = (guard || n === undefined) ? 1 : toInteger(n); - n = length - n; - return baseSlice(array, n < 0 ? 0 : n, length); - } - - /** - * Creates a slice of `array` with elements taken from the end. Elements are - * taken until `predicate` returns falsey. The predicate is invoked with - * three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.takeRightWhile(users, function(o) { return !o.active; }); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.matches` iteratee shorthand. - * _.takeRightWhile(users, { 'user': 'pebbles', 'active': false }); - * // => objects for ['pebbles'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.takeRightWhile(users, ['active', false]); - * // => objects for ['fred', 'pebbles'] - * - * // The `_.property` iteratee shorthand. - * _.takeRightWhile(users, 'active'); - * // => [] - */ - function takeRightWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3), false, true) - : []; - } - - /** - * Creates a slice of `array` with elements taken from the beginning. Elements - * are taken until `predicate` returns falsey. The predicate is invoked with - * three arguments: (value, index, array). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Array - * @param {Array} array The array to query. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the slice of `array`. - * @example - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false}, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.takeWhile(users, function(o) { return !o.active; }); - * // => objects for ['barney', 'fred'] - * - * // The `_.matches` iteratee shorthand. - * _.takeWhile(users, { 'user': 'barney', 'active': false }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.takeWhile(users, ['active', false]); - * // => objects for ['barney', 'fred'] - * - * // The `_.property` iteratee shorthand. - * _.takeWhile(users, 'active'); - * // => [] - */ - function takeWhile(array, predicate) { - return (array && array.length) - ? baseWhile(array, getIteratee(predicate, 3)) - : []; - } - - /** - * Creates an array of unique values, in order, from all given arrays using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.union([2], [1, 2]); - * // => [2, 1] - */ - var union = baseRest(function(arrays) { - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true)); - }); - - /** - * This method is like `_.union` except that it accepts `iteratee` which is - * invoked for each element of each `arrays` to generate the criterion by - * which uniqueness is computed. Result values are chosen from the first - * array in which the value occurs. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {Array} Returns the new array of combined values. - * @example - * - * _.unionBy([2.1], [1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.unionBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - var unionBy = baseRest(function(arrays) { - var iteratee = last(arrays); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), getIteratee(iteratee, 2)); - }); - - /** - * This method is like `_.union` except that it accepts `comparator` which - * is invoked to compare elements of `arrays`. Result values are chosen from - * the first array in which the value occurs. The comparator is invoked - * with two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of combined values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.unionWith(objects, others, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] - */ - var unionWith = baseRest(function(arrays) { - var comparator = last(arrays); - if (isArrayLikeObject(comparator)) { - comparator = undefined; - } - return baseUniq(baseFlatten(arrays, 1, isArrayLikeObject, true), undefined, comparator); - }); - - /** - * Creates a duplicate-free version of an array, using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons, in which only the first occurrence of each - * element is kept. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniq([2, 1, 2]); - * // => [2, 1] - */ - function uniq(array) { - return (array && array.length) - ? baseUniq(array) - : []; - } - - /** - * This method is like `_.uniq` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the criterion by which - * uniqueness is computed. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * _.uniqBy([2.1, 1.2, 2.3], Math.floor); - * // => [2.1, 1.2] - * - * // The `_.property` iteratee shorthand. - * _.uniqBy([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] - */ - function uniqBy(array, iteratee) { - return (array && array.length) - ? baseUniq(array, getIteratee(iteratee, 2)) - : []; - } - - /** - * This method is like `_.uniq` except that it accepts `comparator` which - * is invoked to compare elements of `array`. The comparator is invoked with - * two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new duplicate free array. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.uniqWith(objects, _.isEqual); - * // => [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }] - */ - function uniqWith(array, comparator) { - return (array && array.length) - ? baseUniq(array, undefined, comparator) - : []; - } - - /** - * This method is like `_.zip` except that it accepts an array of grouped - * elements and creates an array regrouping the elements to their pre-zip - * configuration. - * - * @static - * @memberOf _ - * @since 1.2.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - * - * _.unzip(zipped); - * // => [['a', 'b'], [1, 2], [true, false]] - */ - function unzip(array) { - if (!(array && array.length)) { - return []; - } - var length = 0; - array = arrayFilter(array, function(group) { - if (isArrayLikeObject(group)) { - length = nativeMax(group.length, length); - return true; - } - }); - return baseTimes(length, function(index) { - return arrayMap(array, baseProperty(index)); - }); - } - - /** - * This method is like `_.unzip` except that it accepts `iteratee` to specify - * how regrouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {Array} array The array of grouped elements to process. - * @param {Function} [iteratee=_.identity] The function to combine - * regrouped values. - * @returns {Array} Returns the new array of regrouped elements. - * @example - * - * var zipped = _.zip([1, 2], [10, 20], [100, 200]); - * // => [[1, 10, 100], [2, 20, 200]] - * - * _.unzipWith(zipped, _.add); - * // => [3, 30, 300] - */ - function unzipWith(array, iteratee) { - if (!(array && array.length)) { - return []; - } - var result = unzip(array); - if (iteratee == null) { - return result; - } - return arrayMap(result, function(group) { - return apply(iteratee, undefined, group); - }); - } - - /** - * Creates an array excluding all given values using - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * for equality comparisons. - * - * **Note:** Unlike `_.pull`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {Array} array The array to inspect. - * @param {...*} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @see _.difference, _.xor - * @example - * - * _.without([2, 1, 2, 3], 1, 2); - * // => [3] - */ - var without = baseRest(function(array, values) { - return isArrayLikeObject(array) - ? baseDifference(array, values) - : []; - }); - - /** - * Creates an array of unique values that is the - * [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) - * of the given arrays. The order of result values is determined by the order - * they occur in the arrays. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of filtered values. - * @see _.difference, _.without - * @example - * - * _.xor([2, 1], [2, 3]); - * // => [1, 3] - */ - var xor = baseRest(function(arrays) { - return baseXor(arrayFilter(arrays, isArrayLikeObject)); - }); - - /** - * This method is like `_.xor` except that it accepts `iteratee` which is - * invoked for each element of each `arrays` to generate the criterion by - * which by which they're compared. The iteratee is invoked with one argument: - * (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [iteratee=_.identity] - * The iteratee invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * _.xorBy([2.1, 1.2], [2.3, 3.4], Math.floor); - * // => [1.2, 3.4] - * - * // The `_.property` iteratee shorthand. - * _.xorBy([{ 'x': 1 }], [{ 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 2 }] - */ - var xorBy = baseRest(function(arrays) { - var iteratee = last(arrays); - if (isArrayLikeObject(iteratee)) { - iteratee = undefined; - } - return baseXor(arrayFilter(arrays, isArrayLikeObject), getIteratee(iteratee, 2)); - }); - - /** - * This method is like `_.xor` except that it accepts `comparator` which is - * invoked to compare elements of `arrays`. The comparator is invoked with - * two arguments: (arrVal, othVal). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @param {Function} [comparator] The comparator invoked per element. - * @returns {Array} Returns the new array of filtered values. - * @example - * - * var objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }]; - * var others = [{ 'x': 1, 'y': 1 }, { 'x': 1, 'y': 2 }]; - * - * _.xorWith(objects, others, _.isEqual); - * // => [{ 'x': 2, 'y': 1 }, { 'x': 1, 'y': 1 }] - */ - var xorWith = baseRest(function(arrays) { - var comparator = last(arrays); - if (isArrayLikeObject(comparator)) { - comparator = undefined; - } - return baseXor(arrayFilter(arrays, isArrayLikeObject), undefined, comparator); - }); - - /** - * Creates an array of grouped elements, the first of which contains the - * first elements of the given arrays, the second of which contains the - * second elements of the given arrays, and so on. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zip(['a', 'b'], [1, 2], [true, false]); - * // => [['a', 1, true], ['b', 2, false]] - */ - var zip = baseRest(unzip); - - /** - * This method is like `_.fromPairs` except that it accepts two arrays, - * one of property identifiers and one of corresponding values. - * - * @static - * @memberOf _ - * @since 0.4.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObject(['a', 'b'], [1, 2]); - * // => { 'a': 1, 'b': 2 } - */ - function zipObject(props, values) { - return baseZipObject(props || [], values || [], assignValue); - } - - /** - * This method is like `_.zipObject` except that it supports property paths. - * - * @static - * @memberOf _ - * @since 4.1.0 - * @category Array - * @param {Array} [props=[]] The property identifiers. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example - * - * _.zipObjectDeep(['a.b[0].c', 'a.b[1].d'], [1, 2]); - * // => { 'a': { 'b': [{ 'c': 1 }, { 'd': 2 }] } } - */ - function zipObjectDeep(props, values) { - return baseZipObject(props || [], values || [], baseSet); - } - - /** - * This method is like `_.zip` except that it accepts `iteratee` to specify - * how grouped values should be combined. The iteratee is invoked with the - * elements of each group: (...group). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @param {Function} [iteratee=_.identity] The function to combine grouped values. - * @returns {Array} Returns the new array of grouped elements. - * @example - * - * _.zipWith([1, 2], [10, 20], [100, 200], function(a, b, c) { - * return a + b + c; - * }); - * // => [111, 222] - */ - var zipWith = baseRest(function(arrays) { - var length = arrays.length, - iteratee = length > 1 ? arrays[length - 1] : undefined; - - iteratee = typeof iteratee == 'function' ? (arrays.pop(), iteratee) : undefined; - return unzipWith(arrays, iteratee); - }); - - /*------------------------------------------------------------------------*/ - - /** - * Creates a `lodash` wrapper instance that wraps `value` with explicit method - * chain sequences enabled. The result of such sequences must be unwrapped - * with `_#value`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Seq - * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'pebbles', 'age': 1 } - * ]; - * - * var youngest = _ - * .chain(users) - * .sortBy('age') - * .map(function(o) { - * return o.user + ' is ' + o.age; - * }) - * .head() - * .value(); - * // => 'pebbles is 1' - */ - function chain(value) { - var result = lodash(value); - result.__chain__ = true; - return result; - } - - /** - * This method invokes `interceptor` and returns `value`. The interceptor - * is invoked with one argument; (value). The purpose of this method is to - * "tap into" a method chain sequence in order to modify intermediate results. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns `value`. - * @example - * - * _([1, 2, 3]) - * .tap(function(array) { - * // Mutate input array. - * array.pop(); - * }) - * .reverse() - * .value(); - * // => [2, 1] - */ - function tap(value, interceptor) { - interceptor(value); - return value; - } - - /** - * This method is like `_.tap` except that it returns the result of `interceptor`. - * The purpose of this method is to "pass thru" values replacing intermediate - * results in a method chain sequence. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Seq - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @returns {*} Returns the result of `interceptor`. - * @example - * - * _(' abc ') - * .chain() - * .trim() - * .thru(function(value) { - * return [value]; - * }) - * .value(); - * // => ['abc'] - */ - function thru(value, interceptor) { - return interceptor(value); - } - - /** - * This method is the wrapper version of `_.at`. - * - * @name at - * @memberOf _ - * @since 1.0.0 - * @category Seq - * @param {...(string|string[])} [paths] The property paths of elements to pick. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; - * - * _(object).at(['a[0].b.c', 'a[1]']).value(); - * // => [3, 4] - */ - var wrapperAt = baseRest(function(paths) { - paths = baseFlatten(paths, 1); - var length = paths.length, - start = length ? paths[0] : 0, - value = this.__wrapped__, - interceptor = function(object) { return baseAt(object, paths); }; - - if (length > 1 || this.__actions__.length || - !(value instanceof LazyWrapper) || !isIndex(start)) { - return this.thru(interceptor); - } - value = value.slice(start, +start + (length ? 1 : 0)); - value.__actions__.push({ - 'func': thru, - 'args': [interceptor], - 'thisArg': undefined - }); - return new LodashWrapper(value, this.__chain__).thru(function(array) { - if (length && !array.length) { - array.push(undefined); - } - return array; - }); - }); - - /** - * Creates a `lodash` wrapper instance with explicit method chain sequences enabled. - * - * @name chain - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; - * - * // A sequence without explicit chaining. - * _(users).head(); - * // => { 'user': 'barney', 'age': 36 } - * - * // A sequence with explicit chaining. - * _(users) - * .chain() - * .head() - * .pick('user') - * .value(); - * // => { 'user': 'barney' } - */ - function wrapperChain() { - return chain(this); - } - - /** - * Executes the chain sequence and returns the wrapped result. - * - * @name commit - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2]; - * var wrapped = _(array).push(3); - * - * console.log(array); - * // => [1, 2] - * - * wrapped = wrapped.commit(); - * console.log(array); - * // => [1, 2, 3] - * - * wrapped.last(); - * // => 3 - * - * console.log(array); - * // => [1, 2, 3] - */ - function wrapperCommit() { - return new LodashWrapper(this.value(), this.__chain__); - } - - /** - * Gets the next value on a wrapped object following the - * [iterator protocol](https://mdn.io/iteration_protocols#iterator). - * - * @name next - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the next iterator value. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped.next(); - * // => { 'done': false, 'value': 1 } - * - * wrapped.next(); - * // => { 'done': false, 'value': 2 } - * - * wrapped.next(); - * // => { 'done': true, 'value': undefined } - */ - function wrapperNext() { - if (this.__values__ === undefined) { - this.__values__ = toArray(this.value()); - } - var done = this.__index__ >= this.__values__.length, - value = done ? undefined : this.__values__[this.__index__++]; - - return { 'done': done, 'value': value }; - } - - /** - * Enables the wrapper to be iterable. - * - * @name Symbol.iterator - * @memberOf _ - * @since 4.0.0 - * @category Seq - * @returns {Object} Returns the wrapper object. - * @example - * - * var wrapped = _([1, 2]); - * - * wrapped[Symbol.iterator]() === wrapped; - * // => true - * - * Array.from(wrapped); - * // => [1, 2] - */ - function wrapperToIterator() { - return this; - } - - /** - * Creates a clone of the chain sequence planting `value` as the wrapped value. - * - * @name plant - * @memberOf _ - * @since 3.2.0 - * @category Seq - * @param {*} value The value to plant. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var wrapped = _([1, 2]).map(square); - * var other = wrapped.plant([3, 4]); - * - * other.value(); - * // => [9, 16] - * - * wrapped.value(); - * // => [1, 4] - */ - function wrapperPlant(value) { - var result, - parent = this; - - while (parent instanceof baseLodash) { - var clone = wrapperClone(parent); - clone.__index__ = 0; - clone.__values__ = undefined; - if (result) { - previous.__wrapped__ = clone; - } else { - result = clone; - } - var previous = clone; - parent = parent.__wrapped__; - } - previous.__wrapped__ = value; - return result; - } - - /** - * This method is the wrapper version of `_.reverse`. - * - * **Note:** This method mutates the wrapped array. - * - * @name reverse - * @memberOf _ - * @since 0.1.0 - * @category Seq - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var array = [1, 2, 3]; - * - * _(array).reverse().value() - * // => [3, 2, 1] - * - * console.log(array); - * // => [3, 2, 1] - */ - function wrapperReverse() { - var value = this.__wrapped__; - if (value instanceof LazyWrapper) { - var wrapped = value; - if (this.__actions__.length) { - wrapped = new LazyWrapper(this); - } - wrapped = wrapped.reverse(); - wrapped.__actions__.push({ - 'func': thru, - 'args': [reverse], - 'thisArg': undefined - }); - return new LodashWrapper(wrapped, this.__chain__); - } - return this.thru(reverse); - } - - /** - * Executes the chain sequence to resolve the unwrapped value. - * - * @name value - * @memberOf _ - * @since 0.1.0 - * @alias toJSON, valueOf - * @category Seq - * @returns {*} Returns the resolved unwrapped value. - * @example - * - * _([1, 2, 3]).value(); - * // => [1, 2, 3] - */ - function wrapperValue() { - return baseWrapperValue(this.__wrapped__, this.__actions__); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the number of times the key was returned by `iteratee`. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.countBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': 1, '6': 2 } - * - * // The `_.property` iteratee shorthand. - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } - */ - var countBy = createAggregator(function(result, value, key) { - hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); - }); - - /** - * Checks if `predicate` returns truthy for **all** elements of `collection`. - * Iteration is stopped once `predicate` returns falsey. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. - * @example - * - * _.every([true, 1, null, 'yes'], Boolean); - * // => false - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.every(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.every(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.every(users, 'active'); - * // => false - */ - function every(collection, predicate, guard) { - var func = isArray(collection) ? arrayEvery : baseEvery; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, getIteratee(predicate, 3)); - } - - /** - * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * **Note:** Unlike `_.remove`, this method returns a new array. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.reject - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.filter(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.filter(users, { 'age': 36, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.filter(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.filter(users, 'active'); - * // => objects for ['barney'] - */ - function filter(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, getIteratee(predicate, 3)); - } - - /** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is invoked with three - * arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to search. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param {number} [fromIndex=0] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.find(users, function(o) { return o.age < 40; }); - * // => object for 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.find(users, { 'age': 1, 'active': true }); - * // => object for 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.find(users, ['active', false]); - * // => object for 'fred' - * - * // The `_.property` iteratee shorthand. - * _.find(users, 'active'); - * // => object for 'barney' - */ - var find = createFind(findIndex); - - /** - * This method is like `_.find` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Collection - * @param {Array|Object} collection The collection to search. - * @param {Function} [predicate=_.identity] - * The function invoked per iteration. - * @param {number} [fromIndex=collection.length-1] The index to search from. - * @returns {*} Returns the matched element, else `undefined`. - * @example - * - * _.findLast([1, 2, 3, 4], function(n) { - * return n % 2 == 1; - * }); - * // => 3 - */ - var findLast = createFind(findLastIndex); - - /** - * Creates a flattened array of values by running each element in `collection` - * thru `iteratee` and flattening the mapped results. The iteratee is invoked - * with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [n, n]; - * } - * - * _.flatMap([1, 2], duplicate); - * // => [1, 1, 2, 2] - */ - function flatMap(collection, iteratee) { - return baseFlatten(map(collection, iteratee), 1); - } - - /** - * This method is like `_.flatMap` except that it recursively flattens the - * mapped results. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The function invoked per iteration. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [[[n, n]]]; - * } - * - * _.flatMapDeep([1, 2], duplicate); - * // => [1, 1, 2, 2] - */ - function flatMapDeep(collection, iteratee) { - return baseFlatten(map(collection, iteratee), INFINITY); - } - - /** - * This method is like `_.flatMap` except that it recursively flattens the - * mapped results up to `depth` times. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The function invoked per iteration. - * @param {number} [depth=1] The maximum recursion depth. - * @returns {Array} Returns the new flattened array. - * @example - * - * function duplicate(n) { - * return [[[n, n]]]; - * } - * - * _.flatMapDepth([1, 2], duplicate, 2); - * // => [[1, 1], [2, 2]] - */ - function flatMapDepth(collection, iteratee, depth) { - depth = depth === undefined ? 1 : toInteger(depth); - return baseFlatten(map(collection, iteratee), depth); - } - - /** - * Iterates over elements of `collection` and invokes `iteratee` for each element. - * The iteratee is invoked with three arguments: (value, index|key, collection). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * **Note:** As with other "Collections" methods, objects with a "length" - * property are iterated like arrays. To avoid this behavior use `_.forIn` - * or `_.forOwn` for object iteration. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @alias each - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEachRight - * @example - * - * _([1, 2]).forEach(function(value) { - * console.log(value); - * }); - * // => Logs `1` then `2`. - * - * _.forEach({ 'a': 1, 'b': 2 }, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ - function forEach(collection, iteratee) { - var func = isArray(collection) ? arrayEach : baseEach; - return func(collection, getIteratee(iteratee, 3)); - } - - /** - * This method is like `_.forEach` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @alias eachRight - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array|Object} Returns `collection`. - * @see _.forEach - * @example - * - * _.forEachRight([1, 2], function(value) { - * console.log(value); - * }); - * // => Logs `2` then `1`. - */ - function forEachRight(collection, iteratee) { - var func = isArray(collection) ? arrayEachRight : baseEachRight; - return func(collection, getIteratee(iteratee, 3)); - } - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The order of grouped values - * is determined by the order they occur in `collection`. The corresponding - * value of each key is an array of elements responsible for generating the - * key. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * _.groupBy([6.1, 4.2, 6.3], Math.floor); - * // => { '4': [4.2], '6': [6.1, 6.3] } - * - * // The `_.property` iteratee shorthand. - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } - */ - var groupBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - result[key].push(value); - } else { - result[key] = [value]; - } - }); - - /** - * Checks if `value` is in `collection`. If `collection` is a string, it's - * checked for a substring of `value`, otherwise - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * is used for equality comparisons. If `fromIndex` is negative, it's used as - * the offset from the end of `collection`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {*} value The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. - * @returns {boolean} Returns `true` if `value` is found, else `false`. - * @example - * - * _.includes([1, 2, 3], 1); - * // => true - * - * _.includes([1, 2, 3], 1, 2); - * // => false - * - * _.includes({ 'a': 1, 'b': 2 }, 1); - * // => true - * - * _.includes('abcd', 'bc'); - * // => true - */ - function includes(collection, value, fromIndex, guard) { - collection = isArrayLike(collection) ? collection : values(collection); - fromIndex = (fromIndex && !guard) ? toInteger(fromIndex) : 0; - - var length = collection.length; - if (fromIndex < 0) { - fromIndex = nativeMax(length + fromIndex, 0); - } - return isString(collection) - ? (fromIndex <= length && collection.indexOf(value, fromIndex) > -1) - : (!!length && baseIndexOf(collection, value, fromIndex) > -1); - } - - /** - * Invokes the method at `path` of each element in `collection`, returning - * an array of the results of each invoked method. Any additional arguments - * are provided to each invoked method. If `path` is a function, it's invoked - * for, and `this` bound to, each element in `collection`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array|Function|string} path The path of the method to invoke or - * the function invoked per iteration. - * @param {...*} [args] The arguments to invoke each method with. - * @returns {Array} Returns the array of results. - * @example - * - * _.invokeMap([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] - * - * _.invokeMap([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] - */ - var invokeMap = baseRest(function(collection, path, args) { - var index = -1, - isFunc = typeof path == 'function', - isProp = isKey(path), - result = isArrayLike(collection) ? Array(collection.length) : []; - - baseEach(collection, function(value) { - var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); - result[++index] = func ? apply(func, value, args) : baseInvoke(value, path, args); - }); - return result; - }); - - /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` thru `iteratee`. The corresponding value of - * each key is the last element responsible for generating the key. The - * iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] - * The iteratee to transform keys. - * @returns {Object} Returns the composed aggregate object. - * @example - * - * var array = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; - * - * _.keyBy(array, function(o) { - * return String.fromCharCode(o.code); - * }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.keyBy(array, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } - */ - var keyBy = createAggregator(function(result, value, key) { - result[key] = value; - }); - - /** - * Creates an array of values by running each element in `collection` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `chunk`, `curry`, `curryRight`, `drop`, `dropRight`, `every`, - * `fill`, `invert`, `parseInt`, `random`, `range`, `rangeRight`, `repeat`, - * `sampleSize`, `slice`, `some`, `sortBy`, `split`, `take`, `takeRight`, - * `template`, `trim`, `trimEnd`, `trimStart`, and `words` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - * @example - * - * function square(n) { - * return n * n; - * } - * - * _.map([4, 8], square); - * // => [16, 64] - * - * _.map({ 'a': 4, 'b': 8 }, square); - * // => [16, 64] (iteration order is not guaranteed) - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * // The `_.property` iteratee shorthand. - * _.map(users, 'user'); - * // => ['barney', 'fred'] - */ - function map(collection, iteratee) { - var func = isArray(collection) ? arrayMap : baseMap; - return func(collection, getIteratee(iteratee, 3)); - } - - /** - * This method is like `_.sortBy` except that it allows specifying the sort - * orders of the iteratees to sort by. If `orders` is unspecified, all values - * are sorted in ascending order. Otherwise, specify an order of "desc" for - * descending or "asc" for ascending sort order of corresponding values. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Array[]|Function[]|Object[]|string[]} [iteratees=[_.identity]] - * The iteratees to sort by. - * @param {string[]} [orders] The sort orders of `iteratees`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.reduce`. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 34 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 36 } - * ]; - * - * // Sort by `user` in ascending order and by `age` in descending order. - * _.orderBy(users, ['user', 'age'], ['asc', 'desc']); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - */ - function orderBy(collection, iteratees, orders, guard) { - if (collection == null) { - return []; - } - if (!isArray(iteratees)) { - iteratees = iteratees == null ? [] : [iteratees]; - } - orders = guard ? undefined : orders; - if (!isArray(orders)) { - orders = orders == null ? [] : [orders]; - } - return baseOrderBy(collection, iteratees, orders); - } - - /** - * Creates an array of elements split into two groups, the first of which - * contains elements `predicate` returns truthy for, the second of which - * contains elements `predicate` returns falsey for. The predicate is - * invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the array of grouped elements. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * _.partition(users, function(o) { return o.active; }); - * // => objects for [['fred'], ['barney', 'pebbles']] - * - * // The `_.matches` iteratee shorthand. - * _.partition(users, { 'age': 1, 'active': false }); - * // => objects for [['pebbles'], ['barney', 'fred']] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.partition(users, ['active', false]); - * // => objects for [['barney', 'pebbles'], ['fred']] - * - * // The `_.property` iteratee shorthand. - * _.partition(users, 'active'); - * // => objects for [['fred'], ['barney', 'pebbles']] - */ - var partition = createAggregator(function(result, value, key) { - result[key ? 0 : 1].push(value); - }, function() { return [[], []]; }); - - /** - * Reduces `collection` to a value which is the accumulated result of running - * each element in `collection` thru `iteratee`, where each successive - * invocation is supplied the return value of the previous. If `accumulator` - * is not given, the first element of `collection` is used as the initial - * value. The iteratee is invoked with four arguments: - * (accumulator, value, index|key, collection). - * - * Many lodash methods are guarded to work as iteratees for methods like - * `_.reduce`, `_.reduceRight`, and `_.transform`. - * - * The guarded methods are: - * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `orderBy`, - * and `sortBy` - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduceRight - * @example - * - * _.reduce([1, 2], function(sum, n) { - * return sum + n; - * }, 0); - * // => 3 - * - * _.reduce({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * return result; - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } (iteration order is not guaranteed) - */ - function reduce(collection, iteratee, accumulator) { - var func = isArray(collection) ? arrayReduce : baseReduce, - initAccum = arguments.length < 3; - - return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEach); - } - - /** - * This method is like `_.reduce` except that it iterates over elements of - * `collection` from right to left. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @returns {*} Returns the accumulated value. - * @see _.reduce - * @example - * - * var array = [[0, 1], [2, 3], [4, 5]]; - * - * _.reduceRight(array, function(flattened, other) { - * return flattened.concat(other); - * }, []); - * // => [4, 5, 2, 3, 0, 1] - */ - function reduceRight(collection, iteratee, accumulator) { - var func = isArray(collection) ? arrayReduceRight : baseReduce, - initAccum = arguments.length < 3; - - return func(collection, getIteratee(iteratee, 4), accumulator, initAccum, baseEachRight); - } - - /** - * The opposite of `_.filter`; this method returns the elements of `collection` - * that `predicate` does **not** return truthy for. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {Array} Returns the new filtered array. - * @see _.filter - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } - * ]; - * - * _.reject(users, function(o) { return !o.active; }); - * // => objects for ['fred'] - * - * // The `_.matches` iteratee shorthand. - * _.reject(users, { 'age': 40, 'active': true }); - * // => objects for ['barney'] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.reject(users, ['active', false]); - * // => objects for ['fred'] - * - * // The `_.property` iteratee shorthand. - * _.reject(users, 'active'); - * // => objects for ['barney'] - */ - function reject(collection, predicate) { - var func = isArray(collection) ? arrayFilter : baseFilter; - return func(collection, negate(getIteratee(predicate, 3))); - } - - /** - * Gets a random element from `collection`. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. - * @returns {*} Returns the random element. - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - */ - function sample(collection) { - var array = isArrayLike(collection) ? collection : values(collection), - length = array.length; - - return length > 0 ? array[baseRandom(0, length - 1)] : undefined; - } - - /** - * Gets `n` random elements at unique keys from `collection` up to the - * size of `collection`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Collection - * @param {Array|Object} collection The collection to sample. - * @param {number} [n=1] The number of elements to sample. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the random elements. - * @example - * - * _.sampleSize([1, 2, 3], 2); - * // => [3, 1] - * - * _.sampleSize([1, 2, 3], 4); - * // => [2, 3, 1] - */ - function sampleSize(collection, n, guard) { - var index = -1, - result = toArray(collection), - length = result.length, - lastIndex = length - 1; - - if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { - n = 1; - } else { - n = baseClamp(toInteger(n), 0, length); - } - while (++index < n) { - var rand = baseRandom(index, lastIndex), - value = result[rand]; - - result[rand] = result[index]; - result[index] = value; - } - result.length = n; - return result; - } - - /** - * Creates an array of shuffled values, using a version of the - * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to shuffle. - * @returns {Array} Returns the new shuffled array. - * @example - * - * _.shuffle([1, 2, 3, 4]); - * // => [4, 1, 3, 2] - */ - function shuffle(collection) { - return sampleSize(collection, MAX_ARRAY_LENGTH); - } - - /** - * Gets the size of `collection` by returning its length for array-like - * values or the number of own enumerable string keyed properties for objects. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to inspect. - * @returns {number} Returns the collection size. - * @example - * - * _.size([1, 2, 3]); - * // => 3 - * - * _.size({ 'a': 1, 'b': 2 }); - * // => 2 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - if (collection == null) { - return 0; - } - if (isArrayLike(collection)) { - var result = collection.length; - return (result && isString(collection)) ? stringSize(collection) : result; - } - if (isObjectLike(collection)) { - var tag = getTag(collection); - if (tag == mapTag || tag == setTag) { - return collection.size; - } - } - return keys(collection).length; - } - - /** - * Checks if `predicate` returns truthy for **any** element of `collection`. - * Iteration is stopped once `predicate` returns truthy. The predicate is - * invoked with three arguments: (value, index|key, collection). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. - * @example - * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.some(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // The `_.matchesProperty` iteratee shorthand. - * _.some(users, ['active', false]); - * // => true - * - * // The `_.property` iteratee shorthand. - * _.some(users, 'active'); - * // => true - */ - function some(collection, predicate, guard) { - var func = isArray(collection) ? arraySome : baseSome; - if (guard && isIterateeCall(collection, predicate, guard)) { - predicate = undefined; - } - return func(collection, getIteratee(predicate, 3)); - } - - /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection thru each iteratee. This method - * performs a stable sort, that is, it preserves the original sort order of - * equal elements. The iteratees are invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Collection - * @param {Array|Object} collection The collection to iterate over. - * @param {...(Function|Function[])} [iteratees=[_.identity]] - * The iteratees to sort by. - * @returns {Array} Returns the new sorted array. - * @example - * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'barney', 'age': 34 } - * ]; - * - * _.sortBy(users, function(o) { return o.user; }); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - * - * _.sortBy(users, ['user', 'age']); - * // => objects for [['barney', 34], ['barney', 36], ['fred', 40], ['fred', 48]] - * - * _.sortBy(users, 'user', function(o) { - * return Math.floor(o.age / 10); - * }); - * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 40]] - */ - var sortBy = baseRest(function(collection, iteratees) { - if (collection == null) { - return []; - } - var length = iteratees.length; - if (length > 1 && isIterateeCall(collection, iteratees[0], iteratees[1])) { - iteratees = []; - } else if (length > 2 && isIterateeCall(iteratees[0], iteratees[1], iteratees[2])) { - iteratees = [iteratees[0]]; - } - return baseOrderBy(collection, baseFlatten(iteratees, 1), []); - }); - - /*------------------------------------------------------------------------*/ - - /** - * Gets the timestamp of the number of milliseconds that have elapsed since - * the Unix epoch (1 January 1970 00:00:00 UTC). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Date - * @returns {number} Returns the timestamp. - * @example - * - * _.defer(function(stamp) { - * console.log(_.now() - stamp); - * }, _.now()); - * // => Logs the number of milliseconds it took for the deferred invocation. - */ - function now() { - return Date.now(); - } - - /*------------------------------------------------------------------------*/ - - /** - * The opposite of `_.before`; this method creates a function that invokes - * `func` once it's called `n` or more times. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {number} n The number of calls before `func` is invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var saves = ['profile', 'settings']; - * - * var done = _.after(saves.length, function() { - * console.log('done saving!'); - * }); - * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => Logs 'done saving!' after the two async saves have completed. - */ - function after(n, func) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } - - /** - * Creates a function that invokes `func`, with up to `n` arguments, - * ignoring any additional arguments. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to cap arguments for. - * @param {number} [n=func.length] The arity cap. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new capped function. - * @example - * - * _.map(['6', '8', '10'], _.ary(parseInt, 1)); - * // => [6, 8, 10] - */ - function ary(func, n, guard) { - n = guard ? undefined : n; - n = (func && n == null) ? func.length : n; - return createWrap(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); - } - - /** - * Creates a function that invokes `func`, with the `this` binding and arguments - * of the created function, while it's called less than `n` times. Subsequent - * calls to the created function return the result of the last `func` invocation. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {number} n The number of calls at which `func` is no longer invoked. - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * jQuery(element).on('click', _.before(5, addContactToList)); - * // => Allows adding up to 4 contacts to the list. - */ - function before(n, func) { - var result; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - n = toInteger(n); - return function() { - if (--n > 0) { - result = func.apply(this, arguments); - } - if (n <= 1) { - func = undefined; - } - return result; - }; - } - - /** - * Creates a function that invokes `func` with the `this` binding of `thisArg` - * and `partials` prepended to the arguments it receives. - * - * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for partially applied arguments. - * - * **Note:** Unlike native `Function#bind`, this method doesn't set the "length" - * property of bound functions. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * function greet(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * - * var object = { 'user': 'fred' }; - * - * var bound = _.bind(greet, object, 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * // Bound with placeholders. - * var bound = _.bind(greet, object, _, '!'); - * bound('hi'); - * // => 'hi fred!' - */ - var bind = baseRest(function(func, thisArg, partials) { - var bitmask = BIND_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, getHolder(bind)); - bitmask |= PARTIAL_FLAG; - } - return createWrap(func, bitmask, thisArg, partials, holders); - }); - - /** - * Creates a function that invokes the method at `object[key]` with `partials` - * prepended to the arguments it receives. - * - * This method differs from `_.bind` by allowing bound functions to reference - * methods that may be redefined or don't yet exist. See - * [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) - * for more details. - * - * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Function - * @param {Object} object The object to invoke the method on. - * @param {string} key The key of the method. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new bound function. - * @example - * - * var object = { - * 'user': 'fred', - * 'greet': function(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * } - * }; - * - * var bound = _.bindKey(object, 'greet', 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * object.greet = function(greeting, punctuation) { - * return greeting + 'ya ' + this.user + punctuation; - * }; - * - * bound('!'); - * // => 'hiya fred!' - * - * // Bound with placeholders. - * var bound = _.bindKey(object, 'greet', _, '!'); - * bound('hi'); - * // => 'hiya fred!' - */ - var bindKey = baseRest(function(object, key, partials) { - var bitmask = BIND_FLAG | BIND_KEY_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, getHolder(bindKey)); - bitmask |= PARTIAL_FLAG; - } - return createWrap(key, bitmask, object, partials, holders); - }); - - /** - * Creates a function that accepts arguments of `func` and either invokes - * `func` returning its result, if at least `arity` number of arguments have - * been provided, or returns a function that accepts the remaining `func` - * arguments, and so on. The arity of `func` may be specified if `func.length` - * is not sufficient. - * - * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, - * may be used as a placeholder for provided arguments. - * - * **Note:** This method doesn't set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curry(abc); - * - * curried(1)(2)(3); - * // => [1, 2, 3] - * - * curried(1, 2)(3); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // Curried with placeholders. - * curried(1)(_, 3)(2); - * // => [1, 2, 3] - */ - function curry(func, arity, guard) { - arity = guard ? undefined : arity; - var result = createWrap(func, CURRY_FLAG, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curry.placeholder; - return result; - } - - /** - * This method is like `_.curry` except that arguments are applied to `func` - * in the manner of `_.partialRight` instead of `_.partial`. - * - * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for provided arguments. - * - * **Note:** This method doesn't set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the new curried function. - * @example - * - * var abc = function(a, b, c) { - * return [a, b, c]; - * }; - * - * var curried = _.curryRight(abc); - * - * curried(3)(2)(1); - * // => [1, 2, 3] - * - * curried(2, 3)(1); - * // => [1, 2, 3] - * - * curried(1, 2, 3); - * // => [1, 2, 3] - * - * // Curried with placeholders. - * curried(3)(1, _)(2); - * // => [1, 2, 3] - */ - function curryRight(func, arity, guard) { - arity = guard ? undefined : arity; - var result = createWrap(func, CURRY_RIGHT_FLAG, undefined, undefined, undefined, undefined, undefined, arity); - result.placeholder = curryRight.placeholder; - return result; - } - - /** - * Creates a debounced function that delays invoking `func` until after `wait` - * milliseconds have elapsed since the last time the debounced function was - * invoked. The debounced function comes with a `cancel` method to cancel - * delayed `func` invocations and a `flush` method to immediately invoke them. - * Provide `options` to indicate whether `func` should be invoked on the - * leading and/or trailing edge of the `wait` timeout. The `func` is invoked - * with the last arguments provided to the debounced function. Subsequent - * calls to the debounced function return the result of the last `func` - * invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the debounced function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.debounce` and `_.throttle`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to debounce. - * @param {number} [wait=0] The number of milliseconds to delay. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=false] - * Specify invoking on the leading edge of the timeout. - * @param {number} [options.maxWait] - * The maximum time `func` is allowed to be delayed before it's invoked. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new debounced function. - * @example - * - * // Avoid costly calculations while the window size is in flux. - * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); - * - * // Invoke `sendMail` when clicked, debouncing subsequent calls. - * jQuery(element).on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * })); - * - * // Ensure `batchLog` is invoked once after 1 second of debounced calls. - * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); - * var source = new EventSource('/stream'); - * jQuery(source).on('message', debounced); - * - * // Cancel the trailing debounced invocation. - * jQuery(window).on('popstate', debounced.cancel); - */ - function debounce(func, wait, options) { - var lastArgs, - lastThis, - maxWait, - result, - timerId, - lastCallTime, - lastInvokeTime = 0, - leading = false, - maxing = false, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - wait = toNumber(wait) || 0; - if (isObject(options)) { - leading = !!options.leading; - maxing = 'maxWait' in options; - maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - - function invokeFunc(time) { - var args = lastArgs, - thisArg = lastThis; - - lastArgs = lastThis = undefined; - lastInvokeTime = time; - result = func.apply(thisArg, args); - return result; - } - - function leadingEdge(time) { - // Reset any `maxWait` timer. - lastInvokeTime = time; - // Start the timer for the trailing edge. - timerId = setTimeout(timerExpired, wait); - // Invoke the leading edge. - return leading ? invokeFunc(time) : result; - } - - function remainingWait(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime, - result = wait - timeSinceLastCall; - - return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; - } - - function shouldInvoke(time) { - var timeSinceLastCall = time - lastCallTime, - timeSinceLastInvoke = time - lastInvokeTime; - - // Either this is the first call, activity has stopped and we're at the - // trailing edge, the system time has gone backwards and we're treating - // it as the trailing edge, or we've hit the `maxWait` limit. - return (lastCallTime === undefined || (timeSinceLastCall >= wait) || - (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); - } - - function timerExpired() { - var time = now(); - if (shouldInvoke(time)) { - return trailingEdge(time); - } - // Restart the timer. - timerId = setTimeout(timerExpired, remainingWait(time)); - } - - function trailingEdge(time) { - timerId = undefined; - - // Only invoke if we have `lastArgs` which means `func` has been - // debounced at least once. - if (trailing && lastArgs) { - return invokeFunc(time); - } - lastArgs = lastThis = undefined; - return result; - } - - function cancel() { - if (timerId !== undefined) { - clearTimeout(timerId); - } - lastInvokeTime = 0; - lastArgs = lastCallTime = lastThis = timerId = undefined; - } - - function flush() { - return timerId === undefined ? result : trailingEdge(now()); - } - - function debounced() { - var time = now(), - isInvoking = shouldInvoke(time); - - lastArgs = arguments; - lastThis = this; - lastCallTime = time; - - if (isInvoking) { - if (timerId === undefined) { - return leadingEdge(lastCallTime); - } - if (maxing) { - // Handle invocations in a tight loop. - timerId = setTimeout(timerExpired, wait); - return invokeFunc(lastCallTime); - } - } - if (timerId === undefined) { - timerId = setTimeout(timerExpired, wait); - } - return result; - } - debounced.cancel = cancel; - debounced.flush = flush; - return debounced; - } - - /** - * Defers invoking the `func` until the current call stack has cleared. Any - * additional arguments are provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to defer. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { - * console.log(text); - * }, 'deferred'); - * // => Logs 'deferred' after one or more milliseconds. - */ - var defer = baseRest(function(func, args) { - return baseDelay(func, 1, args); - }); - - /** - * Invokes `func` after `wait` milliseconds. Any additional arguments are - * provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { - * console.log(text); - * }, 1000, 'later'); - * // => Logs 'later' after one second. - */ - var delay = baseRest(function(func, wait, args) { - return baseDelay(func, toNumber(wait) || 0, args); - }); - - /** - * Creates a function that invokes `func` with arguments reversed. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to flip arguments for. - * @returns {Function} Returns the new flipped function. - * @example - * - * var flipped = _.flip(function() { - * return _.toArray(arguments); - * }); - * - * flipped('a', 'b', 'c', 'd'); - * // => ['d', 'c', 'b', 'a'] - */ - function flip(func) { - return createWrap(func, FLIP_FLAG); - } - - /** - * Creates a function that memoizes the result of `func`. If `resolver` is - * provided, it determines the cache key for storing the result based on the - * arguments provided to the memoized function. By default, the first argument - * provided to the memoized function is used as the map cache key. The `func` - * is invoked with the `this` binding of the memoized function. - * - * **Note:** The cache is exposed as the `cache` property on the memoized - * function. Its creation may be customized by replacing the `_.memoize.Cache` - * constructor with one whose instances implement the - * [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) - * method interface of `delete`, `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to have its output memoized. - * @param {Function} [resolver] The function to resolve the cache key. - * @returns {Function} Returns the new memoized function. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * var other = { 'c': 3, 'd': 4 }; - * - * var values = _.memoize(_.values); - * values(object); - * // => [1, 2] - * - * values(other); - * // => [3, 4] - * - * object.a = 2; - * values(object); - * // => [1, 2] - * - * // Modify the result cache. - * values.cache.set(object, ['a', 'b']); - * values(object); - * // => ['a', 'b'] - * - * // Replace `_.memoize.Cache`. - * _.memoize.Cache = WeakMap; - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - key = resolver ? resolver.apply(this, args) : args[0], - cache = memoized.cache; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - memoized.cache = cache.set(key, result); - return result; - }; - memoized.cache = new (memoize.Cache || MapCache); - return memoized; - } - - // Assign cache to `_.memoize`. - memoize.Cache = MapCache; - - /** - * Creates a function that negates the result of the predicate `func`. The - * `func` predicate is invoked with the `this` binding and arguments of the - * created function. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new negated function. - * @example - * - * function isEven(n) { - * return n % 2 == 0; - * } - * - * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); - * // => [1, 3, 5] - */ - function negate(predicate) { - if (typeof predicate != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function() { - var args = arguments; - switch (args.length) { - case 0: return !predicate.call(this); - case 1: return !predicate.call(this, args[0]); - case 2: return !predicate.call(this, args[0], args[1]); - case 3: return !predicate.call(this, args[0], args[1], args[2]); - } - return !predicate.apply(this, args); - }; - } - - /** - * Creates a function that is restricted to invoking `func` once. Repeat calls - * to the function return the value of the first invocation. The `func` is - * invoked with the `this` binding and arguments of the created function. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // => `createApplication` is invoked once - */ - function once(func) { - return before(2, func); - } - - /** - * Creates a function that invokes `func` with its arguments transformed. - * - * @static - * @since 4.0.0 - * @memberOf _ - * @category Function - * @param {Function} func The function to wrap. - * @param {...(Function|Function[])} [transforms=[_.identity]] - * The argument transforms. - * @returns {Function} Returns the new function. - * @example - * - * function doubled(n) { - * return n * 2; - * } - * - * function square(n) { - * return n * n; - * } - * - * var func = _.overArgs(function(x, y) { - * return [x, y]; - * }, [square, doubled]); - * - * func(9, 3); - * // => [81, 6] - * - * func(10, 5); - * // => [100, 10] - */ - var overArgs = baseRest(function(func, transforms) { - transforms = (transforms.length == 1 && isArray(transforms[0])) - ? arrayMap(transforms[0], baseUnary(getIteratee())) - : arrayMap(baseFlatten(transforms, 1), baseUnary(getIteratee())); - - var funcsLength = transforms.length; - return baseRest(function(args) { - var index = -1, - length = nativeMin(args.length, funcsLength); - - while (++index < length) { - args[index] = transforms[index].call(this, args[index]); - } - return apply(func, this, args); - }); - }); - - /** - * Creates a function that invokes `func` with `partials` prepended to the - * arguments it receives. This method is like `_.bind` except it does **not** - * alter the `this` binding. - * - * The `_.partial.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method doesn't set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @since 0.2.0 - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * function greet(greeting, name) { - * return greeting + ' ' + name; - * } - * - * var sayHelloTo = _.partial(greet, 'hello'); - * sayHelloTo('fred'); - * // => 'hello fred' - * - * // Partially applied with placeholders. - * var greetFred = _.partial(greet, _, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - */ - var partial = baseRest(function(func, partials) { - var holders = replaceHolders(partials, getHolder(partial)); - return createWrap(func, PARTIAL_FLAG, undefined, partials, holders); - }); - - /** - * This method is like `_.partial` except that partially applied arguments - * are appended to the arguments it receives. - * - * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method doesn't set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Function - * @param {Function} func The function to partially apply arguments to. - * @param {...*} [partials] The arguments to be partially applied. - * @returns {Function} Returns the new partially applied function. - * @example - * - * function greet(greeting, name) { - * return greeting + ' ' + name; - * } - * - * var greetFred = _.partialRight(greet, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - * - * // Partially applied with placeholders. - * var sayHelloTo = _.partialRight(greet, 'hello', _); - * sayHelloTo('fred'); - * // => 'hello fred' - */ - var partialRight = baseRest(function(func, partials) { - var holders = replaceHolders(partials, getHolder(partialRight)); - return createWrap(func, PARTIAL_RIGHT_FLAG, undefined, partials, holders); - }); - - /** - * Creates a function that invokes `func` with arguments arranged according - * to the specified `indexes` where the argument value at the first index is - * provided as the first argument, the argument value at the second index is - * provided as the second argument, and so on. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Function - * @param {Function} func The function to rearrange arguments for. - * @param {...(number|number[])} indexes The arranged argument indexes. - * @returns {Function} Returns the new function. - * @example - * - * var rearged = _.rearg(function(a, b, c) { - * return [a, b, c]; - * }, [2, 0, 1]); - * - * rearged('b', 'c', 'a') - * // => ['a', 'b', 'c'] - */ - var rearg = baseRest(function(func, indexes) { - return createWrap(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes, 1)); - }); - - /** - * Creates a function that invokes `func` with the `this` binding of the - * created function and arguments from `start` and beyond provided as - * an array. - * - * **Note:** This method is based on the - * [rest parameter](https://mdn.io/rest_parameters). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to apply a rest parameter to. - * @param {number} [start=func.length-1] The start position of the rest parameter. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.rest(function(what, names) { - * return what + ' ' + _.initial(names).join(', ') + - * (_.size(names) > 1 ? ', & ' : '') + _.last(names); - * }); - * - * say('hello', 'fred', 'barney', 'pebbles'); - * // => 'hello fred, barney, & pebbles' - */ - function rest(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = start === undefined ? start : toInteger(start); - return baseRest(func, start); - } - - /** - * Creates a function that invokes `func` with the `this` binding of the - * create function and an array of arguments much like - * [`Function#apply`](http://www.ecma-international.org/ecma-262/6.0/#sec-function.prototype.apply). - * - * **Note:** This method is based on the - * [spread operator](https://mdn.io/spread_operator). - * - * @static - * @memberOf _ - * @since 3.2.0 - * @category Function - * @param {Function} func The function to spread arguments over. - * @param {number} [start=0] The start position of the spread. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.spread(function(who, what) { - * return who + ' says ' + what; - * }); - * - * say(['fred', 'hello']); - * // => 'fred says hello' - * - * var numbers = Promise.all([ - * Promise.resolve(40), - * Promise.resolve(36) - * ]); - * - * numbers.then(_.spread(function(x, y) { - * return x + y; - * })); - * // => a Promise of 76 - */ - function spread(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = start === undefined ? 0 : nativeMax(toInteger(start), 0); - return baseRest(function(args) { - var array = args[start], - otherArgs = castSlice(args, 0, start); - - if (array) { - arrayPush(otherArgs, array); - } - return apply(func, this, otherArgs); - }); - } - - /** - * Creates a throttled function that only invokes `func` at most once per - * every `wait` milliseconds. The throttled function comes with a `cancel` - * method to cancel delayed `func` invocations and a `flush` method to - * immediately invoke them. Provide `options` to indicate whether `func` - * should be invoked on the leading and/or trailing edge of the `wait` - * timeout. The `func` is invoked with the last arguments provided to the - * throttled function. Subsequent calls to the throttled function return the - * result of the last `func` invocation. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is - * invoked on the trailing edge of the timeout only if the throttled function - * is invoked more than once during the `wait` timeout. - * - * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred - * until to the next tick, similar to `setTimeout` with a timeout of `0`. - * - * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) - * for details over the differences between `_.throttle` and `_.debounce`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {Function} func The function to throttle. - * @param {number} [wait=0] The number of milliseconds to throttle invocations to. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.leading=true] - * Specify invoking on the leading edge of the timeout. - * @param {boolean} [options.trailing=true] - * Specify invoking on the trailing edge of the timeout. - * @returns {Function} Returns the new throttled function. - * @example - * - * // Avoid excessively updating the position while scrolling. - * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); - * - * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes. - * var throttled = _.throttle(renewToken, 300000, { 'trailing': false }); - * jQuery(element).on('click', throttled); - * - * // Cancel the trailing throttled invocation. - * jQuery(window).on('popstate', throttled.cancel); - */ - function throttle(func, wait, options) { - var leading = true, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - if (isObject(options)) { - leading = 'leading' in options ? !!options.leading : leading; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - return debounce(func, wait, { - 'leading': leading, - 'maxWait': wait, - 'trailing': trailing - }); - } - - /** - * Creates a function that accepts up to one argument, ignoring any - * additional arguments. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Function - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - * @example - * - * _.map(['6', '8', '10'], _.unary(parseInt)); - * // => [6, 8, 10] - */ - function unary(func) { - return ary(func, 1); - } - - /** - * Creates a function that provides `value` to `wrapper` as its first - * argument. Any additional arguments provided to the function are appended - * to those provided to the `wrapper`. The wrapper is invoked with the `this` - * binding of the created function. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Function - * @param {*} value The value to wrap. - * @param {Function} [wrapper=identity] The wrapper function. - * @returns {Function} Returns the new function. - * @example - * - * var p = _.wrap(_.escape, function(func, text) { - * return '<p>' + func(text) + '</p>'; - * }); - * - * p('fred, barney, & pebbles'); - * // => '<p>fred, barney, & pebbles</p>' - */ - function wrap(value, wrapper) { - wrapper = wrapper == null ? identity : wrapper; - return partial(wrapper, value); - } - - /*------------------------------------------------------------------------*/ - - /** - * Casts `value` as an array if it's not one. - * - * @static - * @memberOf _ - * @since 4.4.0 - * @category Lang - * @param {*} value The value to inspect. - * @returns {Array} Returns the cast array. - * @example - * - * _.castArray(1); - * // => [1] - * - * _.castArray({ 'a': 1 }); - * // => [{ 'a': 1 }] - * - * _.castArray('abc'); - * // => ['abc'] - * - * _.castArray(null); - * // => [null] - * - * _.castArray(undefined); - * // => [undefined] - * - * _.castArray(); - * // => [] - * - * var array = [1, 2, 3]; - * console.log(_.castArray(array) === array); - * // => true - */ - function castArray() { - if (!arguments.length) { - return []; - } - var value = arguments[0]; - return isArray(value) ? value : [value]; - } - - /** - * Creates a shallow clone of `value`. - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](https://mdn.io/Structured_clone_algorithm) - * and supports cloning arrays, array buffers, booleans, date objects, maps, - * numbers, `Object` objects, regexes, sets, strings, symbols, and typed - * arrays. The own enumerable properties of `arguments` objects are cloned - * as plain objects. An empty object is returned for uncloneable values such - * as error objects, functions, DOM nodes, and WeakMaps. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to clone. - * @returns {*} Returns the cloned value. - * @see _.cloneDeep - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var shallow = _.clone(objects); - * console.log(shallow[0] === objects[0]); - * // => true - */ - function clone(value) { - return baseClone(value, false, true); - } - - /** - * This method is like `_.clone` except that it accepts `customizer` which - * is invoked to produce the cloned value. If `customizer` returns `undefined`, - * cloning is handled by the method instead. The `customizer` is invoked with - * up to four arguments; (value [, index|key, object, stack]). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to clone. - * @param {Function} [customizer] The function to customize cloning. - * @returns {*} Returns the cloned value. - * @see _.cloneDeepWith - * @example - * - * function customizer(value) { - * if (_.isElement(value)) { - * return value.cloneNode(false); - * } - * } - * - * var el = _.cloneWith(document.body, customizer); - * - * console.log(el === document.body); - * // => false - * console.log(el.nodeName); - * // => 'BODY' - * console.log(el.childNodes.length); - * // => 0 - */ - function cloneWith(value, customizer) { - return baseClone(value, false, true, customizer); - } - - /** - * This method is like `_.clone` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @returns {*} Returns the deep cloned value. - * @see _.clone - * @example - * - * var objects = [{ 'a': 1 }, { 'b': 2 }]; - * - * var deep = _.cloneDeep(objects); - * console.log(deep[0] === objects[0]); - * // => false - */ - function cloneDeep(value) { - return baseClone(value, true, true); - } - - /** - * This method is like `_.cloneWith` except that it recursively clones `value`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to recursively clone. - * @param {Function} [customizer] The function to customize cloning. - * @returns {*} Returns the deep cloned value. - * @see _.cloneWith - * @example - * - * function customizer(value) { - * if (_.isElement(value)) { - * return value.cloneNode(true); - * } - * } - * - * var el = _.cloneDeepWith(document.body, customizer); - * - * console.log(el === document.body); - * // => false - * console.log(el.nodeName); - * // => 'BODY' - * console.log(el.childNodes.length); - * // => 20 - */ - function cloneDeepWith(value, customizer) { - return baseClone(value, true, true, customizer); - } - - /** - * Checks if `object` conforms to `source` by invoking the predicate - * properties of `source` with the corresponding property values of `object`. - * - * **Note:** This method is equivalent to `_.conforms` when `source` is - * partially applied. - * - * @static - * @memberOf _ - * @since 4.14.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property predicates to conform to. - * @returns {boolean} Returns `true` if `object` conforms, else `false`. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * - * _.conformsTo(object, { 'b': function(n) { return n > 1; } }); - * // => true - * - * _.conformsTo(object, { 'b': function(n) { return n > 2; } }); - * // => false - */ - function conformsTo(object, source) { - return source == null || baseConformsTo(object, source, keys(source)); - } - - /** - * Performs a - * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) - * comparison between two values to determine if they are equivalent. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.eq(object, object); - * // => true - * - * _.eq(object, other); - * // => false - * - * _.eq('a', 'a'); - * // => true - * - * _.eq('a', Object('a')); - * // => false - * - * _.eq(NaN, NaN); - * // => true - */ - function eq(value, other) { - return value === other || (value !== value && other !== other); - } - - /** - * Checks if `value` is greater than `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than `other`, - * else `false`. - * @see _.lt - * @example - * - * _.gt(3, 1); - * // => true - * - * _.gt(3, 3); - * // => false - * - * _.gt(1, 3); - * // => false - */ - var gt = createRelationalOperation(baseGt); - - /** - * Checks if `value` is greater than or equal to `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is greater than or equal to - * `other`, else `false`. - * @see _.lte - * @example - * - * _.gte(3, 1); - * // => true - * - * _.gte(3, 3); - * // => true - * - * _.gte(1, 3); - * // => false - */ - var gte = createRelationalOperation(function(value, other) { - return value >= other; - }); - - /** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. - return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && - (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); - } - - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ - var isArray = Array.isArray; - - /** - * Checks if `value` is classified as an `ArrayBuffer` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array buffer, else `false`. - * @example - * - * _.isArrayBuffer(new ArrayBuffer(2)); - * // => true - * - * _.isArrayBuffer(new Array(2)); - * // => false - */ - var isArrayBuffer = nodeIsArrayBuffer ? baseUnary(nodeIsArrayBuffer) : baseIsArrayBuffer; - - /** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ - function isArrayLike(value) { - return value != null && isLength(getLength(value)) && !isFunction(value); - } - - /** - * This method is like `_.isArrayLike` except that it also checks if `value` - * is an object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array-like object, - * else `false`. - * @example - * - * _.isArrayLikeObject([1, 2, 3]); - * // => true - * - * _.isArrayLikeObject(document.body.children); - * // => true - * - * _.isArrayLikeObject('abc'); - * // => false - * - * _.isArrayLikeObject(_.noop); - * // => false - */ - function isArrayLikeObject(value) { - return isObjectLike(value) && isArrayLike(value); - } - - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a boolean, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || - (isObjectLike(value) && objectToString.call(value) == boolTag); - } - - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ - var isBuffer = nativeIsBuffer || stubFalse; - - /** - * Checks if `value` is classified as a `Date` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a date object, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - * - * _.isDate('Mon April 23 2012'); - * // => false - */ - var isDate = nodeIsDate ? baseUnary(nodeIsDate) : baseIsDate; - - /** - * Checks if `value` is likely a DOM element. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a DOM element, - * else `false`. - * @example - * - * _.isElement(document.body); - * // => true - * - * _.isElement('<body>'); - * // => false - */ - function isElement(value) { - return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); - } - - /** - * Checks if `value` is an empty object, collection, map, or set. - * - * Objects are considered empty if they have no own enumerable string keyed - * properties. - * - * Array-like values such as `arguments` objects, arrays, buffers, strings, or - * jQuery-like collections are considered empty if they have a `length` of `0`. - * Similarly, maps and sets are considered empty if they have a `size` of `0`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is empty, else `false`. - * @example - * - * _.isEmpty(null); - * // => true - * - * _.isEmpty(true); - * // => true - * - * _.isEmpty(1); - * // => true - * - * _.isEmpty([1, 2, 3]); - * // => false - * - * _.isEmpty({ 'a': 1 }); - * // => false - */ - function isEmpty(value) { - if (isArrayLike(value) && - (isArray(value) || isString(value) || isFunction(value.splice) || - isArguments(value) || isBuffer(value))) { - return !value.length; - } - if (isObjectLike(value)) { - var tag = getTag(value); - if (tag == mapTag || tag == setTag) { - return !value.size; - } - } - for (var key in value) { - if (hasOwnProperty.call(value, key)) { - return false; - } - } - return !(nonEnumShadows && keys(value).length); - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. - * - * **Note:** This method supports comparing arrays, array buffers, booleans, - * date objects, error objects, maps, numbers, `Object` objects, regexes, - * sets, strings, symbols, and typed arrays. `Object` objects are compared - * by their own, not inherited, enumerable properties. Functions and DOM - * nodes are **not** supported. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if the values are equivalent, - * else `false`. - * @example - * - * var object = { 'a': 1 }; - * var other = { 'a': 1 }; - * - * _.isEqual(object, other); - * // => true - * - * object === other; - * // => false - */ - function isEqual(value, other) { - return baseIsEqual(value, other); - } - - /** - * This method is like `_.isEqual` except that it accepts `customizer` which - * is invoked to compare values. If `customizer` returns `undefined`, comparisons - * are handled by the method instead. The `customizer` is invoked with up to - * six arguments: (objValue, othValue [, index|key, object, other, stack]). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if the values are equivalent, - * else `false`. - * @example - * - * function isGreeting(value) { - * return /^h(?:i|ello)$/.test(value); - * } - * - * function customizer(objValue, othValue) { - * if (isGreeting(objValue) && isGreeting(othValue)) { - * return true; - * } - * } - * - * var array = ['hello', 'goodbye']; - * var other = ['hi', 'goodbye']; - * - * _.isEqualWith(array, other, customizer); - * // => true - */ - function isEqualWith(value, other, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - var result = customizer ? customizer(value, other) : undefined; - return result === undefined ? baseIsEqual(value, other, customizer) : !!result; - } - - /** - * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, - * `SyntaxError`, `TypeError`, or `URIError` object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an error object, - * else `false`. - * @example - * - * _.isError(new Error); - * // => true - * - * _.isError(Error); - * // => false - */ - function isError(value) { - if (!isObjectLike(value)) { - return false; - } - return (objectToString.call(value) == errorTag) || - (typeof value.message == 'string' && typeof value.name == 'string'); - } - - /** - * Checks if `value` is a finite primitive number. - * - * **Note:** This method is based on - * [`Number.isFinite`](https://mdn.io/Number/isFinite). - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a finite number, - * else `false`. - * @example - * - * _.isFinite(3); - * // => true - * - * _.isFinite(Number.MIN_VALUE); - * // => true - * - * _.isFinite(Infinity); - * // => false - * - * _.isFinite('3'); - * // => false - */ - function isFinite(value) { - return typeof value == 'number' && nativeIsFinite(value); - } - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 8 which returns 'object' for typed array and weak map constructors, - // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. - var tag = isObject(value) ? objectToString.call(value) : ''; - return tag == funcTag || tag == genTag; - } - - /** - * Checks if `value` is an integer. - * - * **Note:** This method is based on - * [`Number.isInteger`](https://mdn.io/Number/isInteger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an integer, else `false`. - * @example - * - * _.isInteger(3); - * // => true - * - * _.isInteger(Number.MIN_VALUE); - * // => false - * - * _.isInteger(Infinity); - * // => false - * - * _.isInteger('3'); - * // => false - */ - function isInteger(value) { - return typeof value == 'number' && value == toInteger(value); - } - - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This function is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, - * else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ - function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ - function isObject(value) { - var type = typeof value; - return !!value && (type == 'object' || type == 'function'); - } - - /** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ - function isObjectLike(value) { - return !!value && typeof value == 'object'; - } - - /** - * Checks if `value` is classified as a `Map` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a map, else `false`. - * @example - * - * _.isMap(new Map); - * // => true - * - * _.isMap(new WeakMap); - * // => false - */ - var isMap = nodeIsMap ? baseUnary(nodeIsMap) : baseIsMap; - - /** - * Performs a partial deep comparison between `object` and `source` to - * determine if `object` contains equivalent property values. - * - * **Note:** This method supports comparing the same values as `_.isEqual` - * and is equivalent to `_.matches` when `source` is partially applied. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * var object = { 'a': 1, 'b': 2 }; - * - * _.isMatch(object, { 'b': 2 }); - * // => true - * - * _.isMatch(object, { 'b': 1 }); - * // => false - */ - function isMatch(object, source) { - return object === source || baseIsMatch(object, source, getMatchData(source)); - } - - /** - * This method is like `_.isMatch` except that it accepts `customizer` which - * is invoked to compare values. If `customizer` returns `undefined`, comparisons - * are handled by the method instead. The `customizer` is invoked with five - * arguments: (objValue, srcValue, index|key, object, source). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {Object} object The object to inspect. - * @param {Object} source The object of property values to match. - * @param {Function} [customizer] The function to customize comparisons. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * function isGreeting(value) { - * return /^h(?:i|ello)$/.test(value); - * } - * - * function customizer(objValue, srcValue) { - * if (isGreeting(objValue) && isGreeting(srcValue)) { - * return true; - * } - * } - * - * var object = { 'greeting': 'hello' }; - * var source = { 'greeting': 'hi' }; - * - * _.isMatchWith(object, source, customizer); - * // => true - */ - function isMatchWith(object, source, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return baseIsMatch(object, source, getMatchData(source), customizer); - } - - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is based on - * [`Number.isNaN`](https://mdn.io/Number/isNaN) and is not the same as - * global [`isNaN`](https://mdn.io/isNaN) which returns `true` for - * `undefined` and other non-number values. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - * @example - * - * _.isNaN(NaN); - * // => true - * - * _.isNaN(new Number(NaN)); - * // => true - * - * isNaN(undefined); - * // => true - * - * _.isNaN(undefined); - * // => false - */ - function isNaN(value) { - // An `NaN` primitive is the only value that is not equal to itself. - // Perform the `toStringTag` check first to avoid errors with some - // ActiveX objects in IE. - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is a pristine native function. - * - * **Note:** This method can't reliably detect native functions in the presence - * of the core-js package because core-js circumvents this kind of detection. - * Despite multiple requests, the core-js maintainer has made it clear: any - * attempt to fix the detection will be obstructed. As a result, we're left - * with little choice but to throw an error. Unfortunately, this also affects - * packages, like [babel-polyfill](https://www.npmjs.com/package/babel-polyfill), - * which rely on core-js. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a native function, - * else `false`. - * @example - * - * _.isNative(Array.prototype.push); - * // => true - * - * _.isNative(_); - * // => false - */ - function isNative(value) { - if (isMaskable(value)) { - throw new Error('This method is not supported with core-js. Try https://github.com/es-shims.'); - } - return baseIsNative(value); - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `null`, else `false`. - * @example - * - * _.isNull(null); - * // => true - * - * _.isNull(void 0); - * // => false - */ - function isNull(value) { - return value === null; - } - - /** - * Checks if `value` is `null` or `undefined`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is nullish, else `false`. - * @example - * - * _.isNil(null); - * // => true - * - * _.isNil(void 0); - * // => true - * - * _.isNil(NaN); - * // => false - */ - function isNil(value) { - return value == null; - } - - /** - * Checks if `value` is classified as a `Number` primitive or object. - * - * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are - * classified as numbers, use the `_.isFinite` method. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a number, else `false`. - * @example - * - * _.isNumber(3); - * // => true - * - * _.isNumber(Number.MIN_VALUE); - * // => true - * - * _.isNumber(Infinity); - * // => true - * - * _.isNumber('3'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || - (isObjectLike(value) && objectToString.call(value) == numberTag); - } - - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * @static - * @memberOf _ - * @since 0.8.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, - * else `false`. - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * _.isPlainObject(new Foo); - * // => false - * - * _.isPlainObject([1, 2, 3]); - * // => false - * - * _.isPlainObject({ 'x': 0, 'y': 0 }); - * // => true - * - * _.isPlainObject(Object.create(null)); - * // => true - */ - function isPlainObject(value) { - if (!isObjectLike(value) || - objectToString.call(value) != objectTag || isHostObject(value)) { - return false; - } - var proto = getPrototype(value); - if (proto === null) { - return true; - } - var Ctor = hasOwnProperty.call(proto, 'constructor') && proto.constructor; - return (typeof Ctor == 'function' && - Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString); - } - - /** - * Checks if `value` is classified as a `RegExp` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a regexp, else `false`. - * @example - * - * _.isRegExp(/abc/); - * // => true - * - * _.isRegExp('/abc/'); - * // => false - */ - var isRegExp = nodeIsRegExp ? baseUnary(nodeIsRegExp) : baseIsRegExp; - - /** - * Checks if `value` is a safe integer. An integer is safe if it's an IEEE-754 - * double precision number which isn't the result of a rounded unsafe integer. - * - * **Note:** This method is based on - * [`Number.isSafeInteger`](https://mdn.io/Number/isSafeInteger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a safe integer, - * else `false`. - * @example - * - * _.isSafeInteger(3); - * // => true - * - * _.isSafeInteger(Number.MIN_VALUE); - * // => false - * - * _.isSafeInteger(Infinity); - * // => false - * - * _.isSafeInteger('3'); - * // => false - */ - function isSafeInteger(value) { - return isInteger(value) && value >= -MAX_SAFE_INTEGER && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is classified as a `Set` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a set, else `false`. - * @example - * - * _.isSet(new Set); - * // => true - * - * _.isSet(new WeakSet); - * // => false - */ - var isSet = nodeIsSet ? baseUnary(nodeIsSet) : baseIsSet; - - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a string, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || - (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); - } - - /** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ - function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && objectToString.call(value) == symbolTag); - } - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - - /** - * Checks if `value` is `undefined`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. - * @example - * - * _.isUndefined(void 0); - * // => true - * - * _.isUndefined(null); - * // => false - */ - function isUndefined(value) { - return value === undefined; - } - - /** - * Checks if `value` is classified as a `WeakMap` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a weak map, else `false`. - * @example - * - * _.isWeakMap(new WeakMap); - * // => true - * - * _.isWeakMap(new Map); - * // => false - */ - function isWeakMap(value) { - return isObjectLike(value) && getTag(value) == weakMapTag; - } - - /** - * Checks if `value` is classified as a `WeakSet` object. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a weak set, else `false`. - * @example - * - * _.isWeakSet(new WeakSet); - * // => true - * - * _.isWeakSet(new Set); - * // => false - */ - function isWeakSet(value) { - return isObjectLike(value) && objectToString.call(value) == weakSetTag; - } - - /** - * Checks if `value` is less than `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than `other`, - * else `false`. - * @see _.gt - * @example - * - * _.lt(1, 3); - * // => true - * - * _.lt(3, 3); - * // => false - * - * _.lt(3, 1); - * // => false - */ - var lt = createRelationalOperation(baseLt); - - /** - * Checks if `value` is less than or equal to `other`. - * - * @static - * @memberOf _ - * @since 3.9.0 - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @returns {boolean} Returns `true` if `value` is less than or equal to - * `other`, else `false`. - * @see _.gte - * @example - * - * _.lte(1, 3); - * // => true - * - * _.lte(3, 3); - * // => true - * - * _.lte(3, 1); - * // => false - */ - var lte = createRelationalOperation(function(value, other) { - return value <= other; - }); - - /** - * Converts `value` to an array. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * _.toArray({ 'a': 1, 'b': 2 }); - * // => [1, 2] - * - * _.toArray('abc'); - * // => ['a', 'b', 'c'] - * - * _.toArray(1); - * // => [] - * - * _.toArray(null); - * // => [] - */ - function toArray(value) { - if (!value) { - return []; - } - if (isArrayLike(value)) { - return isString(value) ? stringToArray(value) : copyArray(value); - } - if (iteratorSymbol && value[iteratorSymbol]) { - return iteratorToArray(value[iteratorSymbol]()); - } - var tag = getTag(value), - func = tag == mapTag ? mapToArray : (tag == setTag ? setToArray : values); - - return func(value); - } - - /** - * Converts `value` to a finite number. - * - * @static - * @memberOf _ - * @since 4.12.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted number. - * @example - * - * _.toFinite(3.2); - * // => 3.2 - * - * _.toFinite(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toFinite(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toFinite('3.2'); - * // => 3.2 - */ - function toFinite(value) { - if (!value) { - return value === 0 ? value : 0; - } - value = toNumber(value); - if (value === INFINITY || value === -INFINITY) { - var sign = (value < 0 ? -1 : 1); - return sign * MAX_INTEGER; - } - return value === value ? value : 0; - } - - /** - * Converts `value` to an integer. - * - * **Note:** This method is loosely based on - * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toInteger(3.2); - * // => 3 - * - * _.toInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toInteger(Infinity); - * // => 1.7976931348623157e+308 - * - * _.toInteger('3.2'); - * // => 3 - */ - function toInteger(value) { - var result = toFinite(value), - remainder = result % 1; - - return result === result ? (remainder ? result - remainder : result) : 0; - } - - /** - * Converts `value` to an integer suitable for use as the length of an - * array-like object. - * - * **Note:** This method is based on - * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toLength(3.2); - * // => 3 - * - * _.toLength(Number.MIN_VALUE); - * // => 0 - * - * _.toLength(Infinity); - * // => 4294967295 - * - * _.toLength('3.2'); - * // => 3 - */ - function toLength(value) { - return value ? baseClamp(toInteger(value), 0, MAX_ARRAY_LENGTH) : 0; - } - - /** - * Converts `value` to a number. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {number} Returns the number. - * @example - * - * _.toNumber(3.2); - * // => 3.2 - * - * _.toNumber(Number.MIN_VALUE); - * // => 5e-324 - * - * _.toNumber(Infinity); - * // => Infinity - * - * _.toNumber('3.2'); - * // => 3.2 - */ - function toNumber(value) { - if (typeof value == 'number') { - return value; - } - if (isSymbol(value)) { - return NAN; - } - if (isObject(value)) { - var other = isFunction(value.valueOf) ? value.valueOf() : value; - value = isObject(other) ? (other + '') : other; - } - if (typeof value != 'string') { - return value === 0 ? value : +value; - } - value = value.replace(reTrim, ''); - var isBinary = reIsBinary.test(value); - return (isBinary || reIsOctal.test(value)) - ? freeParseInt(value.slice(2), isBinary ? 2 : 8) - : (reIsBadHex.test(value) ? NAN : +value); - } - - /** - * Converts `value` to a plain object flattening inherited enumerable string - * keyed properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {Object} Returns the converted plain object. - * @example - * - * function Foo() { - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.assign({ 'a': 1 }, new Foo); - * // => { 'a': 1, 'b': 2 } - * - * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); - * // => { 'a': 1, 'b': 2, 'c': 3 } - */ - function toPlainObject(value) { - return copyObject(value, keysIn(value)); - } - - /** - * Converts `value` to a safe integer. A safe integer can be compared and - * represented correctly. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {number} Returns the converted integer. - * @example - * - * _.toSafeInteger(3.2); - * // => 3 - * - * _.toSafeInteger(Number.MIN_VALUE); - * // => 0 - * - * _.toSafeInteger(Infinity); - * // => 9007199254740991 - * - * _.toSafeInteger('3.2'); - * // => 3 - */ - function toSafeInteger(value) { - return baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER); - } - - /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to process. - * @returns {string} Returns the string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ - function toString(value) { - return value == null ? '' : baseToString(value); - } - - /*------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable string keyed properties of source objects to the - * destination object. Source objects are applied from left to right. - * Subsequent sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object` and is loosely based on - * [`Object.assign`](https://mdn.io/Object/assign). - * - * @static - * @memberOf _ - * @since 0.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assignIn - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assign({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'c': 3 } - */ - var assign = createAssigner(function(object, source) { - if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { - copyObject(source, keys(source), object); - return; - } - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - assignValue(object, key, source[key]); - } - } - }); - - /** - * This method is like `_.assign` except that it iterates over own and - * inherited source properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extend - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.assign - * @example - * - * function Foo() { - * this.a = 1; - * } - * - * function Bar() { - * this.c = 3; - * } - * - * Foo.prototype.b = 2; - * Bar.prototype.d = 4; - * - * _.assignIn({ 'a': 0 }, new Foo, new Bar); - * // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4 } - */ - var assignIn = createAssigner(function(object, source) { - if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { - copyObject(source, keysIn(source), object); - return; - } - for (var key in source) { - assignValue(object, key, source[key]); - } - }); - - /** - * This method is like `_.assignIn` except that it accepts `customizer` - * which is invoked to produce the assigned values. If `customizer` returns - * `undefined`, assignment is handled by the method instead. The `customizer` - * is invoked with five arguments: (objValue, srcValue, key, object, source). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias extendWith - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @see _.assignWith - * @example - * - * function customizer(objValue, srcValue) { - * return _.isUndefined(objValue) ? srcValue : objValue; - * } - * - * var defaults = _.partialRight(_.assignInWith, customizer); - * - * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var assignInWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keysIn(source), object, customizer); - }); - - /** - * This method is like `_.assign` except that it accepts `customizer` - * which is invoked to produce the assigned values. If `customizer` returns - * `undefined`, assignment is handled by the method instead. The `customizer` - * is invoked with five arguments: (objValue, srcValue, key, object, source). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @see _.assignInWith - * @example - * - * function customizer(objValue, srcValue) { - * return _.isUndefined(objValue) ? srcValue : objValue; - * } - * - * var defaults = _.partialRight(_.assignWith, customizer); - * - * defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var assignWith = createAssigner(function(object, source, srcIndex, customizer) { - copyObject(source, keys(source), object, customizer); - }); - - /** - * Creates an array of values corresponding to `paths` of `object`. - * - * @static - * @memberOf _ - * @since 1.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {...(string|string[])} [paths] The property paths of elements to pick. - * @returns {Array} Returns the picked values. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] }; - * - * _.at(object, ['a[0].b.c', 'a[1]']); - * // => [3, 4] - */ - var at = baseRest(function(object, paths) { - return baseAt(object, baseFlatten(paths, 1)); - }); - - /** - * Creates an object that inherits from the `prototype` object. If a - * `properties` object is given, its own enumerable string keyed properties - * are assigned to the created object. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @returns {Object} Returns the new object. - * @example - * - * function Shape() { - * this.x = 0; - * this.y = 0; - * } - * - * function Circle() { - * Shape.call(this); - * } - * - * Circle.prototype = _.create(Shape.prototype, { - * 'constructor': Circle - * }); - * - * var circle = new Circle; - * circle instanceof Circle; - * // => true - * - * circle instanceof Shape; - * // => true - */ - function create(prototype, properties) { - var result = baseCreate(prototype); - return properties ? baseAssign(result, properties) : result; - } - - /** - * Assigns own and inherited enumerable string keyed properties of source - * objects to the destination object for all destination properties that - * resolve to `undefined`. Source objects are applied from left to right. - * Once a property is set, additional values of the same property are ignored. - * - * **Note:** This method mutates `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaultsDeep - * @example - * - * _.defaults({ 'a': 1 }, { 'b': 2 }, { 'a': 3 }); - * // => { 'a': 1, 'b': 2 } - */ - var defaults = baseRest(function(args) { - args.push(undefined, assignInDefaults); - return apply(assignInWith, undefined, args); - }); - - /** - * This method is like `_.defaults` except that it recursively assigns - * default properties. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @see _.defaults - * @example - * - * _.defaultsDeep({ 'a': { 'b': 2 } }, { 'a': { 'b': 1, 'c': 3 } }); - * // => { 'a': { 'b': 2, 'c': 3 } } - */ - var defaultsDeep = baseRest(function(args) { - args.push(undefined, mergeDefaults); - return apply(mergeWith, undefined, args); - }); - - /** - * This method is like `_.find` except that it returns the key of the first - * element `predicate` returns truthy for instead of the element itself. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category Object - * @param {Object} object The object to search. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findKey(users, function(o) { return o.age < 40; }); - * // => 'barney' (iteration order is not guaranteed) - * - * // The `_.matches` iteratee shorthand. - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findKey(users, 'active'); - * // => 'barney' - */ - function findKey(object, predicate) { - return baseFindKey(object, getIteratee(predicate, 3), baseForOwn); - } - - /** - * This method is like `_.findKey` except that it iterates over elements of - * a collection in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to search. - * @param {Function} [predicate=_.identity] The function invoked per iteration. - * @returns {string|undefined} Returns the key of the matched element, - * else `undefined`. - * @example - * - * var users = { - * 'barney': { 'age': 36, 'active': true }, - * 'fred': { 'age': 40, 'active': false }, - * 'pebbles': { 'age': 1, 'active': true } - * }; - * - * _.findLastKey(users, function(o) { return o.age < 40; }); - * // => returns 'pebbles' assuming `_.findKey` returns 'barney' - * - * // The `_.matches` iteratee shorthand. - * _.findLastKey(users, { 'age': 36, 'active': true }); - * // => 'barney' - * - * // The `_.matchesProperty` iteratee shorthand. - * _.findLastKey(users, ['active', false]); - * // => 'fred' - * - * // The `_.property` iteratee shorthand. - * _.findLastKey(users, 'active'); - * // => 'pebbles' - */ - function findLastKey(object, predicate) { - return baseFindKey(object, getIteratee(predicate, 3), baseForOwnRight); - } - - /** - * Iterates over own and inherited enumerable string keyed properties of an - * object and invokes `iteratee` for each property. The iteratee is invoked - * with three arguments: (value, key, object). Iteratee functions may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 0.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forInRight - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forIn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a', 'b', then 'c' (iteration order is not guaranteed). - */ - function forIn(object, iteratee) { - return object == null - ? object - : baseFor(object, getIteratee(iteratee, 3), keysIn); - } - - /** - * This method is like `_.forIn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forIn - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forInRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c'. - */ - function forInRight(object, iteratee) { - return object == null - ? object - : baseForRight(object, getIteratee(iteratee, 3), keysIn); - } - - /** - * Iterates over own enumerable string keyed properties of an object and - * invokes `iteratee` for each property. The iteratee is invoked with three - * arguments: (value, key, object). Iteratee functions may exit iteration - * early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 0.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forOwnRight - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'a' then 'b' (iteration order is not guaranteed). - */ - function forOwn(object, iteratee) { - return object && baseForOwn(object, getIteratee(iteratee, 3)); - } - - /** - * This method is like `_.forOwn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @since 2.0.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns `object`. - * @see _.forOwn - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwnRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => Logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b'. - */ - function forOwnRight(object, iteratee) { - return object && baseForOwnRight(object, getIteratee(iteratee, 3)); - } - - /** - * Creates an array of function property names from own enumerable properties - * of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the function names. - * @see _.functionsIn - * @example - * - * function Foo() { - * this.a = _.constant('a'); - * this.b = _.constant('b'); - * } - * - * Foo.prototype.c = _.constant('c'); - * - * _.functions(new Foo); - * // => ['a', 'b'] - */ - function functions(object) { - return object == null ? [] : baseFunctions(object, keys(object)); - } - - /** - * Creates an array of function property names from own and inherited - * enumerable properties of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the function names. - * @see _.functions - * @example - * - * function Foo() { - * this.a = _.constant('a'); - * this.b = _.constant('b'); - * } - * - * Foo.prototype.c = _.constant('c'); - * - * _.functionsIn(new Foo); - * // => ['a', 'b', 'c'] - */ - function functionsIn(object) { - return object == null ? [] : baseFunctions(object, keysIn(object)); - } - - /** - * Gets the value at `path` of `object`. If the resolved value is - * `undefined`, the `defaultValue` is returned in its place. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to get. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.get(object, 'a[0].b.c'); - * // => 3 - * - * _.get(object, ['a', '0', 'b', 'c']); - * // => 3 - * - * _.get(object, 'a.b.c', 'default'); - * // => 'default' - */ - function get(object, path, defaultValue) { - var result = object == null ? undefined : baseGet(object, path); - return result === undefined ? defaultValue : result; - } - - /** - * Checks if `path` is a direct property of `object`. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = { 'a': { 'b': 2 } }; - * var other = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.has(object, 'a'); - * // => true - * - * _.has(object, 'a.b'); - * // => true - * - * _.has(object, ['a', 'b']); - * // => true - * - * _.has(other, 'a'); - * // => false - */ - function has(object, path) { - return object != null && hasPath(object, path, baseHas); - } - - /** - * Checks if `path` is a direct or inherited property of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` exists, else `false`. - * @example - * - * var object = _.create({ 'a': _.create({ 'b': 2 }) }); - * - * _.hasIn(object, 'a'); - * // => true - * - * _.hasIn(object, 'a.b'); - * // => true - * - * _.hasIn(object, ['a', 'b']); - * // => true - * - * _.hasIn(object, 'b'); - * // => false - */ - function hasIn(object, path) { - return object != null && hasPath(object, path, baseHasIn); - } - - /** - * Creates an object composed of the inverted keys and values of `object`. - * If `object` contains duplicate values, subsequent values overwrite - * property assignments of previous values. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Object - * @param {Object} object The object to invert. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invert(object); - * // => { '1': 'c', '2': 'b' } - */ - var invert = createInverter(function(result, value, key) { - result[value] = key; - }, constant(identity)); - - /** - * This method is like `_.invert` except that the inverted object is generated - * from the results of running each element of `object` thru `iteratee`. The - * corresponding inverted value of each inverted key is an array of keys - * responsible for generating the inverted value. The iteratee is invoked - * with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.1.0 - * @category Object - * @param {Object} object The object to invert. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invertBy(object); - * // => { '1': ['a', 'c'], '2': ['b'] } - * - * _.invertBy(object, function(value) { - * return 'group' + value; - * }); - * // => { 'group1': ['a', 'c'], 'group2': ['b'] } - */ - var invertBy = createInverter(function(result, value, key) { - if (hasOwnProperty.call(result, value)) { - result[value].push(key); - } else { - result[value] = [key]; - } - }, getIteratee); - - /** - * Invokes the method at `path` of `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the method to invoke. - * @param {...*} [args] The arguments to invoke the method with. - * @returns {*} Returns the result of the invoked method. - * @example - * - * var object = { 'a': [{ 'b': { 'c': [1, 2, 3, 4] } }] }; - * - * _.invoke(object, 'a[0].b.c.slice', 1, 3); - * // => [2, 3] - */ - var invoke = baseRest(baseInvoke); - - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - function keys(object) { - var isProto = isPrototype(object); - if (!(isProto || isArrayLike(object))) { - return baseKeys(object); - } - var indexes = indexKeys(object), - skipIndexes = !!indexes, - result = indexes || [], - length = result.length; - - for (var key in object) { - if (baseHas(object, key) && - !(skipIndexes && (key == 'length' || isIndex(key, length))) && - !(isProto && key == 'constructor')) { - result.push(key); - } - } - return result; - } - - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - var index = -1, - isProto = isPrototype(object), - props = baseKeysIn(object), - propsLength = props.length, - indexes = indexKeys(object), - skipIndexes = !!indexes, - result = indexes || [], - length = result.length; - - while (++index < propsLength) { - var key = props[index]; - if (!(skipIndexes && (key == 'length' || isIndex(key, length))) && - !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; - } - - /** - * The opposite of `_.mapValues`; this method creates an object with the - * same values as `object` and keys generated by running each own enumerable - * string keyed property of `object` thru `iteratee`. The iteratee is invoked - * with three arguments: (value, key, object). - * - * @static - * @memberOf _ - * @since 3.8.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapValues - * @example - * - * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { - * return key + value; - * }); - * // => { 'a1': 1, 'b2': 2 } - */ - function mapKeys(object, iteratee) { - var result = {}; - iteratee = getIteratee(iteratee, 3); - - baseForOwn(object, function(value, key, object) { - result[iteratee(value, key, object)] = value; - }); - return result; - } - - /** - * Creates an object with the same keys as `object` and values generated - * by running each own enumerable string keyed property of `object` thru - * `iteratee`. The iteratee is invoked with three arguments: - * (value, key, object). - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Object} Returns the new mapped object. - * @see _.mapKeys - * @example - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * _.mapValues(users, function(o) { return o.age; }); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - * - * // The `_.property` iteratee shorthand. - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ - function mapValues(object, iteratee) { - var result = {}; - iteratee = getIteratee(iteratee, 3); - - baseForOwn(object, function(value, key, object) { - result[key] = iteratee(value, key, object); - }); - return result; - } - - /** - * This method is like `_.assign` except that it recursively merges own and - * inherited enumerable string keyed properties of source objects into the - * destination object. Source properties that resolve to `undefined` are - * skipped if a destination value exists. Array and plain object properties - * are merged recursively. Other objects and value types are overridden by - * assignment. Source objects are applied from left to right. Subsequent - * sources overwrite property assignments of previous sources. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 0.5.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * var object = { - * 'a': [{ 'b': 2 }, { 'd': 4 }] - * }; - * - * var other = { - * 'a': [{ 'c': 3 }, { 'e': 5 }] - * }; - * - * _.merge(object, other); - * // => { 'a': [{ 'b': 2, 'c': 3 }, { 'd': 4, 'e': 5 }] } - */ - var merge = createAssigner(function(object, source, srcIndex) { - baseMerge(object, source, srcIndex); - }); - - /** - * This method is like `_.merge` except that it accepts `customizer` which - * is invoked to produce the merged values of the destination and source - * properties. If `customizer` returns `undefined`, merging is handled by the - * method instead. The `customizer` is invoked with seven arguments: - * (objValue, srcValue, key, object, source, stack). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The destination object. - * @param {...Object} sources The source objects. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * function customizer(objValue, srcValue) { - * if (_.isArray(objValue)) { - * return objValue.concat(srcValue); - * } - * } - * - * var object = { 'a': [1], 'b': [2] }; - * var other = { 'a': [3], 'b': [4] }; - * - * _.mergeWith(object, other, customizer); - * // => { 'a': [1, 3], 'b': [2, 4] } - */ - var mergeWith = createAssigner(function(object, source, srcIndex, customizer) { - baseMerge(object, source, srcIndex, customizer); - }); - - /** - * The opposite of `_.pick`; this method creates an object composed of the - * own and inherited enumerable string keyed properties of `object` that are - * not omitted. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [props] The property identifiers to omit. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omit(object, ['a', 'c']); - * // => { 'b': '2' } - */ - var omit = baseRest(function(object, props) { - if (object == null) { - return {}; - } - props = arrayMap(baseFlatten(props, 1), toKey); - return basePick(object, baseDifference(getAllKeysIn(object), props)); - }); - - /** - * The opposite of `_.pickBy`; this method creates an object composed of - * the own and inherited enumerable string keyed properties of `object` that - * `predicate` doesn't return truthy for. The predicate is invoked with two - * arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.omitBy(object, _.isNumber); - * // => { 'b': '2' } - */ - function omitBy(object, predicate) { - return pickBy(object, negate(getIteratee(predicate))); - } - - /** - * Creates an object composed of the picked `object` properties. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {...(string|string[])} [props] The property identifiers to pick. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pick(object, ['a', 'c']); - * // => { 'a': 1, 'c': 3 } - */ - var pick = baseRest(function(object, props) { - return object == null ? {} : basePick(object, arrayMap(baseFlatten(props, 1), toKey)); - }); - - /** - * Creates an object composed of the `object` properties `predicate` returns - * truthy for. The predicate is invoked with two arguments: (value, key). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The source object. - * @param {Function} [predicate=_.identity] The function invoked per property. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'a': 1, 'b': '2', 'c': 3 }; - * - * _.pickBy(object, _.isNumber); - * // => { 'a': 1, 'c': 3 } - */ - function pickBy(object, predicate) { - return object == null ? {} : basePickBy(object, getAllKeysIn(object), getIteratee(predicate)); - } - - /** - * This method is like `_.get` except that if the resolved value is a - * function it's invoked with the `this` binding of its parent object and - * its result is returned. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path of the property to resolve. - * @param {*} [defaultValue] The value returned for `undefined` resolved values. - * @returns {*} Returns the resolved value. - * @example - * - * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; - * - * _.result(object, 'a[0].b.c1'); - * // => 3 - * - * _.result(object, 'a[0].b.c2'); - * // => 4 - * - * _.result(object, 'a[0].b.c3', 'default'); - * // => 'default' - * - * _.result(object, 'a[0].b.c3', _.constant('default')); - * // => 'default' - */ - function result(object, path, defaultValue) { - path = isKey(path, object) ? [path] : castPath(path); - - var index = -1, - length = path.length; - - // Ensure the loop is entered when path is empty. - if (!length) { - object = undefined; - length = 1; - } - while (++index < length) { - var value = object == null ? undefined : object[toKey(path[index])]; - if (value === undefined) { - index = length; - value = defaultValue; - } - object = isFunction(value) ? value.call(object) : value; - } - return object; - } - - /** - * Sets the value at `path` of `object`. If a portion of `path` doesn't exist, - * it's created. Arrays are created for missing index properties while objects - * are created for all other missing properties. Use `_.setWith` to customize - * `path` creation. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.set(object, 'a[0].b.c', 4); - * console.log(object.a[0].b.c); - * // => 4 - * - * _.set(object, ['x', '0', 'y', 'z'], 5); - * console.log(object.x[0].y.z); - * // => 5 - */ - function set(object, path, value) { - return object == null ? object : baseSet(object, path, value); - } - - /** - * This method is like `_.set` except that it accepts `customizer` which is - * invoked to produce the objects of `path`. If `customizer` returns `undefined` - * path creation is handled by the method instead. The `customizer` is invoked - * with three arguments: (nsValue, key, nsObject). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {*} value The value to set. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * var object = {}; - * - * _.setWith(object, '[0][1]', 'a', Object); - * // => { '0': { '1': 'a' } } - */ - function setWith(object, path, value, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return object == null ? object : baseSet(object, path, value, customizer); - } - - /** - * Creates an array of own enumerable string keyed-value pairs for `object` - * which can be consumed by `_.fromPairs`. If `object` is a map or set, its - * entries are returned. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias entries - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the key-value pairs. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.toPairs(new Foo); - * // => [['a', 1], ['b', 2]] (iteration order is not guaranteed) - */ - var toPairs = createToPairs(keys); - - /** - * Creates an array of own and inherited enumerable string keyed-value pairs - * for `object` which can be consumed by `_.fromPairs`. If `object` is a map - * or set, its entries are returned. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @alias entriesIn - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the key-value pairs. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.toPairsIn(new Foo); - * // => [['a', 1], ['b', 2], ['c', 3]] (iteration order is not guaranteed) - */ - var toPairsIn = createToPairs(keysIn); - - /** - * An alternative to `_.reduce`; this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own - * enumerable string keyed properties thru `iteratee`, with each invocation - * potentially mutating the `accumulator` object. If `accumulator` is not - * provided, a new object with the same `[[Prototype]]` will be used. The - * iteratee is invoked with four arguments: (accumulator, value, key, object). - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @since 1.3.0 - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @returns {*} Returns the accumulated value. - * @example - * - * _.transform([2, 3, 4], function(result, n) { - * result.push(n *= n); - * return n % 2 == 0; - * }, []); - * // => [4, 9] - * - * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) { - * (result[value] || (result[value] = [])).push(key); - * }, {}); - * // => { '1': ['a', 'c'], '2': ['b'] } - */ - function transform(object, iteratee, accumulator) { - var isArr = isArray(object) || isTypedArray(object); - iteratee = getIteratee(iteratee, 4); - - if (accumulator == null) { - if (isArr || isObject(object)) { - var Ctor = object.constructor; - if (isArr) { - accumulator = isArray(object) ? new Ctor : []; - } else { - accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; - } - } else { - accumulator = {}; - } - } - (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - return accumulator; - } - - /** - * Removes the property at `path` of `object`. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to unset. - * @returns {boolean} Returns `true` if the property is deleted, else `false`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 7 } }] }; - * _.unset(object, 'a[0].b.c'); - * // => true - * - * console.log(object); - * // => { 'a': [{ 'b': {} }] }; - * - * _.unset(object, ['a', '0', 'b', 'c']); - * // => true - * - * console.log(object); - * // => { 'a': [{ 'b': {} }] }; - */ - function unset(object, path) { - return object == null ? true : baseUnset(object, path); - } - - /** - * This method is like `_.set` except that accepts `updater` to produce the - * value to set. Use `_.updateWith` to customize `path` creation. The `updater` - * is invoked with one argument: (value). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {Function} updater The function to produce the updated value. - * @returns {Object} Returns `object`. - * @example - * - * var object = { 'a': [{ 'b': { 'c': 3 } }] }; - * - * _.update(object, 'a[0].b.c', function(n) { return n * n; }); - * console.log(object.a[0].b.c); - * // => 9 - * - * _.update(object, 'x[0].y.z', function(n) { return n ? n + 1 : 0; }); - * console.log(object.x[0].y.z); - * // => 0 - */ - function update(object, path, updater) { - return object == null ? object : baseUpdate(object, path, castFunction(updater)); - } - - /** - * This method is like `_.update` except that it accepts `customizer` which is - * invoked to produce the objects of `path`. If `customizer` returns `undefined` - * path creation is handled by the method instead. The `customizer` is invoked - * with three arguments: (nsValue, key, nsObject). - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @since 4.6.0 - * @category Object - * @param {Object} object The object to modify. - * @param {Array|string} path The path of the property to set. - * @param {Function} updater The function to produce the updated value. - * @param {Function} [customizer] The function to customize assigned values. - * @returns {Object} Returns `object`. - * @example - * - * var object = {}; - * - * _.updateWith(object, '[0][1]', _.constant('a'), Object); - * // => { '0': { '1': 'a' } } - */ - function updateWith(object, path, updater, customizer) { - customizer = typeof customizer == 'function' ? customizer : undefined; - return object == null ? object : baseUpdate(object, path, castFunction(updater), customizer); - } - - /** - * Creates an array of the own enumerable string keyed property values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.values(new Foo); - * // => [1, 2] (iteration order is not guaranteed) - * - * _.values('hi'); - * // => ['h', 'i'] - */ - function values(object) { - return object ? baseValues(object, keys(object)) : []; - } - - /** - * Creates an array of the own and inherited enumerable string keyed property - * values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property values. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.valuesIn(new Foo); - * // => [1, 2, 3] (iteration order is not guaranteed) - */ - function valuesIn(object) { - return object == null ? [] : baseValues(object, keysIn(object)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Clamps `number` within the inclusive `lower` and `upper` bounds. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Number - * @param {number} number The number to clamp. - * @param {number} [lower] The lower bound. - * @param {number} upper The upper bound. - * @returns {number} Returns the clamped number. - * @example - * - * _.clamp(-10, -5, 5); - * // => -5 - * - * _.clamp(10, -5, 5); - * // => 5 - */ - function clamp(number, lower, upper) { - if (upper === undefined) { - upper = lower; - lower = undefined; - } - if (upper !== undefined) { - upper = toNumber(upper); - upper = upper === upper ? upper : 0; - } - if (lower !== undefined) { - lower = toNumber(lower); - lower = lower === lower ? lower : 0; - } - return baseClamp(toNumber(number), lower, upper); - } - - /** - * Checks if `n` is between `start` and up to, but not including, `end`. If - * `end` is not specified, it's set to `start` with `start` then set to `0`. - * If `start` is greater than `end` the params are swapped to support - * negative ranges. - * - * @static - * @memberOf _ - * @since 3.3.0 - * @category Number - * @param {number} number The number to check. - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @returns {boolean} Returns `true` if `number` is in the range, else `false`. - * @see _.range, _.rangeRight - * @example - * - * _.inRange(3, 2, 4); - * // => true - * - * _.inRange(4, 8); - * // => true - * - * _.inRange(4, 2); - * // => false - * - * _.inRange(2, 2); - * // => false - * - * _.inRange(1.2, 2); - * // => true - * - * _.inRange(5.2, 4); - * // => false - * - * _.inRange(-3, -2, -6); - * // => true - */ - function inRange(number, start, end) { - start = toFinite(start); - if (end === undefined) { - end = start; - start = 0; - } else { - end = toFinite(end); - } - number = toNumber(number); - return baseInRange(number, start, end); - } - - /** - * Produces a random number between the inclusive `lower` and `upper` bounds. - * If only one argument is provided a number between `0` and the given number - * is returned. If `floating` is `true`, or either `lower` or `upper` are - * floats, a floating-point number is returned instead of an integer. - * - * **Note:** JavaScript follows the IEEE-754 standard for resolving - * floating-point values which can produce unexpected results. - * - * @static - * @memberOf _ - * @since 0.7.0 - * @category Number - * @param {number} [lower=0] The lower bound. - * @param {number} [upper=1] The upper bound. - * @param {boolean} [floating] Specify returning a floating-point number. - * @returns {number} Returns the random number. - * @example - * - * _.random(0, 5); - * // => an integer between 0 and 5 - * - * _.random(5); - * // => also an integer between 0 and 5 - * - * _.random(5, true); - * // => a floating-point number between 0 and 5 - * - * _.random(1.2, 5.2); - * // => a floating-point number between 1.2 and 5.2 - */ - function random(lower, upper, floating) { - if (floating && typeof floating != 'boolean' && isIterateeCall(lower, upper, floating)) { - upper = floating = undefined; - } - if (floating === undefined) { - if (typeof upper == 'boolean') { - floating = upper; - upper = undefined; - } - else if (typeof lower == 'boolean') { - floating = lower; - lower = undefined; - } - } - if (lower === undefined && upper === undefined) { - lower = 0; - upper = 1; - } - else { - lower = toFinite(lower); - if (upper === undefined) { - upper = lower; - lower = 0; - } else { - upper = toFinite(upper); - } - } - if (lower > upper) { - var temp = lower; - lower = upper; - upper = temp; - } - if (floating || lower % 1 || upper % 1) { - var rand = nativeRandom(); - return nativeMin(lower + (rand * (upper - lower + freeParseFloat('1e-' + ((rand + '').length - 1)))), upper); - } - return baseRandom(lower, upper); - } - - /*------------------------------------------------------------------------*/ - - /** - * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the camel cased string. - * @example - * - * _.camelCase('Foo Bar'); - * // => 'fooBar' - * - * _.camelCase('--foo-bar--'); - * // => 'fooBar' - * - * _.camelCase('__FOO_BAR__'); - * // => 'fooBar' - */ - var camelCase = createCompounder(function(result, word, index) { - word = word.toLowerCase(); - return result + (index ? capitalize(word) : word); - }); - - /** - * Converts the first character of `string` to upper case and the remaining - * to lower case. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to capitalize. - * @returns {string} Returns the capitalized string. - * @example - * - * _.capitalize('FRED'); - * // => 'Fred' - */ - function capitalize(string) { - return upperFirst(toString(string).toLowerCase()); - } - - /** - * Deburrs `string` by converting - * [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * to basic latin letters and removing - * [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to deburr. - * @returns {string} Returns the deburred string. - * @example - * - * _.deburr('dรฉjร vu'); - * // => 'deja vu' - */ - function deburr(string) { - string = toString(string); - return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); - } - - /** - * Checks if `string` ends with the given target string. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=string.length] The position to search up to. - * @returns {boolean} Returns `true` if `string` ends with `target`, - * else `false`. - * @example - * - * _.endsWith('abc', 'c'); - * // => true - * - * _.endsWith('abc', 'b'); - * // => false - * - * _.endsWith('abc', 'b', 2); - * // => true - */ - function endsWith(string, target, position) { - string = toString(string); - target = baseToString(target); - - var length = string.length; - position = position === undefined - ? length - : baseClamp(toInteger(position), 0, length); - - var end = position; - position -= target.length; - return position >= 0 && string.slice(position, end) == target; - } - - /** - * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to - * their corresponding HTML entities. - * - * **Note:** No other characters are escaped. To escape additional - * characters use a third-party library like [_he_](https://mths.be/he). - * - * Though the ">" character is escaped for symmetry, characters like - * ">" and "/" don't need escaping in HTML and have no special meaning - * unless they're part of a tag or unquoted attribute value. See - * [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) - * (under "semi-related fun fact") for more details. - * - * Backticks are escaped because in IE < 9, they can break out of - * attribute values or HTML comments. See [#59](https://html5sec.org/#59), - * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and - * [#133](https://html5sec.org/#133) of the - * [HTML5 Security Cheatsheet](https://html5sec.org/) for more details. - * - * When working with HTML you should always - * [quote attribute values](http://wonko.com/post/html-escaping) to reduce - * XSS vectors. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escape('fred, barney, & pebbles'); - * // => 'fred, barney, & pebbles' - */ - function escape(string) { - string = toString(string); - return (string && reHasUnescapedHtml.test(string)) - ? string.replace(reUnescapedHtml, escapeHtmlChar) - : string; - } - - /** - * Escapes the `RegExp` special characters "^", "$", "\", ".", "*", "+", - * "?", "(", ")", "[", "]", "{", "}", and "|" in `string`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to escape. - * @returns {string} Returns the escaped string. - * @example - * - * _.escapeRegExp('[lodash](https://lodash.com/)'); - * // => '\[lodash\]\(https://lodash\.com/\)' - */ - function escapeRegExp(string) { - string = toString(string); - return (string && reHasRegExpChar.test(string)) - ? string.replace(reRegExpChar, '\\$&') - : string; - } - - /** - * Converts `string` to - * [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the kebab cased string. - * @example - * - * _.kebabCase('Foo Bar'); - * // => 'foo-bar' - * - * _.kebabCase('fooBar'); - * // => 'foo-bar' - * - * _.kebabCase('__FOO_BAR__'); - * // => 'foo-bar' - */ - var kebabCase = createCompounder(function(result, word, index) { - return result + (index ? '-' : '') + word.toLowerCase(); - }); - - /** - * Converts `string`, as space separated words, to lower case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the lower cased string. - * @example - * - * _.lowerCase('--Foo-Bar--'); - * // => 'foo bar' - * - * _.lowerCase('fooBar'); - * // => 'foo bar' - * - * _.lowerCase('__FOO_BAR__'); - * // => 'foo bar' - */ - var lowerCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + word.toLowerCase(); - }); - - /** - * Converts the first character of `string` to lower case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.lowerFirst('Fred'); - * // => 'fred' - * - * _.lowerFirst('FRED'); - * // => 'fRED' - */ - var lowerFirst = createCaseFirst('toLowerCase'); - - /** - * Pads `string` on the left and right sides if it's shorter than `length`. - * Padding characters are truncated if they can't be evenly divided by `length`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.pad('abc', 8); - * // => ' abc ' - * - * _.pad('abc', 8, '_-'); - * // => '_-abc_-_' - * - * _.pad('abc', 3); - * // => 'abc' - */ - function pad(string, length, chars) { - string = toString(string); - length = toInteger(length); - - var strLength = length ? stringSize(string) : 0; - if (!length || strLength >= length) { - return string; - } - var mid = (length - strLength) / 2; - return ( - createPadding(nativeFloor(mid), chars) + - string + - createPadding(nativeCeil(mid), chars) - ); - } - - /** - * Pads `string` on the right side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padEnd('abc', 6); - * // => 'abc ' - * - * _.padEnd('abc', 6, '_-'); - * // => 'abc_-_' - * - * _.padEnd('abc', 3); - * // => 'abc' - */ - function padEnd(string, length, chars) { - string = toString(string); - length = toInteger(length); - - var strLength = length ? stringSize(string) : 0; - return (length && strLength < length) - ? (string + createPadding(length - strLength, chars)) - : string; - } - - /** - * Pads `string` on the left side if it's shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to pad. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the padded string. - * @example - * - * _.padStart('abc', 6); - * // => ' abc' - * - * _.padStart('abc', 6, '_-'); - * // => '_-_abc' - * - * _.padStart('abc', 3); - * // => 'abc' - */ - function padStart(string, length, chars) { - string = toString(string); - length = toInteger(length); - - var strLength = length ? stringSize(string) : 0; - return (length && strLength < length) - ? (createPadding(length - strLength, chars) + string) - : string; - } - - /** - * Converts `string` to an integer of the specified radix. If `radix` is - * `undefined` or `0`, a `radix` of `10` is used unless `value` is a - * hexadecimal, in which case a `radix` of `16` is used. - * - * **Note:** This method aligns with the - * [ES5 implementation](https://es5.github.io/#x15.1.2.2) of `parseInt`. - * - * @static - * @memberOf _ - * @since 1.1.0 - * @category String - * @param {string} string The string to convert. - * @param {number} [radix=10] The radix to interpret `value` by. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {number} Returns the converted integer. - * @example - * - * _.parseInt('08'); - * // => 8 - * - * _.map(['6', '08', '10'], _.parseInt); - * // => [6, 8, 10] - */ - function parseInt(string, radix, guard) { - // Chrome fails to trim leading <BOM> whitespace characters. - // See https://bugs.chromium.org/p/v8/issues/detail?id=3109 for more details. - if (guard || radix == null) { - radix = 0; - } else if (radix) { - radix = +radix; - } - string = toString(string).replace(reTrim, ''); - return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); - } - - /** - * Repeats the given string `n` times. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to repeat. - * @param {number} [n=1] The number of times to repeat the string. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the repeated string. - * @example - * - * _.repeat('*', 3); - * // => '***' - * - * _.repeat('abc', 2); - * // => 'abcabc' - * - * _.repeat('abc', 0); - * // => '' - */ - function repeat(string, n, guard) { - if ((guard ? isIterateeCall(string, n, guard) : n === undefined)) { - n = 1; - } else { - n = toInteger(n); - } - return baseRepeat(toString(string), n); - } - - /** - * Replaces matches for `pattern` in `string` with `replacement`. - * - * **Note:** This method is based on - * [`String#replace`](https://mdn.io/String/replace). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to modify. - * @param {RegExp|string} pattern The pattern to replace. - * @param {Function|string} replacement The match replacement. - * @returns {string} Returns the modified string. - * @example - * - * _.replace('Hi Fred', 'Fred', 'Barney'); - * // => 'Hi Barney' - */ - function replace() { - var args = arguments, - string = toString(args[0]); - - return args.length < 3 ? string : nativeReplace.call(string, args[1], args[2]); - } - - /** - * Converts `string` to - * [snake case](https://en.wikipedia.org/wiki/Snake_case). - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the snake cased string. - * @example - * - * _.snakeCase('Foo Bar'); - * // => 'foo_bar' - * - * _.snakeCase('fooBar'); - * // => 'foo_bar' - * - * _.snakeCase('--FOO-BAR--'); - * // => 'foo_bar' - */ - var snakeCase = createCompounder(function(result, word, index) { - return result + (index ? '_' : '') + word.toLowerCase(); - }); - - /** - * Splits `string` by `separator`. - * - * **Note:** This method is based on - * [`String#split`](https://mdn.io/String/split). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to split. - * @param {RegExp|string} separator The separator pattern to split by. - * @param {number} [limit] The length to truncate results to. - * @returns {Array} Returns the string segments. - * @example - * - * _.split('a-b-c', '-', 2); - * // => ['a', 'b'] - */ - function split(string, separator, limit) { - if (limit && typeof limit != 'number' && isIterateeCall(string, separator, limit)) { - separator = limit = undefined; - } - limit = limit === undefined ? MAX_ARRAY_LENGTH : limit >>> 0; - if (!limit) { - return []; - } - string = toString(string); - if (string && ( - typeof separator == 'string' || - (separator != null && !isRegExp(separator)) - )) { - separator = baseToString(separator); - if (separator == '' && reHasComplexSymbol.test(string)) { - return castSlice(stringToArray(string), 0, limit); - } - } - return nativeSplit.call(string, separator, limit); - } - - /** - * Converts `string` to - * [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). - * - * @static - * @memberOf _ - * @since 3.1.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the start cased string. - * @example - * - * _.startCase('--foo-bar--'); - * // => 'Foo Bar' - * - * _.startCase('fooBar'); - * // => 'Foo Bar' - * - * _.startCase('__FOO_BAR__'); - * // => 'FOO BAR' - */ - var startCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + upperFirst(word); - }); - - /** - * Checks if `string` starts with the given target string. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=0] The position to search from. - * @returns {boolean} Returns `true` if `string` starts with `target`, - * else `false`. - * @example - * - * _.startsWith('abc', 'a'); - * // => true - * - * _.startsWith('abc', 'b'); - * // => false - * - * _.startsWith('abc', 'b', 1); - * // => true - */ - function startsWith(string, target, position) { - string = toString(string); - position = baseClamp(toInteger(position), 0, string.length); - target = baseToString(target); - return string.slice(position, position + target.length) == target; - } - - /** - * Creates a compiled template function that can interpolate data properties - * in "interpolate" delimiters, HTML-escape interpolated data properties in - * "escape" delimiters, and execute JavaScript in "evaluate" delimiters. Data - * properties may be accessed as free variables in the template. If a setting - * object is given, it takes precedence over `_.templateSettings` values. - * - * **Note:** In the development build `_.template` utilizes - * [sourceURLs](http://www.html5rocks.com/en/tutorials/developertools/sourcemaps/#toc-sourceurl) - * for easier debugging. - * - * For more information on precompiling templates see - * [lodash's custom builds documentation](https://lodash.com/custom-builds). - * - * For more information on Chrome extension sandboxes see - * [Chrome's extensions documentation](https://developer.chrome.com/extensions/sandboxingEval). - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category String - * @param {string} [string=''] The template string. - * @param {Object} [options={}] The options object. - * @param {RegExp} [options.escape=_.templateSettings.escape] - * The HTML "escape" delimiter. - * @param {RegExp} [options.evaluate=_.templateSettings.evaluate] - * The "evaluate" delimiter. - * @param {Object} [options.imports=_.templateSettings.imports] - * An object to import into the template as free variables. - * @param {RegExp} [options.interpolate=_.templateSettings.interpolate] - * The "interpolate" delimiter. - * @param {string} [options.sourceURL='lodash.templateSources[n]'] - * The sourceURL of the compiled template. - * @param {string} [options.variable='obj'] - * The data object variable name. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Function} Returns the compiled template function. - * @example - * - * // Use the "interpolate" delimiter to create a compiled template. - * var compiled = _.template('hello <%= user %>!'); - * compiled({ 'user': 'fred' }); - * // => 'hello fred!' - * - * // Use the HTML "escape" delimiter to escape data property values. - * var compiled = _.template('<b><%- value %></b>'); - * compiled({ 'value': '<script>' }); - * // => '<b><script></b>' - * - * // Use the "evaluate" delimiter to execute JavaScript and generate HTML. - * var compiled = _.template('<% _.forEach(users, function(user) { %><li><%- user %></li><% }); %>'); - * compiled({ 'users': ['fred', 'barney'] }); - * // => '<li>fred</li><li>barney</li>' - * - * // Use the internal `print` function in "evaluate" delimiters. - * var compiled = _.template('<% print("hello " + user); %>!'); - * compiled({ 'user': 'barney' }); - * // => 'hello barney!' - * - * // Use the ES delimiter as an alternative to the default "interpolate" delimiter. - * var compiled = _.template('hello ${ user }!'); - * compiled({ 'user': 'pebbles' }); - * // => 'hello pebbles!' - * - * // Use backslashes to treat delimiters as plain text. - * var compiled = _.template('<%= "\\<%- value %\\>" %>'); - * compiled({ 'value': 'ignored' }); - * // => '<%- value %>' - * - * // Use the `imports` option to import `jQuery` as `jq`. - * var text = '<% jq.each(users, function(user) { %><li><%- user %></li><% }); %>'; - * var compiled = _.template(text, { 'imports': { 'jq': jQuery } }); - * compiled({ 'users': ['fred', 'barney'] }); - * // => '<li>fred</li><li>barney</li>' - * - * // Use the `sourceURL` option to specify a custom sourceURL for the template. - * var compiled = _.template('hello <%= user %>!', { 'sourceURL': '/basic/greeting.jst' }); - * compiled(data); - * // => Find the source of "greeting.jst" under the Sources tab or Resources panel of the web inspector. - * - * // Use the `variable` option to ensure a with-statement isn't used in the compiled template. - * var compiled = _.template('hi <%= data.user %>!', { 'variable': 'data' }); - * compiled.source; - * // => function(data) { - * // var __t, __p = ''; - * // __p += 'hi ' + ((__t = ( data.user )) == null ? '' : __t) + '!'; - * // return __p; - * // } - * - * // Use custom template delimiters. - * _.templateSettings.interpolate = /{{([\s\S]+?)}}/g; - * var compiled = _.template('hello {{ user }}!'); - * compiled({ 'user': 'mustache' }); - * // => 'hello mustache!' - * - * // Use the `source` property to inline compiled templates for meaningful - * // line numbers in error messages and stack traces. - * fs.writeFileSync(path.join(process.cwd(), 'jst.js'), '\ - * var JST = {\ - * "main": ' + _.template(mainText).source + '\ - * };\ - * '); - */ - function template(string, options, guard) { - // Based on John Resig's `tmpl` implementation - // (http://ejohn.org/blog/javascript-micro-templating/) - // and Laura Doktorova's doT.js (https://github.com/olado/doT). - var settings = lodash.templateSettings; - - if (guard && isIterateeCall(string, options, guard)) { - options = undefined; - } - string = toString(string); - options = assignInWith({}, options, settings, assignInDefaults); - - var imports = assignInWith({}, options.imports, settings.imports, assignInDefaults), - importsKeys = keys(imports), - importsValues = baseValues(imports, importsKeys); - - var isEscaping, - isEvaluating, - index = 0, - interpolate = options.interpolate || reNoMatch, - source = "__p += '"; - - // Compile the regexp to match each delimiter. - var reDelimiters = RegExp( - (options.escape || reNoMatch).source + '|' + - interpolate.source + '|' + - (interpolate === reInterpolate ? reEsTemplate : reNoMatch).source + '|' + - (options.evaluate || reNoMatch).source + '|$' - , 'g'); - - // Use a sourceURL for easier debugging. - var sourceURL = '//# sourceURL=' + - ('sourceURL' in options - ? options.sourceURL - : ('lodash.templateSources[' + (++templateCounter) + ']') - ) + '\n'; - - string.replace(reDelimiters, function(match, escapeValue, interpolateValue, esTemplateValue, evaluateValue, offset) { - interpolateValue || (interpolateValue = esTemplateValue); - - // Escape characters that can't be included in string literals. - source += string.slice(index, offset).replace(reUnescapedString, escapeStringChar); - - // Replace delimiters with snippets. - if (escapeValue) { - isEscaping = true; - source += "' +\n__e(" + escapeValue + ") +\n'"; - } - if (evaluateValue) { - isEvaluating = true; - source += "';\n" + evaluateValue + ";\n__p += '"; - } - if (interpolateValue) { - source += "' +\n((__t = (" + interpolateValue + ")) == null ? '' : __t) +\n'"; - } - index = offset + match.length; - - // The JS engine embedded in Adobe products needs `match` returned in - // order to produce the correct `offset` value. - return match; - }); - - source += "';\n"; - - // If `variable` is not specified wrap a with-statement around the generated - // code to add the data object to the top of the scope chain. - var variable = options.variable; - if (!variable) { - source = 'with (obj) {\n' + source + '\n}\n'; - } - // Cleanup code by stripping empty strings. - source = (isEvaluating ? source.replace(reEmptyStringLeading, '') : source) - .replace(reEmptyStringMiddle, '$1') - .replace(reEmptyStringTrailing, '$1;'); - - // Frame code as the function body. - source = 'function(' + (variable || 'obj') + ') {\n' + - (variable - ? '' - : 'obj || (obj = {});\n' - ) + - "var __t, __p = ''" + - (isEscaping - ? ', __e = _.escape' - : '' - ) + - (isEvaluating - ? ', __j = Array.prototype.join;\n' + - "function print() { __p += __j.call(arguments, '') }\n" - : ';\n' - ) + - source + - 'return __p\n}'; - - var result = attempt(function() { - return Function(importsKeys, sourceURL + 'return ' + source) - .apply(undefined, importsValues); - }); - - // Provide the compiled function's source by its `toString` method or - // the `source` property as a convenience for inlining compiled templates. - result.source = source; - if (isError(result)) { - throw result; - } - return result; - } - - /** - * Converts `string`, as a whole, to lower case just like - * [String#toLowerCase](https://mdn.io/toLowerCase). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the lower cased string. - * @example - * - * _.toLower('--Foo-Bar--'); - * // => '--foo-bar--' - * - * _.toLower('fooBar'); - * // => 'foobar' - * - * _.toLower('__FOO_BAR__'); - * // => '__foo_bar__' - */ - function toLower(value) { - return toString(value).toLowerCase(); - } - - /** - * Converts `string`, as a whole, to upper case just like - * [String#toUpperCase](https://mdn.io/toUpperCase). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the upper cased string. - * @example - * - * _.toUpper('--foo-bar--'); - * // => '--FOO-BAR--' - * - * _.toUpper('fooBar'); - * // => 'FOOBAR' - * - * _.toUpper('__foo_bar__'); - * // => '__FOO_BAR__' - */ - function toUpper(value) { - return toString(value).toUpperCase(); - } - - /** - * Removes leading and trailing whitespace or specified characters from `string`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to trim. - * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the trimmed string. - * @example - * - * _.trim(' abc '); - * // => 'abc' - * - * _.trim('-_-abc-_-', '_-'); - * // => 'abc' - * - * _.map([' foo ', ' bar '], _.trim); - * // => ['foo', 'bar'] - */ - function trim(string, chars, guard) { - string = toString(string); - if (string && (guard || chars === undefined)) { - return string.replace(reTrim, ''); - } - if (!string || !(chars = baseToString(chars))) { - return string; - } - var strSymbols = stringToArray(string), - chrSymbols = stringToArray(chars), - start = charsStartIndex(strSymbols, chrSymbols), - end = charsEndIndex(strSymbols, chrSymbols) + 1; - - return castSlice(strSymbols, start, end).join(''); - } - - /** - * Removes trailing whitespace or specified characters from `string`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to trim. - * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the trimmed string. - * @example - * - * _.trimEnd(' abc '); - * // => ' abc' - * - * _.trimEnd('-_-abc-_-', '_-'); - * // => '-_-abc' - */ - function trimEnd(string, chars, guard) { - string = toString(string); - if (string && (guard || chars === undefined)) { - return string.replace(reTrimEnd, ''); - } - if (!string || !(chars = baseToString(chars))) { - return string; - } - var strSymbols = stringToArray(string), - end = charsEndIndex(strSymbols, stringToArray(chars)) + 1; - - return castSlice(strSymbols, 0, end).join(''); - } - - /** - * Removes leading whitespace or specified characters from `string`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to trim. - * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the trimmed string. - * @example - * - * _.trimStart(' abc '); - * // => 'abc ' - * - * _.trimStart('-_-abc-_-', '_-'); - * // => 'abc-_-' - */ - function trimStart(string, chars, guard) { - string = toString(string); - if (string && (guard || chars === undefined)) { - return string.replace(reTrimStart, ''); - } - if (!string || !(chars = baseToString(chars))) { - return string; - } - var strSymbols = stringToArray(string), - start = charsStartIndex(strSymbols, stringToArray(chars)); - - return castSlice(strSymbols, start).join(''); - } - - /** - * Truncates `string` if it's longer than the given maximum string length. - * The last characters of the truncated string are replaced with the omission - * string which defaults to "...". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to truncate. - * @param {Object} [options={}] The options object. - * @param {number} [options.length=30] The maximum string length. - * @param {string} [options.omission='...'] The string to indicate text is omitted. - * @param {RegExp|string} [options.separator] The separator pattern to truncate to. - * @returns {string} Returns the truncated string. - * @example - * - * _.truncate('hi-diddly-ho there, neighborino'); - * // => 'hi-diddly-ho there, neighbo...' - * - * _.truncate('hi-diddly-ho there, neighborino', { - * 'length': 24, - * 'separator': ' ' - * }); - * // => 'hi-diddly-ho there,...' - * - * _.truncate('hi-diddly-ho there, neighborino', { - * 'length': 24, - * 'separator': /,? +/ - * }); - * // => 'hi-diddly-ho there...' - * - * _.truncate('hi-diddly-ho there, neighborino', { - * 'omission': ' [...]' - * }); - * // => 'hi-diddly-ho there, neig [...]' - */ - function truncate(string, options) { - var length = DEFAULT_TRUNC_LENGTH, - omission = DEFAULT_TRUNC_OMISSION; - - if (isObject(options)) { - var separator = 'separator' in options ? options.separator : separator; - length = 'length' in options ? toInteger(options.length) : length; - omission = 'omission' in options ? baseToString(options.omission) : omission; - } - string = toString(string); - - var strLength = string.length; - if (reHasComplexSymbol.test(string)) { - var strSymbols = stringToArray(string); - strLength = strSymbols.length; - } - if (length >= strLength) { - return string; - } - var end = length - stringSize(omission); - if (end < 1) { - return omission; - } - var result = strSymbols - ? castSlice(strSymbols, 0, end).join('') - : string.slice(0, end); - - if (separator === undefined) { - return result + omission; - } - if (strSymbols) { - end += (result.length - end); - } - if (isRegExp(separator)) { - if (string.slice(end).search(separator)) { - var match, - substring = result; - - if (!separator.global) { - separator = RegExp(separator.source, toString(reFlags.exec(separator)) + 'g'); - } - separator.lastIndex = 0; - while ((match = separator.exec(substring))) { - var newEnd = match.index; - } - result = result.slice(0, newEnd === undefined ? end : newEnd); - } - } else if (string.indexOf(baseToString(separator), end) != end) { - var index = result.lastIndexOf(separator); - if (index > -1) { - result = result.slice(0, index); - } - } - return result + omission; - } - - /** - * The inverse of `_.escape`; this method converts the HTML entities - * `&`, `<`, `>`, `"`, `'`, and ``` in `string` to - * their corresponding characters. - * - * **Note:** No other HTML entities are unescaped. To unescape additional - * HTML entities use a third-party library like [_he_](https://mths.be/he). - * - * @static - * @memberOf _ - * @since 0.6.0 - * @category String - * @param {string} [string=''] The string to unescape. - * @returns {string} Returns the unescaped string. - * @example - * - * _.unescape('fred, barney, & pebbles'); - * // => 'fred, barney, & pebbles' - */ - function unescape(string) { - string = toString(string); - return (string && reHasEscapedHtml.test(string)) - ? string.replace(reEscapedHtml, unescapeHtmlChar) - : string; - } - - /** - * Converts `string`, as space separated words, to upper case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the upper cased string. - * @example - * - * _.upperCase('--foo-bar'); - * // => 'FOO BAR' - * - * _.upperCase('fooBar'); - * // => 'FOO BAR' - * - * _.upperCase('__foo_bar__'); - * // => 'FOO BAR' - */ - var upperCase = createCompounder(function(result, word, index) { - return result + (index ? ' ' : '') + word.toUpperCase(); - }); - - /** - * Converts the first character of `string` to upper case. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category String - * @param {string} [string=''] The string to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.upperFirst('fred'); - * // => 'Fred' - * - * _.upperFirst('FRED'); - * // => 'FRED' - */ - var upperFirst = createCaseFirst('toUpperCase'); - - /** - * Splits `string` into an array of its words. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to inspect. - * @param {RegExp|string} [pattern] The pattern to match words. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {Array} Returns the words of `string`. - * @example - * - * _.words('fred, barney, & pebbles'); - * // => ['fred', 'barney', 'pebbles'] - * - * _.words('fred, barney, & pebbles', /[^, ]+/g); - * // => ['fred', 'barney', '&', 'pebbles'] - */ - function words(string, pattern, guard) { - string = toString(string); - pattern = guard ? undefined : pattern; - - if (pattern === undefined) { - pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord; - } - return string.match(pattern) || []; - } - - /*------------------------------------------------------------------------*/ - - /** - * Attempts to invoke `func`, returning either the result or the caught error - * object. Any additional arguments are provided to `func` when it's invoked. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Util - * @param {Function} func The function to attempt. - * @param {...*} [args] The arguments to invoke `func` with. - * @returns {*} Returns the `func` result or error object. - * @example - * - * // Avoid throwing errors for invalid selectors. - * var elements = _.attempt(function(selector) { - * return document.querySelectorAll(selector); - * }, '>_>'); - * - * if (_.isError(elements)) { - * elements = []; - * } - */ - var attempt = baseRest(function(func, args) { - try { - return apply(func, undefined, args); - } catch (e) { - return isError(e) ? e : new Error(e); - } - }); - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. - * - * **Note:** This method doesn't set the "length" property of bound functions. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...(string|string[])} methodNames The object method names to bind. - * @returns {Object} Returns `object`. - * @example - * - * var view = { - * 'label': 'docs', - * 'click': function() { - * console.log('clicked ' + this.label); - * } - * }; - * - * _.bindAll(view, ['click']); - * jQuery(element).on('click', view.click); - * // => Logs 'clicked docs' when clicked. - */ - var bindAll = baseRest(function(object, methodNames) { - arrayEach(baseFlatten(methodNames, 1), function(key) { - key = toKey(key); - object[key] = bind(object[key], object); - }); - return object; - }); - - /** - * Creates a function that iterates over `pairs` and invokes the corresponding - * function of the first predicate to return truthy. The predicate-function - * pairs are invoked with the `this` binding and arguments of the created - * function. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Util - * @param {Array} pairs The predicate-function pairs. - * @returns {Function} Returns the new composite function. - * @example - * - * var func = _.cond([ - * [_.matches({ 'a': 1 }), _.constant('matches A')], - * [_.conforms({ 'b': _.isNumber }), _.constant('matches B')], - * [_.stubTrue, _.constant('no match')] - * ]); - * - * func({ 'a': 1, 'b': 2 }); - * // => 'matches A' - * - * func({ 'a': 0, 'b': 1 }); - * // => 'matches B' - * - * func({ 'a': '1', 'b': '2' }); - * // => 'no match' - */ - function cond(pairs) { - var length = pairs ? pairs.length : 0, - toIteratee = getIteratee(); - - pairs = !length ? [] : arrayMap(pairs, function(pair) { - if (typeof pair[1] != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return [toIteratee(pair[0]), pair[1]]; - }); - - return baseRest(function(args) { - var index = -1; - while (++index < length) { - var pair = pairs[index]; - if (apply(pair[0], this, args)) { - return apply(pair[1], this, args); - } - } - }); - } - - /** - * Creates a function that invokes the predicate properties of `source` with - * the corresponding property values of a given object, returning `true` if - * all predicates return truthy, else `false`. - * - * **Note:** The created function is equivalent to `_.conformsTo` with - * `source` partially applied. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Util - * @param {Object} source The object of property predicates to conform to. - * @returns {Function} Returns the new spec function. - * @example - * - * var objects = [ - * { 'a': 2, 'b': 1 }, - * { 'a': 1, 'b': 2 } - * ]; - * - * _.filter(objects, _.conforms({ 'b': function(n) { return n > 1; } })); - * // => [{ 'a': 1, 'b': 2 }] - */ - function conforms(source) { - return baseConforms(baseClone(source, true)); - } - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new constant function. - * @example - * - * var objects = _.times(2, _.constant({ 'a': 1 })); - * - * console.log(objects); - * // => [{ 'a': 1 }, { 'a': 1 }] - * - * console.log(objects[0] === objects[1]); - * // => true - */ - function constant(value) { - return function() { - return value; - }; - } - - /** - * Checks `value` to determine whether a default value should be returned in - * its place. The `defaultValue` is returned if `value` is `NaN`, `null`, - * or `undefined`. - * - * @static - * @memberOf _ - * @since 4.14.0 - * @category Util - * @param {*} value The value to check. - * @param {*} defaultValue The default value. - * @returns {*} Returns the resolved value. - * @example - * - * _.defaultTo(1, 10); - * // => 1 - * - * _.defaultTo(undefined, 10); - * // => 10 - */ - function defaultTo(value, defaultValue) { - return (value == null || value !== value) ? defaultValue : value; - } - - /** - * Creates a function that returns the result of invoking the given functions - * with the `this` binding of the created function, where each successive - * invocation is supplied the return value of the previous. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Util - * @param {...(Function|Function[])} [funcs] The functions to invoke. - * @returns {Function} Returns the new composite function. - * @see _.flowRight - * @example - * - * function square(n) { - * return n * n; - * } - * - * var addSquare = _.flow([_.add, square]); - * addSquare(1, 2); - * // => 9 - */ - var flow = createFlow(); - - /** - * This method is like `_.flow` except that it creates a function that - * invokes the given functions from right to left. - * - * @static - * @since 3.0.0 - * @memberOf _ - * @category Util - * @param {...(Function|Function[])} [funcs] The functions to invoke. - * @returns {Function} Returns the new composite function. - * @see _.flow - * @example - * - * function square(n) { - * return n * n; - * } - * - * var addSquare = _.flowRight([square, _.add]); - * addSquare(1, 2); - * // => 9 - */ - var flowRight = createFlow(true); - - /** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true - */ - function identity(value) { - return value; - } - - /** - * Creates a function that invokes `func` with the arguments of the created - * function. If `func` is a property name, the created function returns the - * property value for a given element. If `func` is an array or object, the - * created function returns `true` for elements that contain the equivalent - * source properties, otherwise it returns `false`. - * - * @static - * @since 4.0.0 - * @memberOf _ - * @category Util - * @param {*} [func=_.identity] The value to convert to a callback. - * @returns {Function} Returns the callback. - * @example - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * // The `_.matches` iteratee shorthand. - * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true })); - * // => [{ 'user': 'barney', 'age': 36, 'active': true }] - * - * // The `_.matchesProperty` iteratee shorthand. - * _.filter(users, _.iteratee(['user', 'fred'])); - * // => [{ 'user': 'fred', 'age': 40 }] - * - * // The `_.property` iteratee shorthand. - * _.map(users, _.iteratee('user')); - * // => ['barney', 'fred'] - * - * // Create custom iteratee shorthands. - * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) { - * return !_.isRegExp(func) ? iteratee(func) : function(string) { - * return func.test(string); - * }; - * }); - * - * _.filter(['abc', 'def'], /ef/); - * // => ['def'] - */ - function iteratee(func) { - return baseIteratee(typeof func == 'function' ? func : baseClone(func, true)); - } - - /** - * Creates a function that performs a partial deep comparison between a given - * object and `source`, returning `true` if the given object has equivalent - * property values, else `false`. - * - * **Note:** The created function supports comparing the same values as - * `_.isEqual` is equivalent to `_.isMatch` with `source` partially applied. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Util - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new spec function. - * @example - * - * var objects = [ - * { 'a': 1, 'b': 2, 'c': 3 }, - * { 'a': 4, 'b': 5, 'c': 6 } - * ]; - * - * _.filter(objects, _.matches({ 'a': 4, 'c': 6 })); - * // => [{ 'a': 4, 'b': 5, 'c': 6 }] - */ - function matches(source) { - return baseMatches(baseClone(source, true)); - } - - /** - * Creates a function that performs a partial deep comparison between the - * value at `path` of a given object to `srcValue`, returning `true` if the - * object value is equivalent, else `false`. - * - * **Note:** This method supports comparing the same values as `_.isEqual`. - * - * @static - * @memberOf _ - * @since 3.2.0 - * @category Util - * @param {Array|string} path The path of the property to get. - * @param {*} srcValue The value to match. - * @returns {Function} Returns the new spec function. - * @example - * - * var objects = [ - * { 'a': 1, 'b': 2, 'c': 3 }, - * { 'a': 4, 'b': 5, 'c': 6 } - * ]; - * - * _.find(objects, _.matchesProperty('a', 4)); - * // => { 'a': 4, 'b': 5, 'c': 6 } - */ - function matchesProperty(path, srcValue) { - return baseMatchesProperty(path, baseClone(srcValue, true)); - } - - /** - * Creates a function that invokes the method at `path` of a given object. - * Any additional arguments are provided to the invoked method. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Util - * @param {Array|string} path The path of the method to invoke. - * @param {...*} [args] The arguments to invoke the method with. - * @returns {Function} Returns the new invoker function. - * @example - * - * var objects = [ - * { 'a': { 'b': _.constant(2) } }, - * { 'a': { 'b': _.constant(1) } } - * ]; - * - * _.map(objects, _.method('a.b')); - * // => [2, 1] - * - * _.map(objects, _.method(['a', 'b'])); - * // => [2, 1] - */ - var method = baseRest(function(path, args) { - return function(object) { - return baseInvoke(object, path, args); - }; - }); - - /** - * The opposite of `_.method`; this method creates a function that invokes - * the method at a given path of `object`. Any additional arguments are - * provided to the invoked method. - * - * @static - * @memberOf _ - * @since 3.7.0 - * @category Util - * @param {Object} object The object to query. - * @param {...*} [args] The arguments to invoke the method with. - * @returns {Function} Returns the new invoker function. - * @example - * - * var array = _.times(3, _.constant), - * object = { 'a': array, 'b': array, 'c': array }; - * - * _.map(['a[2]', 'c[0]'], _.methodOf(object)); - * // => [2, 0] - * - * _.map([['a', '2'], ['c', '0']], _.methodOf(object)); - * // => [2, 0] - */ - var methodOf = baseRest(function(object, args) { - return function(path) { - return baseInvoke(object, path, args); - }; - }); - - /** - * Adds all own enumerable string keyed function properties of a source - * object to the destination object. If `object` is a function, then methods - * are added to its prototype as well. - * - * **Note:** Use `_.runInContext` to create a pristine `lodash` function to - * avoid conflicts caused by modifying the original. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {Function|Object} [object=lodash] The destination object. - * @param {Object} source The object of functions to add. - * @param {Object} [options={}] The options object. - * @param {boolean} [options.chain=true] Specify whether mixins are chainable. - * @returns {Function|Object} Returns `object`. - * @example - * - * function vowels(string) { - * return _.filter(string, function(v) { - * return /[aeiou]/i.test(v); - * }); - * } - * - * _.mixin({ 'vowels': vowels }); - * _.vowels('fred'); - * // => ['e'] - * - * _('fred').vowels().value(); - * // => ['e'] - * - * _.mixin({ 'vowels': vowels }, { 'chain': false }); - * _('fred').vowels(); - * // => ['e'] - */ - function mixin(object, source, options) { - var props = keys(source), - methodNames = baseFunctions(source, props); - - if (options == null && - !(isObject(source) && (methodNames.length || !props.length))) { - options = source; - source = object; - object = this; - methodNames = baseFunctions(source, keys(source)); - } - var chain = !(isObject(options) && 'chain' in options) || !!options.chain, - isFunc = isFunction(object); - - arrayEach(methodNames, function(methodName) { - var func = source[methodName]; - object[methodName] = func; - if (isFunc) { - object.prototype[methodName] = function() { - var chainAll = this.__chain__; - if (chain || chainAll) { - var result = object(this.__wrapped__), - actions = result.__actions__ = copyArray(this.__actions__); - - actions.push({ 'func': func, 'args': arguments, 'thisArg': object }); - result.__chain__ = chainAll; - return result; - } - return func.apply(object, arrayPush([this.value()], arguments)); - }; - } - }); - - return object; - } - - /** - * Reverts the `_` variable to its previous value and returns a reference to - * the `lodash` function. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @returns {Function} Returns the `lodash` function. - * @example - * - * var lodash = _.noConflict(); - */ - function noConflict() { - if (root._ === this) { - root._ = oldDash; - } - return this; - } - - /** - * This method returns `undefined`. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Util - * @example - * - * _.times(2, _.noop); - * // => [undefined, undefined] - */ - function noop() { - // No operation performed. - } - - /** - * Creates a function that gets the argument at index `n`. If `n` is negative, - * the nth argument from the end is returned. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Util - * @param {number} [n=0] The index of the argument to return. - * @returns {Function} Returns the new pass-thru function. - * @example - * - * var func = _.nthArg(1); - * func('a', 'b', 'c', 'd'); - * // => 'b' - * - * var func = _.nthArg(-2); - * func('a', 'b', 'c', 'd'); - * // => 'c' - */ - function nthArg(n) { - n = toInteger(n); - return baseRest(function(args) { - return baseNth(args, n); - }); - } - - /** - * Creates a function that invokes `iteratees` with the arguments it receives - * and returns their results. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Util - * @param {...(Function|Function[])} [iteratees=[_.identity]] - * The iteratees to invoke. - * @returns {Function} Returns the new function. - * @example - * - * var func = _.over([Math.max, Math.min]); - * - * func(1, 2, 3, 4); - * // => [4, 1] - */ - var over = createOver(arrayMap); - - /** - * Creates a function that checks if **all** of the `predicates` return - * truthy when invoked with the arguments it receives. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Util - * @param {...(Function|Function[])} [predicates=[_.identity]] - * The predicates to check. - * @returns {Function} Returns the new function. - * @example - * - * var func = _.overEvery([Boolean, isFinite]); - * - * func('1'); - * // => true - * - * func(null); - * // => false - * - * func(NaN); - * // => false - */ - var overEvery = createOver(arrayEvery); - - /** - * Creates a function that checks if **any** of the `predicates` return - * truthy when invoked with the arguments it receives. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Util - * @param {...(Function|Function[])} [predicates=[_.identity]] - * The predicates to check. - * @returns {Function} Returns the new function. - * @example - * - * var func = _.overSome([Boolean, isFinite]); - * - * func('1'); - * // => true - * - * func(null); - * // => true - * - * func(NaN); - * // => false - */ - var overSome = createOver(arraySome); - - /** - * Creates a function that returns the value at `path` of a given object. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new accessor function. - * @example - * - * var objects = [ - * { 'a': { 'b': 2 } }, - * { 'a': { 'b': 1 } } - * ]; - * - * _.map(objects, _.property('a.b')); - * // => [2, 1] - * - * _.map(_.sortBy(objects, _.property(['a', 'b'])), 'a.b'); - * // => [1, 2] - */ - function property(path) { - return isKey(path) ? baseProperty(toKey(path)) : basePropertyDeep(path); - } - - /** - * The opposite of `_.property`; this method creates a function that returns - * the value at a given path of `object`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Util - * @param {Object} object The object to query. - * @returns {Function} Returns the new accessor function. - * @example - * - * var array = [0, 1, 2], - * object = { 'a': array, 'b': array, 'c': array }; - * - * _.map(['a[2]', 'c[0]'], _.propertyOf(object)); - * // => [2, 0] - * - * _.map([['a', '2'], ['c', '0']], _.propertyOf(object)); - * // => [2, 0] - */ - function propertyOf(object) { - return function(path) { - return object == null ? undefined : baseGet(object, path); - }; - } - - /** - * Creates an array of numbers (positive and/or negative) progressing from - * `start` up to, but not including, `end`. A step of `-1` is used if a negative - * `start` is specified without an `end` or `step`. If `end` is not specified, - * it's set to `start` with `start` then set to `0`. - * - * **Note:** JavaScript follows the IEEE-754 standard for resolving - * floating-point values which can produce unexpected results. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns the range of numbers. - * @see _.inRange, _.rangeRight - * @example - * - * _.range(4); - * // => [0, 1, 2, 3] - * - * _.range(-4); - * // => [0, -1, -2, -3] - * - * _.range(1, 5); - * // => [1, 2, 3, 4] - * - * _.range(0, 20, 5); - * // => [0, 5, 10, 15] - * - * _.range(0, -4, -1); - * // => [0, -1, -2, -3] - * - * _.range(1, 4, 0); - * // => [1, 1, 1] - * - * _.range(0); - * // => [] - */ - var range = createRange(); - - /** - * This method is like `_.range` except that it populates values in - * descending order. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Util - * @param {number} [start=0] The start of the range. - * @param {number} end The end of the range. - * @param {number} [step=1] The value to increment or decrement by. - * @returns {Array} Returns the range of numbers. - * @see _.inRange, _.range - * @example - * - * _.rangeRight(4); - * // => [3, 2, 1, 0] - * - * _.rangeRight(-4); - * // => [-3, -2, -1, 0] - * - * _.rangeRight(1, 5); - * // => [4, 3, 2, 1] - * - * _.rangeRight(0, 20, 5); - * // => [15, 10, 5, 0] - * - * _.rangeRight(0, -4, -1); - * // => [-3, -2, -1, 0] - * - * _.rangeRight(1, 4, 0); - * // => [1, 1, 1] - * - * _.rangeRight(0); - * // => [] - */ - var rangeRight = createRange(true); - - /** - * This method returns a new empty array. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Array} Returns the new empty array. - * @example - * - * var arrays = _.times(2, _.stubArray); - * - * console.log(arrays); - * // => [[], []] - * - * console.log(arrays[0] === arrays[1]); - * // => false - */ - function stubArray() { - return []; - } - - /** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ - function stubFalse() { - return false; - } - - /** - * This method returns a new empty object. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {Object} Returns the new empty object. - * @example - * - * var objects = _.times(2, _.stubObject); - * - * console.log(objects); - * // => [{}, {}] - * - * console.log(objects[0] === objects[1]); - * // => false - */ - function stubObject() { - return {}; - } - - /** - * This method returns an empty string. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {string} Returns the empty string. - * @example - * - * _.times(2, _.stubString); - * // => ['', ''] - */ - function stubString() { - return ''; - } - - /** - * This method returns `true`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `true`. - * @example - * - * _.times(2, _.stubTrue); - * // => [true, true] - */ - function stubTrue() { - return true; - } - - /** - * Invokes the iteratee `n` times, returning an array of the results of - * each invocation. The iteratee is invoked with one argument; (index). - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @returns {Array} Returns the array of results. - * @example - * - * _.times(3, String); - * // => ['0', '1', '2'] - * - * _.times(4, _.constant(0)); - * // => [0, 0, 0, 0] - */ - function times(n, iteratee) { - n = toInteger(n); - if (n < 1 || n > MAX_SAFE_INTEGER) { - return []; - } - var index = MAX_ARRAY_LENGTH, - length = nativeMin(n, MAX_ARRAY_LENGTH); - - iteratee = getIteratee(iteratee); - n -= MAX_ARRAY_LENGTH; - - var result = baseTimes(length, iteratee); - while (++index < n) { - iteratee(index); - } - return result; - } - - /** - * Converts `value` to a property path array. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Util - * @param {*} value The value to convert. - * @returns {Array} Returns the new property path array. - * @example - * - * _.toPath('a.b.c'); - * // => ['a', 'b', 'c'] - * - * _.toPath('a[0].b.c'); - * // => ['a', '0', 'b', 'c'] - */ - function toPath(value) { - if (isArray(value)) { - return arrayMap(value, toKey); - } - return isSymbol(value) ? [value] : copyArray(stringToPath(value)); - } - - /** - * Generates a unique ID. If `prefix` is given, the ID is appended to it. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {string} [prefix=''] The value to prefix the ID with. - * @returns {string} Returns the unique ID. - * @example - * - * _.uniqueId('contact_'); - * // => 'contact_104' - * - * _.uniqueId(); - * // => '105' - */ - function uniqueId(prefix) { - var id = ++idCounter; - return toString(prefix) + id; - } - - /*------------------------------------------------------------------------*/ - - /** - * Adds two numbers. - * - * @static - * @memberOf _ - * @since 3.4.0 - * @category Math - * @param {number} augend The first number in an addition. - * @param {number} addend The second number in an addition. - * @returns {number} Returns the total. - * @example - * - * _.add(6, 4); - * // => 10 - */ - var add = createMathOperation(function(augend, addend) { - return augend + addend; - }, 0); - - /** - * Computes `number` rounded up to `precision`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Math - * @param {number} number The number to round up. - * @param {number} [precision=0] The precision to round up to. - * @returns {number} Returns the rounded up number. - * @example - * - * _.ceil(4.006); - * // => 5 - * - * _.ceil(6.004, 2); - * // => 6.01 - * - * _.ceil(6040, -2); - * // => 6100 - */ - var ceil = createRound('ceil'); - - /** - * Divide two numbers. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Math - * @param {number} dividend The first number in a division. - * @param {number} divisor The second number in a division. - * @returns {number} Returns the quotient. - * @example - * - * _.divide(6, 4); - * // => 1.5 - */ - var divide = createMathOperation(function(dividend, divisor) { - return dividend / divisor; - }, 1); - - /** - * Computes `number` rounded down to `precision`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Math - * @param {number} number The number to round down. - * @param {number} [precision=0] The precision to round down to. - * @returns {number} Returns the rounded down number. - * @example - * - * _.floor(4.006); - * // => 4 - * - * _.floor(0.046, 2); - * // => 0.04 - * - * _.floor(4060, -2); - * // => 4000 - */ - var floor = createRound('floor'); - - /** - * Computes the maximum value of `array`. If `array` is empty or falsey, - * `undefined` is returned. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Math - * @param {Array} array The array to iterate over. - * @returns {*} Returns the maximum value. - * @example - * - * _.max([4, 2, 8, 6]); - * // => 8 - * - * _.max([]); - * // => undefined - */ - function max(array) { - return (array && array.length) - ? baseExtremum(array, identity, baseGt) - : undefined; - } - - /** - * This method is like `_.max` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the criterion by which - * the value is ranked. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Math - * @param {Array} array The array to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {*} Returns the maximum value. - * @example - * - * var objects = [{ 'n': 1 }, { 'n': 2 }]; - * - * _.maxBy(objects, function(o) { return o.n; }); - * // => { 'n': 2 } - * - * // The `_.property` iteratee shorthand. - * _.maxBy(objects, 'n'); - * // => { 'n': 2 } - */ - function maxBy(array, iteratee) { - return (array && array.length) - ? baseExtremum(array, getIteratee(iteratee, 2), baseGt) - : undefined; - } - - /** - * Computes the mean of the values in `array`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Math - * @param {Array} array The array to iterate over. - * @returns {number} Returns the mean. - * @example - * - * _.mean([4, 2, 8, 6]); - * // => 5 - */ - function mean(array) { - return baseMean(array, identity); - } - - /** - * This method is like `_.mean` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the value to be averaged. - * The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Math - * @param {Array} array The array to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {number} Returns the mean. - * @example - * - * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }]; - * - * _.meanBy(objects, function(o) { return o.n; }); - * // => 5 - * - * // The `_.property` iteratee shorthand. - * _.meanBy(objects, 'n'); - * // => 5 - */ - function meanBy(array, iteratee) { - return baseMean(array, getIteratee(iteratee, 2)); - } - - /** - * Computes the minimum value of `array`. If `array` is empty or falsey, - * `undefined` is returned. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Math - * @param {Array} array The array to iterate over. - * @returns {*} Returns the minimum value. - * @example - * - * _.min([4, 2, 8, 6]); - * // => 2 - * - * _.min([]); - * // => undefined - */ - function min(array) { - return (array && array.length) - ? baseExtremum(array, identity, baseLt) - : undefined; - } - - /** - * This method is like `_.min` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the criterion by which - * the value is ranked. The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Math - * @param {Array} array The array to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {*} Returns the minimum value. - * @example - * - * var objects = [{ 'n': 1 }, { 'n': 2 }]; - * - * _.minBy(objects, function(o) { return o.n; }); - * // => { 'n': 1 } - * - * // The `_.property` iteratee shorthand. - * _.minBy(objects, 'n'); - * // => { 'n': 1 } - */ - function minBy(array, iteratee) { - return (array && array.length) - ? baseExtremum(array, getIteratee(iteratee, 2), baseLt) - : undefined; - } - - /** - * Multiply two numbers. - * - * @static - * @memberOf _ - * @since 4.7.0 - * @category Math - * @param {number} multiplier The first number in a multiplication. - * @param {number} multiplicand The second number in a multiplication. - * @returns {number} Returns the product. - * @example - * - * _.multiply(6, 4); - * // => 24 - */ - var multiply = createMathOperation(function(multiplier, multiplicand) { - return multiplier * multiplicand; - }, 1); - - /** - * Computes `number` rounded to `precision`. - * - * @static - * @memberOf _ - * @since 3.10.0 - * @category Math - * @param {number} number The number to round. - * @param {number} [precision=0] The precision to round to. - * @returns {number} Returns the rounded number. - * @example - * - * _.round(4.006); - * // => 4 - * - * _.round(4.006, 2); - * // => 4.01 - * - * _.round(4060, -2); - * // => 4100 - */ - var round = createRound('round'); - - /** - * Subtract two numbers. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Math - * @param {number} minuend The first number in a subtraction. - * @param {number} subtrahend The second number in a subtraction. - * @returns {number} Returns the difference. - * @example - * - * _.subtract(6, 4); - * // => 2 - */ - var subtract = createMathOperation(function(minuend, subtrahend) { - return minuend - subtrahend; - }, 0); - - /** - * Computes the sum of the values in `array`. - * - * @static - * @memberOf _ - * @since 3.4.0 - * @category Math - * @param {Array} array The array to iterate over. - * @returns {number} Returns the sum. - * @example - * - * _.sum([4, 2, 8, 6]); - * // => 20 - */ - function sum(array) { - return (array && array.length) - ? baseSum(array, identity) - : 0; - } - - /** - * This method is like `_.sum` except that it accepts `iteratee` which is - * invoked for each element in `array` to generate the value to be summed. - * The iteratee is invoked with one argument: (value). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Math - * @param {Array} array The array to iterate over. - * @param {Function} [iteratee=_.identity] The iteratee invoked per element. - * @returns {number} Returns the sum. - * @example - * - * var objects = [{ 'n': 4 }, { 'n': 2 }, { 'n': 8 }, { 'n': 6 }]; - * - * _.sumBy(objects, function(o) { return o.n; }); - * // => 20 - * - * // The `_.property` iteratee shorthand. - * _.sumBy(objects, 'n'); - * // => 20 - */ - function sumBy(array, iteratee) { - return (array && array.length) - ? baseSum(array, getIteratee(iteratee, 2)) - : 0; - } - - /*------------------------------------------------------------------------*/ - - // Add methods that return wrapped values in chain sequences. - lodash.after = after; - lodash.ary = ary; - lodash.assign = assign; - lodash.assignIn = assignIn; - lodash.assignInWith = assignInWith; - lodash.assignWith = assignWith; - lodash.at = at; - lodash.before = before; - lodash.bind = bind; - lodash.bindAll = bindAll; - lodash.bindKey = bindKey; - lodash.castArray = castArray; - lodash.chain = chain; - lodash.chunk = chunk; - lodash.compact = compact; - lodash.concat = concat; - lodash.cond = cond; - lodash.conforms = conforms; - lodash.constant = constant; - lodash.countBy = countBy; - lodash.create = create; - lodash.curry = curry; - lodash.curryRight = curryRight; - lodash.debounce = debounce; - lodash.defaults = defaults; - lodash.defaultsDeep = defaultsDeep; - lodash.defer = defer; - lodash.delay = delay; - lodash.difference = difference; - lodash.differenceBy = differenceBy; - lodash.differenceWith = differenceWith; - lodash.drop = drop; - lodash.dropRight = dropRight; - lodash.dropRightWhile = dropRightWhile; - lodash.dropWhile = dropWhile; - lodash.fill = fill; - lodash.filter = filter; - lodash.flatMap = flatMap; - lodash.flatMapDeep = flatMapDeep; - lodash.flatMapDepth = flatMapDepth; - lodash.flatten = flatten; - lodash.flattenDeep = flattenDeep; - lodash.flattenDepth = flattenDepth; - lodash.flip = flip; - lodash.flow = flow; - lodash.flowRight = flowRight; - lodash.fromPairs = fromPairs; - lodash.functions = functions; - lodash.functionsIn = functionsIn; - lodash.groupBy = groupBy; - lodash.initial = initial; - lodash.intersection = intersection; - lodash.intersectionBy = intersectionBy; - lodash.intersectionWith = intersectionWith; - lodash.invert = invert; - lodash.invertBy = invertBy; - lodash.invokeMap = invokeMap; - lodash.iteratee = iteratee; - lodash.keyBy = keyBy; - lodash.keys = keys; - lodash.keysIn = keysIn; - lodash.map = map; - lodash.mapKeys = mapKeys; - lodash.mapValues = mapValues; - lodash.matches = matches; - lodash.matchesProperty = matchesProperty; - lodash.memoize = memoize; - lodash.merge = merge; - lodash.mergeWith = mergeWith; - lodash.method = method; - lodash.methodOf = methodOf; - lodash.mixin = mixin; - lodash.negate = negate; - lodash.nthArg = nthArg; - lodash.omit = omit; - lodash.omitBy = omitBy; - lodash.once = once; - lodash.orderBy = orderBy; - lodash.over = over; - lodash.overArgs = overArgs; - lodash.overEvery = overEvery; - lodash.overSome = overSome; - lodash.partial = partial; - lodash.partialRight = partialRight; - lodash.partition = partition; - lodash.pick = pick; - lodash.pickBy = pickBy; - lodash.property = property; - lodash.propertyOf = propertyOf; - lodash.pull = pull; - lodash.pullAll = pullAll; - lodash.pullAllBy = pullAllBy; - lodash.pullAllWith = pullAllWith; - lodash.pullAt = pullAt; - lodash.range = range; - lodash.rangeRight = rangeRight; - lodash.rearg = rearg; - lodash.reject = reject; - lodash.remove = remove; - lodash.rest = rest; - lodash.reverse = reverse; - lodash.sampleSize = sampleSize; - lodash.set = set; - lodash.setWith = setWith; - lodash.shuffle = shuffle; - lodash.slice = slice; - lodash.sortBy = sortBy; - lodash.sortedUniq = sortedUniq; - lodash.sortedUniqBy = sortedUniqBy; - lodash.split = split; - lodash.spread = spread; - lodash.tail = tail; - lodash.take = take; - lodash.takeRight = takeRight; - lodash.takeRightWhile = takeRightWhile; - lodash.takeWhile = takeWhile; - lodash.tap = tap; - lodash.throttle = throttle; - lodash.thru = thru; - lodash.toArray = toArray; - lodash.toPairs = toPairs; - lodash.toPairsIn = toPairsIn; - lodash.toPath = toPath; - lodash.toPlainObject = toPlainObject; - lodash.transform = transform; - lodash.unary = unary; - lodash.union = union; - lodash.unionBy = unionBy; - lodash.unionWith = unionWith; - lodash.uniq = uniq; - lodash.uniqBy = uniqBy; - lodash.uniqWith = uniqWith; - lodash.unset = unset; - lodash.unzip = unzip; - lodash.unzipWith = unzipWith; - lodash.update = update; - lodash.updateWith = updateWith; - lodash.values = values; - lodash.valuesIn = valuesIn; - lodash.without = without; - lodash.words = words; - lodash.wrap = wrap; - lodash.xor = xor; - lodash.xorBy = xorBy; - lodash.xorWith = xorWith; - lodash.zip = zip; - lodash.zipObject = zipObject; - lodash.zipObjectDeep = zipObjectDeep; - lodash.zipWith = zipWith; - - // Add aliases. - lodash.entries = toPairs; - lodash.entriesIn = toPairsIn; - lodash.extend = assignIn; - lodash.extendWith = assignInWith; - - // Add methods to `lodash.prototype`. - mixin(lodash, lodash); - - /*------------------------------------------------------------------------*/ - - // Add methods that return unwrapped values in chain sequences. - lodash.add = add; - lodash.attempt = attempt; - lodash.camelCase = camelCase; - lodash.capitalize = capitalize; - lodash.ceil = ceil; - lodash.clamp = clamp; - lodash.clone = clone; - lodash.cloneDeep = cloneDeep; - lodash.cloneDeepWith = cloneDeepWith; - lodash.cloneWith = cloneWith; - lodash.conformsTo = conformsTo; - lodash.deburr = deburr; - lodash.defaultTo = defaultTo; - lodash.divide = divide; - lodash.endsWith = endsWith; - lodash.eq = eq; - lodash.escape = escape; - lodash.escapeRegExp = escapeRegExp; - lodash.every = every; - lodash.find = find; - lodash.findIndex = findIndex; - lodash.findKey = findKey; - lodash.findLast = findLast; - lodash.findLastIndex = findLastIndex; - lodash.findLastKey = findLastKey; - lodash.floor = floor; - lodash.forEach = forEach; - lodash.forEachRight = forEachRight; - lodash.forIn = forIn; - lodash.forInRight = forInRight; - lodash.forOwn = forOwn; - lodash.forOwnRight = forOwnRight; - lodash.get = get; - lodash.gt = gt; - lodash.gte = gte; - lodash.has = has; - lodash.hasIn = hasIn; - lodash.head = head; - lodash.identity = identity; - lodash.includes = includes; - lodash.indexOf = indexOf; - lodash.inRange = inRange; - lodash.invoke = invoke; - lodash.isArguments = isArguments; - lodash.isArray = isArray; - lodash.isArrayBuffer = isArrayBuffer; - lodash.isArrayLike = isArrayLike; - lodash.isArrayLikeObject = isArrayLikeObject; - lodash.isBoolean = isBoolean; - lodash.isBuffer = isBuffer; - lodash.isDate = isDate; - lodash.isElement = isElement; - lodash.isEmpty = isEmpty; - lodash.isEqual = isEqual; - lodash.isEqualWith = isEqualWith; - lodash.isError = isError; - lodash.isFinite = isFinite; - lodash.isFunction = isFunction; - lodash.isInteger = isInteger; - lodash.isLength = isLength; - lodash.isMap = isMap; - lodash.isMatch = isMatch; - lodash.isMatchWith = isMatchWith; - lodash.isNaN = isNaN; - lodash.isNative = isNative; - lodash.isNil = isNil; - lodash.isNull = isNull; - lodash.isNumber = isNumber; - lodash.isObject = isObject; - lodash.isObjectLike = isObjectLike; - lodash.isPlainObject = isPlainObject; - lodash.isRegExp = isRegExp; - lodash.isSafeInteger = isSafeInteger; - lodash.isSet = isSet; - lodash.isString = isString; - lodash.isSymbol = isSymbol; - lodash.isTypedArray = isTypedArray; - lodash.isUndefined = isUndefined; - lodash.isWeakMap = isWeakMap; - lodash.isWeakSet = isWeakSet; - lodash.join = join; - lodash.kebabCase = kebabCase; - lodash.last = last; - lodash.lastIndexOf = lastIndexOf; - lodash.lowerCase = lowerCase; - lodash.lowerFirst = lowerFirst; - lodash.lt = lt; - lodash.lte = lte; - lodash.max = max; - lodash.maxBy = maxBy; - lodash.mean = mean; - lodash.meanBy = meanBy; - lodash.min = min; - lodash.minBy = minBy; - lodash.stubArray = stubArray; - lodash.stubFalse = stubFalse; - lodash.stubObject = stubObject; - lodash.stubString = stubString; - lodash.stubTrue = stubTrue; - lodash.multiply = multiply; - lodash.nth = nth; - lodash.noConflict = noConflict; - lodash.noop = noop; - lodash.now = now; - lodash.pad = pad; - lodash.padEnd = padEnd; - lodash.padStart = padStart; - lodash.parseInt = parseInt; - lodash.random = random; - lodash.reduce = reduce; - lodash.reduceRight = reduceRight; - lodash.repeat = repeat; - lodash.replace = replace; - lodash.result = result; - lodash.round = round; - lodash.runInContext = runInContext; - lodash.sample = sample; - lodash.size = size; - lodash.snakeCase = snakeCase; - lodash.some = some; - lodash.sortedIndex = sortedIndex; - lodash.sortedIndexBy = sortedIndexBy; - lodash.sortedIndexOf = sortedIndexOf; - lodash.sortedLastIndex = sortedLastIndex; - lodash.sortedLastIndexBy = sortedLastIndexBy; - lodash.sortedLastIndexOf = sortedLastIndexOf; - lodash.startCase = startCase; - lodash.startsWith = startsWith; - lodash.subtract = subtract; - lodash.sum = sum; - lodash.sumBy = sumBy; - lodash.template = template; - lodash.times = times; - lodash.toFinite = toFinite; - lodash.toInteger = toInteger; - lodash.toLength = toLength; - lodash.toLower = toLower; - lodash.toNumber = toNumber; - lodash.toSafeInteger = toSafeInteger; - lodash.toString = toString; - lodash.toUpper = toUpper; - lodash.trim = trim; - lodash.trimEnd = trimEnd; - lodash.trimStart = trimStart; - lodash.truncate = truncate; - lodash.unescape = unescape; - lodash.uniqueId = uniqueId; - lodash.upperCase = upperCase; - lodash.upperFirst = upperFirst; - - // Add aliases. - lodash.each = forEach; - lodash.eachRight = forEachRight; - lodash.first = head; - - mixin(lodash, (function() { - var source = {}; - baseForOwn(lodash, function(func, methodName) { - if (!hasOwnProperty.call(lodash.prototype, methodName)) { - source[methodName] = func; - } - }); - return source; - }()), { 'chain': false }); - - /*------------------------------------------------------------------------*/ - - /** - * The semantic version number. - * - * @static - * @memberOf _ - * @type {string} - */ - lodash.VERSION = VERSION; - - // Assign default placeholders. - arrayEach(['bind', 'bindKey', 'curry', 'curryRight', 'partial', 'partialRight'], function(methodName) { - lodash[methodName].placeholder = lodash; - }); - - // Add `LazyWrapper` methods for `_.drop` and `_.take` variants. - arrayEach(['drop', 'take'], function(methodName, index) { - LazyWrapper.prototype[methodName] = function(n) { - var filtered = this.__filtered__; - if (filtered && !index) { - return new LazyWrapper(this); - } - n = n === undefined ? 1 : nativeMax(toInteger(n), 0); - - var result = this.clone(); - if (filtered) { - result.__takeCount__ = nativeMin(n, result.__takeCount__); - } else { - result.__views__.push({ - 'size': nativeMin(n, MAX_ARRAY_LENGTH), - 'type': methodName + (result.__dir__ < 0 ? 'Right' : '') - }); - } - return result; - }; - - LazyWrapper.prototype[methodName + 'Right'] = function(n) { - return this.reverse()[methodName](n).reverse(); - }; - }); - - // Add `LazyWrapper` methods that accept an `iteratee` value. - arrayEach(['filter', 'map', 'takeWhile'], function(methodName, index) { - var type = index + 1, - isFilter = type == LAZY_FILTER_FLAG || type == LAZY_WHILE_FLAG; - - LazyWrapper.prototype[methodName] = function(iteratee) { - var result = this.clone(); - result.__iteratees__.push({ - 'iteratee': getIteratee(iteratee, 3), - 'type': type - }); - result.__filtered__ = result.__filtered__ || isFilter; - return result; - }; - }); - - // Add `LazyWrapper` methods for `_.head` and `_.last`. - arrayEach(['head', 'last'], function(methodName, index) { - var takeName = 'take' + (index ? 'Right' : ''); - - LazyWrapper.prototype[methodName] = function() { - return this[takeName](1).value()[0]; - }; - }); - - // Add `LazyWrapper` methods for `_.initial` and `_.tail`. - arrayEach(['initial', 'tail'], function(methodName, index) { - var dropName = 'drop' + (index ? '' : 'Right'); - - LazyWrapper.prototype[methodName] = function() { - return this.__filtered__ ? new LazyWrapper(this) : this[dropName](1); - }; - }); - - LazyWrapper.prototype.compact = function() { - return this.filter(identity); - }; - - LazyWrapper.prototype.find = function(predicate) { - return this.filter(predicate).head(); - }; - - LazyWrapper.prototype.findLast = function(predicate) { - return this.reverse().find(predicate); - }; - - LazyWrapper.prototype.invokeMap = baseRest(function(path, args) { - if (typeof path == 'function') { - return new LazyWrapper(this); - } - return this.map(function(value) { - return baseInvoke(value, path, args); - }); - }); - - LazyWrapper.prototype.reject = function(predicate) { - return this.filter(negate(getIteratee(predicate))); - }; - - LazyWrapper.prototype.slice = function(start, end) { - start = toInteger(start); - - var result = this; - if (result.__filtered__ && (start > 0 || end < 0)) { - return new LazyWrapper(result); - } - if (start < 0) { - result = result.takeRight(-start); - } else if (start) { - result = result.drop(start); - } - if (end !== undefined) { - end = toInteger(end); - result = end < 0 ? result.dropRight(-end) : result.take(end - start); - } - return result; - }; - - LazyWrapper.prototype.takeRightWhile = function(predicate) { - return this.reverse().takeWhile(predicate).reverse(); - }; - - LazyWrapper.prototype.toArray = function() { - return this.take(MAX_ARRAY_LENGTH); - }; - - // Add `LazyWrapper` methods to `lodash.prototype`. - baseForOwn(LazyWrapper.prototype, function(func, methodName) { - var checkIteratee = /^(?:filter|find|map|reject)|While$/.test(methodName), - isTaker = /^(?:head|last)$/.test(methodName), - lodashFunc = lodash[isTaker ? ('take' + (methodName == 'last' ? 'Right' : '')) : methodName], - retUnwrapped = isTaker || /^find/.test(methodName); - - if (!lodashFunc) { - return; - } - lodash.prototype[methodName] = function() { - var value = this.__wrapped__, - args = isTaker ? [1] : arguments, - isLazy = value instanceof LazyWrapper, - iteratee = args[0], - useLazy = isLazy || isArray(value); - - var interceptor = function(value) { - var result = lodashFunc.apply(lodash, arrayPush([value], args)); - return (isTaker && chainAll) ? result[0] : result; - }; - - if (useLazy && checkIteratee && typeof iteratee == 'function' && iteratee.length != 1) { - // Avoid lazy use if the iteratee has a "length" value other than `1`. - isLazy = useLazy = false; - } - var chainAll = this.__chain__, - isHybrid = !!this.__actions__.length, - isUnwrapped = retUnwrapped && !chainAll, - onlyLazy = isLazy && !isHybrid; - - if (!retUnwrapped && useLazy) { - value = onlyLazy ? value : new LazyWrapper(this); - var result = func.apply(value, args); - result.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); - return new LodashWrapper(result, chainAll); - } - if (isUnwrapped && onlyLazy) { - return func.apply(this, args); - } - result = this.thru(interceptor); - return isUnwrapped ? (isTaker ? result.value()[0] : result.value()) : result; - }; - }); - - // Add `Array` methods to `lodash.prototype`. - arrayEach(['pop', 'push', 'shift', 'sort', 'splice', 'unshift'], function(methodName) { - var func = arrayProto[methodName], - chainName = /^(?:push|sort|unshift)$/.test(methodName) ? 'tap' : 'thru', - retUnwrapped = /^(?:pop|shift)$/.test(methodName); - - lodash.prototype[methodName] = function() { - var args = arguments; - if (retUnwrapped && !this.__chain__) { - var value = this.value(); - return func.apply(isArray(value) ? value : [], args); - } - return this[chainName](function(value) { - return func.apply(isArray(value) ? value : [], args); - }); - }; - }); - - // Map minified method names to their real names. - baseForOwn(LazyWrapper.prototype, function(func, methodName) { - var lodashFunc = lodash[methodName]; - if (lodashFunc) { - var key = (lodashFunc.name + ''), - names = realNames[key] || (realNames[key] = []); - - names.push({ 'name': methodName, 'func': lodashFunc }); - } - }); - - realNames[createHybrid(undefined, BIND_KEY_FLAG).name] = [{ - 'name': 'wrapper', - 'func': undefined - }]; - - // Add methods to `LazyWrapper`. - LazyWrapper.prototype.clone = lazyClone; - LazyWrapper.prototype.reverse = lazyReverse; - LazyWrapper.prototype.value = lazyValue; - - // Add chain sequence methods to the `lodash` wrapper. - lodash.prototype.at = wrapperAt; - lodash.prototype.chain = wrapperChain; - lodash.prototype.commit = wrapperCommit; - lodash.prototype.next = wrapperNext; - lodash.prototype.plant = wrapperPlant; - lodash.prototype.reverse = wrapperReverse; - lodash.prototype.toJSON = lodash.prototype.valueOf = lodash.prototype.value = wrapperValue; - - // Add lazy aliases. - lodash.prototype.first = lodash.prototype.head; - - if (iteratorSymbol) { - lodash.prototype[iteratorSymbol] = wrapperToIterator; - } - return lodash; - } - - /*--------------------------------------------------------------------------*/ - - // Export lodash. - var _ = runInContext(); - - // Some AMD build optimizers, like r.js, check for condition patterns like: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // Expose Lodash on the global object to prevent errors when Lodash is - // loaded by a script tag in the presence of an AMD loader. - // See http://requirejs.org/docs/errors.html#mismatch for more details. - // Use `_.noConflict` to remove Lodash from the global object. - root._ = _; - - // Define as an anonymous module so, through path mapping, it can be - // referenced as the "underscore" module. - define(function() { - return _; - }); - } - // Check for `exports` after `define` in case a build optimizer adds it. - else if (freeModule) { - // Export for Node.js. - (freeModule.exports = _)._ = _; - // Export for CommonJS support. - freeExports._ = _; - } - else { - // Export to the global object. - root._ = _; - } -}.call(this)); diff --git a/third_party/immer/extra/js/lib/mori.js b/third_party/immer/extra/js/lib/mori.js deleted file mode 100644 index 39954ef9fe16..000000000000 --- a/third_party/immer/extra/js/lib/mori.js +++ /dev/null @@ -1,435 +0,0 @@ -/* - * immer: immutable data structures for C++ - * Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente - * - * This software is distributed under the Boost Software License, Version 1.0. - * See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt - */ - -(function(definition){if(typeof exports==="object"){module.exports=definition();}else if(typeof define==="function"&&define.amd){define(definition);}else{mori=definition();}})(function(){return function(){ -if(typeof Math.imul == "undefined" || (Math.imul(0xffffffff,5) == 0)) { - Math.imul = function (a, b) { - var ah = (a >>> 16) & 0xffff; - var al = a & 0xffff; - var bh = (b >>> 16) & 0xffff; - var bl = b & 0xffff; - // the shift by 0 fixes the sign on the high part - // the final |0 converts the unsigned value into a signed value - return ((al * bl) + (((ah * bl + al * bh) << 16) >>> 0)|0); - } -} - -var k,aa=this; -function n(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null";else if("function"== -b&&"undefined"==typeof a.call)return"object";return b}var ba="closure_uid_"+(1E9*Math.random()>>>0),ca=0;function r(a,b){var c=a.split("."),d=aa;c[0]in d||!d.execScript||d.execScript("var "+c[0]);for(var e;c.length&&(e=c.shift());)c.length||void 0===b?d=d[e]?d[e]:d[e]={}:d[e]=b};function da(a){return Array.prototype.join.call(arguments,"")};function ea(a,b){for(var c in a)b.call(void 0,a[c],c,a)};function fa(a,b){null!=a&&this.append.apply(this,arguments)}fa.prototype.Za="";fa.prototype.append=function(a,b,c){this.Za+=a;if(null!=b)for(var d=1;d<arguments.length;d++)this.Za+=arguments[d];return this};fa.prototype.clear=function(){this.Za=""};fa.prototype.toString=function(){return this.Za};function ga(a,b){a.sort(b||ha)}function ia(a,b){for(var c=0;c<a.length;c++)a[c]={index:c,value:a[c]};var d=b||ha;ga(a,function(a,b){return d(a.value,b.value)||a.index-b.index});for(c=0;c<a.length;c++)a[c]=a[c].value}function ha(a,b){return a>b?1:a<b?-1:0};var ja;if("undefined"===typeof ka)var ka=function(){throw Error("No *print-fn* fn set for evaluation environment");};var la=null,ma=null;if("undefined"===typeof na)var na=null;function oa(){return new pa(null,5,[sa,!0,ua,!0,wa,!1,ya,!1,za,la],null)}function t(a){return null!=a&&!1!==a}function Aa(a){return t(a)?!1:!0}function w(a,b){return a[n(null==b?null:b)]?!0:a._?!0:!1}function Ba(a){return null==a?null:a.constructor} -function x(a,b){var c=Ba(b),c=t(t(c)?c.Yb:c)?c.Xb:n(b);return Error(["No protocol method ",a," defined for type ",c,": ",b].join(""))}function Da(a){var b=a.Xb;return t(b)?b:""+z(a)}var Ea="undefined"!==typeof Symbol&&"function"===n(Symbol)?Symbol.Cc:"@@iterator";function Fa(a){for(var b=a.length,c=Array(b),d=0;;)if(d<b)c[d]=a[d],d+=1;else break;return c}function Ha(a){for(var b=Array(arguments.length),c=0;;)if(c<b.length)b[c]=arguments[c],c+=1;else return b} -var Ia=function(){function a(a,b){function c(a,b){a.push(b);return a}var g=[];return A.c?A.c(c,g,b):A.call(null,c,g,b)}function b(a){return c.a(null,a)}var c=null,c=function(d,c){switch(arguments.length){case 1:return b.call(this,d);case 2:return a.call(this,0,c)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),Ja={},La={};function Ma(a){if(a?a.L:a)return a.L(a);var b;b=Ma[n(null==a?null:a)];if(!b&&(b=Ma._,!b))throw x("ICounted.-count",a);return b.call(null,a)} -function Na(a){if(a?a.J:a)return a.J(a);var b;b=Na[n(null==a?null:a)];if(!b&&(b=Na._,!b))throw x("IEmptyableCollection.-empty",a);return b.call(null,a)}var Qa={};function Ra(a,b){if(a?a.G:a)return a.G(a,b);var c;c=Ra[n(null==a?null:a)];if(!c&&(c=Ra._,!c))throw x("ICollection.-conj",a);return c.call(null,a,b)} -var Ta={},C=function(){function a(a,b,c){if(a?a.$:a)return a.$(a,b,c);var g;g=C[n(null==a?null:a)];if(!g&&(g=C._,!g))throw x("IIndexed.-nth",a);return g.call(null,a,b,c)}function b(a,b){if(a?a.Q:a)return a.Q(a,b);var c;c=C[n(null==a?null:a)];if(!c&&(c=C._,!c))throw x("IIndexed.-nth",a);return c.call(null,a,b)}var c=null,c=function(d,c,f){switch(arguments.length){case 2:return b.call(this,d,c);case 3:return a.call(this,d,c,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}(), -Ua={};function Va(a){if(a?a.N:a)return a.N(a);var b;b=Va[n(null==a?null:a)];if(!b&&(b=Va._,!b))throw x("ISeq.-first",a);return b.call(null,a)}function Wa(a){if(a?a.S:a)return a.S(a);var b;b=Wa[n(null==a?null:a)];if(!b&&(b=Wa._,!b))throw x("ISeq.-rest",a);return b.call(null,a)} -var Xa={},Za={},$a=function(){function a(a,b,c){if(a?a.s:a)return a.s(a,b,c);var g;g=$a[n(null==a?null:a)];if(!g&&(g=$a._,!g))throw x("ILookup.-lookup",a);return g.call(null,a,b,c)}function b(a,b){if(a?a.t:a)return a.t(a,b);var c;c=$a[n(null==a?null:a)];if(!c&&(c=$a._,!c))throw x("ILookup.-lookup",a);return c.call(null,a,b)}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c= -a;return c}(),ab={};function bb(a,b){if(a?a.rb:a)return a.rb(a,b);var c;c=bb[n(null==a?null:a)];if(!c&&(c=bb._,!c))throw x("IAssociative.-contains-key?",a);return c.call(null,a,b)}function cb(a,b,c){if(a?a.Ka:a)return a.Ka(a,b,c);var d;d=cb[n(null==a?null:a)];if(!d&&(d=cb._,!d))throw x("IAssociative.-assoc",a);return d.call(null,a,b,c)}var db={};function eb(a,b){if(a?a.wb:a)return a.wb(a,b);var c;c=eb[n(null==a?null:a)];if(!c&&(c=eb._,!c))throw x("IMap.-dissoc",a);return c.call(null,a,b)}var fb={}; -function hb(a){if(a?a.hb:a)return a.hb(a);var b;b=hb[n(null==a?null:a)];if(!b&&(b=hb._,!b))throw x("IMapEntry.-key",a);return b.call(null,a)}function ib(a){if(a?a.ib:a)return a.ib(a);var b;b=ib[n(null==a?null:a)];if(!b&&(b=ib._,!b))throw x("IMapEntry.-val",a);return b.call(null,a)}var jb={};function kb(a,b){if(a?a.Eb:a)return a.Eb(a,b);var c;c=kb[n(null==a?null:a)];if(!c&&(c=kb._,!c))throw x("ISet.-disjoin",a);return c.call(null,a,b)} -function lb(a){if(a?a.La:a)return a.La(a);var b;b=lb[n(null==a?null:a)];if(!b&&(b=lb._,!b))throw x("IStack.-peek",a);return b.call(null,a)}function mb(a){if(a?a.Ma:a)return a.Ma(a);var b;b=mb[n(null==a?null:a)];if(!b&&(b=mb._,!b))throw x("IStack.-pop",a);return b.call(null,a)}var nb={};function pb(a,b,c){if(a?a.Ua:a)return a.Ua(a,b,c);var d;d=pb[n(null==a?null:a)];if(!d&&(d=pb._,!d))throw x("IVector.-assoc-n",a);return d.call(null,a,b,c)} -function qb(a){if(a?a.Ra:a)return a.Ra(a);var b;b=qb[n(null==a?null:a)];if(!b&&(b=qb._,!b))throw x("IDeref.-deref",a);return b.call(null,a)}var rb={};function sb(a){if(a?a.H:a)return a.H(a);var b;b=sb[n(null==a?null:a)];if(!b&&(b=sb._,!b))throw x("IMeta.-meta",a);return b.call(null,a)}var tb={};function ub(a,b){if(a?a.F:a)return a.F(a,b);var c;c=ub[n(null==a?null:a)];if(!c&&(c=ub._,!c))throw x("IWithMeta.-with-meta",a);return c.call(null,a,b)} -var vb={},wb=function(){function a(a,b,c){if(a?a.O:a)return a.O(a,b,c);var g;g=wb[n(null==a?null:a)];if(!g&&(g=wb._,!g))throw x("IReduce.-reduce",a);return g.call(null,a,b,c)}function b(a,b){if(a?a.R:a)return a.R(a,b);var c;c=wb[n(null==a?null:a)];if(!c&&(c=wb._,!c))throw x("IReduce.-reduce",a);return c.call(null,a,b)}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}(); -function xb(a,b,c){if(a?a.gb:a)return a.gb(a,b,c);var d;d=xb[n(null==a?null:a)];if(!d&&(d=xb._,!d))throw x("IKVReduce.-kv-reduce",a);return d.call(null,a,b,c)}function yb(a,b){if(a?a.A:a)return a.A(a,b);var c;c=yb[n(null==a?null:a)];if(!c&&(c=yb._,!c))throw x("IEquiv.-equiv",a);return c.call(null,a,b)}function zb(a){if(a?a.B:a)return a.B(a);var b;b=zb[n(null==a?null:a)];if(!b&&(b=zb._,!b))throw x("IHash.-hash",a);return b.call(null,a)}var Bb={}; -function Cb(a){if(a?a.D:a)return a.D(a);var b;b=Cb[n(null==a?null:a)];if(!b&&(b=Cb._,!b))throw x("ISeqable.-seq",a);return b.call(null,a)}var Db={},Eb={},Fb={};function Gb(a){if(a?a.ab:a)return a.ab(a);var b;b=Gb[n(null==a?null:a)];if(!b&&(b=Gb._,!b))throw x("IReversible.-rseq",a);return b.call(null,a)}function Hb(a,b){if(a?a.Hb:a)return a.Hb(a,b);var c;c=Hb[n(null==a?null:a)];if(!c&&(c=Hb._,!c))throw x("ISorted.-sorted-seq",a);return c.call(null,a,b)} -function Ib(a,b,c){if(a?a.Ib:a)return a.Ib(a,b,c);var d;d=Ib[n(null==a?null:a)];if(!d&&(d=Ib._,!d))throw x("ISorted.-sorted-seq-from",a);return d.call(null,a,b,c)}function Jb(a,b){if(a?a.Gb:a)return a.Gb(a,b);var c;c=Jb[n(null==a?null:a)];if(!c&&(c=Jb._,!c))throw x("ISorted.-entry-key",a);return c.call(null,a,b)}function Kb(a){if(a?a.Fb:a)return a.Fb(a);var b;b=Kb[n(null==a?null:a)];if(!b&&(b=Kb._,!b))throw x("ISorted.-comparator",a);return b.call(null,a)} -function Lb(a,b){if(a?a.Wb:a)return a.Wb(0,b);var c;c=Lb[n(null==a?null:a)];if(!c&&(c=Lb._,!c))throw x("IWriter.-write",a);return c.call(null,a,b)}var Mb={};function Nb(a,b,c){if(a?a.v:a)return a.v(a,b,c);var d;d=Nb[n(null==a?null:a)];if(!d&&(d=Nb._,!d))throw x("IPrintWithWriter.-pr-writer",a);return d.call(null,a,b,c)}function Ob(a){if(a?a.$a:a)return a.$a(a);var b;b=Ob[n(null==a?null:a)];if(!b&&(b=Ob._,!b))throw x("IEditableCollection.-as-transient",a);return b.call(null,a)} -function Pb(a,b){if(a?a.Sa:a)return a.Sa(a,b);var c;c=Pb[n(null==a?null:a)];if(!c&&(c=Pb._,!c))throw x("ITransientCollection.-conj!",a);return c.call(null,a,b)}function Qb(a){if(a?a.Ta:a)return a.Ta(a);var b;b=Qb[n(null==a?null:a)];if(!b&&(b=Qb._,!b))throw x("ITransientCollection.-persistent!",a);return b.call(null,a)}function Rb(a,b,c){if(a?a.kb:a)return a.kb(a,b,c);var d;d=Rb[n(null==a?null:a)];if(!d&&(d=Rb._,!d))throw x("ITransientAssociative.-assoc!",a);return d.call(null,a,b,c)} -function Sb(a,b){if(a?a.Jb:a)return a.Jb(a,b);var c;c=Sb[n(null==a?null:a)];if(!c&&(c=Sb._,!c))throw x("ITransientMap.-dissoc!",a);return c.call(null,a,b)}function Tb(a,b,c){if(a?a.Ub:a)return a.Ub(0,b,c);var d;d=Tb[n(null==a?null:a)];if(!d&&(d=Tb._,!d))throw x("ITransientVector.-assoc-n!",a);return d.call(null,a,b,c)}function Ub(a){if(a?a.Vb:a)return a.Vb();var b;b=Ub[n(null==a?null:a)];if(!b&&(b=Ub._,!b))throw x("ITransientVector.-pop!",a);return b.call(null,a)} -function Vb(a,b){if(a?a.Tb:a)return a.Tb(0,b);var c;c=Vb[n(null==a?null:a)];if(!c&&(c=Vb._,!c))throw x("ITransientSet.-disjoin!",a);return c.call(null,a,b)}function Xb(a){if(a?a.Pb:a)return a.Pb();var b;b=Xb[n(null==a?null:a)];if(!b&&(b=Xb._,!b))throw x("IChunk.-drop-first",a);return b.call(null,a)}function Yb(a){if(a?a.Cb:a)return a.Cb(a);var b;b=Yb[n(null==a?null:a)];if(!b&&(b=Yb._,!b))throw x("IChunkedSeq.-chunked-first",a);return b.call(null,a)} -function Zb(a){if(a?a.Db:a)return a.Db(a);var b;b=Zb[n(null==a?null:a)];if(!b&&(b=Zb._,!b))throw x("IChunkedSeq.-chunked-rest",a);return b.call(null,a)}function $b(a){if(a?a.Bb:a)return a.Bb(a);var b;b=$b[n(null==a?null:a)];if(!b&&(b=$b._,!b))throw x("IChunkedNext.-chunked-next",a);return b.call(null,a)}function ac(a,b){if(a?a.bb:a)return a.bb(0,b);var c;c=ac[n(null==a?null:a)];if(!c&&(c=ac._,!c))throw x("IVolatile.-vreset!",a);return c.call(null,a,b)}var bc={}; -function cc(a){if(a?a.fb:a)return a.fb(a);var b;b=cc[n(null==a?null:a)];if(!b&&(b=cc._,!b))throw x("IIterable.-iterator",a);return b.call(null,a)}function dc(a){this.qc=a;this.q=0;this.j=1073741824}dc.prototype.Wb=function(a,b){return this.qc.append(b)};function ec(a){var b=new fa;a.v(null,new dc(b),oa());return""+z(b)} -var fc="undefined"!==typeof Math.imul&&0!==(Math.imul.a?Math.imul.a(4294967295,5):Math.imul.call(null,4294967295,5))?function(a,b){return Math.imul.a?Math.imul.a(a,b):Math.imul.call(null,a,b)}:function(a,b){var c=a&65535,d=b&65535;return c*d+((a>>>16&65535)*d+c*(b>>>16&65535)<<16>>>0)|0};function gc(a){a=fc(a,3432918353);return fc(a<<15|a>>>-15,461845907)}function hc(a,b){var c=a^b;return fc(c<<13|c>>>-13,5)+3864292196} -function ic(a,b){var c=a^b,c=fc(c^c>>>16,2246822507),c=fc(c^c>>>13,3266489909);return c^c>>>16}var kc={},lc=0;function mc(a){255<lc&&(kc={},lc=0);var b=kc[a];if("number"!==typeof b){a:if(null!=a)if(b=a.length,0<b){for(var c=0,d=0;;)if(c<b)var e=c+1,d=fc(31,d)+a.charCodeAt(c),c=e;else{b=d;break a}b=void 0}else b=0;else b=0;kc[a]=b;lc+=1}return a=b} -function nc(a){a&&(a.j&4194304||a.vc)?a=a.B(null):"number"===typeof a?a=(Math.floor.b?Math.floor.b(a):Math.floor.call(null,a))%2147483647:!0===a?a=1:!1===a?a=0:"string"===typeof a?(a=mc(a),0!==a&&(a=gc(a),a=hc(0,a),a=ic(a,4))):a=a instanceof Date?a.valueOf():null==a?0:zb(a);return a} -function oc(a){var b;b=a.name;var c;a:{c=1;for(var d=0;;)if(c<b.length){var e=c+2,d=hc(d,gc(b.charCodeAt(c-1)|b.charCodeAt(c)<<16));c=e}else{c=d;break a}c=void 0}c=1===(b.length&1)?c^gc(b.charCodeAt(b.length-1)):c;b=ic(c,fc(2,b.length));a=mc(a.ba);return b^a+2654435769+(b<<6)+(b>>2)}function pc(a,b){if(a.ta===b.ta)return 0;var c=Aa(a.ba);if(t(c?b.ba:c))return-1;if(t(a.ba)){if(Aa(b.ba))return 1;c=ha(a.ba,b.ba);return 0===c?ha(a.name,b.name):c}return ha(a.name,b.name)} -function qc(a,b,c,d,e){this.ba=a;this.name=b;this.ta=c;this.Ya=d;this.Z=e;this.j=2154168321;this.q=4096}k=qc.prototype;k.v=function(a,b){return Lb(b,this.ta)};k.B=function(){var a=this.Ya;return null!=a?a:this.Ya=a=oc(this)};k.F=function(a,b){return new qc(this.ba,this.name,this.ta,this.Ya,b)};k.H=function(){return this.Z}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return $a.c(c,this,null);case 3:return $a.c(c,this,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return $a.c(c,this,null)};a.c=function(a,c,d){return $a.c(c,this,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return $a.c(a,this,null)};k.a=function(a,b){return $a.c(a,this,b)};k.A=function(a,b){return b instanceof qc?this.ta===b.ta:!1}; -k.toString=function(){return this.ta};var rc=function(){function a(a,b){var c=null!=a?[z(a),z("/"),z(b)].join(""):b;return new qc(a,b,c,null,null)}function b(a){return a instanceof qc?a:c.a(null,a)}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(); -function D(a){if(null==a)return null;if(a&&(a.j&8388608||a.mc))return a.D(null);if(a instanceof Array||"string"===typeof a)return 0===a.length?null:new F(a,0);if(w(Bb,a))return Cb(a);throw Error([z(a),z(" is not ISeqable")].join(""));}function G(a){if(null==a)return null;if(a&&(a.j&64||a.jb))return a.N(null);a=D(a);return null==a?null:Va(a)}function H(a){return null!=a?a&&(a.j&64||a.jb)?a.S(null):(a=D(a))?Wa(a):J:J}function K(a){return null==a?null:a&&(a.j&128||a.xb)?a.T(null):D(H(a))} -var sc=function(){function a(a,b){return null==a?null==b:a===b||yb(a,b)}var b=null,c=function(){function a(b,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return c.call(this,b,d,l)}function c(a,d,e){for(;;)if(b.a(a,d))if(K(e))a=d,d=G(e),e=K(e);else return b.a(d,G(e));else return!1}a.i=2;a.f=function(a){var b=G(a);a=K(a);var d=G(a);a=H(a);return c(b,d,a)};a.d=c;return a}(),b=function(b,e,f){switch(arguments.length){case 1:return!0; -case 2:return a.call(this,b,e);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.b=function(){return!0};b.a=a;b.d=c.d;return b}();function tc(a){this.C=a}tc.prototype.next=function(){if(null!=this.C){var a=G(this.C);this.C=K(this.C);return{done:!1,value:a}}return{done:!0,value:null}};function uc(a){return new tc(D(a))} -function vc(a,b){var c=gc(a),c=hc(0,c);return ic(c,b)}function wc(a){var b=0,c=1;for(a=D(a);;)if(null!=a)b+=1,c=fc(31,c)+nc(G(a))|0,a=K(a);else return vc(c,b)}function xc(a){var b=0,c=0;for(a=D(a);;)if(null!=a)b+=1,c=c+nc(G(a))|0,a=K(a);else return vc(c,b)}La["null"]=!0;Ma["null"]=function(){return 0};Date.prototype.A=function(a,b){return b instanceof Date&&this.toString()===b.toString()};yb.number=function(a,b){return a===b};rb["function"]=!0;sb["function"]=function(){return null}; -Ja["function"]=!0;zb._=function(a){return a[ba]||(a[ba]=++ca)};function yc(a){this.o=a;this.q=0;this.j=32768}yc.prototype.Ra=function(){return this.o};function Ac(a){return a instanceof yc}function Bc(a){return Ac(a)?L.b?L.b(a):L.call(null,a):a}function L(a){return qb(a)} -var Cc=function(){function a(a,b,c,d){for(var l=Ma(a);;)if(d<l){var m=C.a(a,d);c=b.a?b.a(c,m):b.call(null,c,m);if(Ac(c))return qb(c);d+=1}else return c}function b(a,b,c){var d=Ma(a),l=c;for(c=0;;)if(c<d){var m=C.a(a,c),l=b.a?b.a(l,m):b.call(null,l,m);if(Ac(l))return qb(l);c+=1}else return l}function c(a,b){var c=Ma(a);if(0===c)return b.l?b.l():b.call(null);for(var d=C.a(a,0),l=1;;)if(l<c){var m=C.a(a,l),d=b.a?b.a(d,m):b.call(null,d,m);if(Ac(d))return qb(d);l+=1}else return d}var d=null,d=function(d, -f,g,h){switch(arguments.length){case 2:return c.call(this,d,f);case 3:return b.call(this,d,f,g);case 4:return a.call(this,d,f,g,h)}throw Error("Invalid arity: "+arguments.length);};d.a=c;d.c=b;d.n=a;return d}(),Dc=function(){function a(a,b,c,d){for(var l=a.length;;)if(d<l){var m=a[d];c=b.a?b.a(c,m):b.call(null,c,m);if(Ac(c))return qb(c);d+=1}else return c}function b(a,b,c){var d=a.length,l=c;for(c=0;;)if(c<d){var m=a[c],l=b.a?b.a(l,m):b.call(null,l,m);if(Ac(l))return qb(l);c+=1}else return l}function c(a, -b){var c=a.length;if(0===a.length)return b.l?b.l():b.call(null);for(var d=a[0],l=1;;)if(l<c){var m=a[l],d=b.a?b.a(d,m):b.call(null,d,m);if(Ac(d))return qb(d);l+=1}else return d}var d=null,d=function(d,f,g,h){switch(arguments.length){case 2:return c.call(this,d,f);case 3:return b.call(this,d,f,g);case 4:return a.call(this,d,f,g,h)}throw Error("Invalid arity: "+arguments.length);};d.a=c;d.c=b;d.n=a;return d}();function Ec(a){return a?a.j&2||a.cc?!0:a.j?!1:w(La,a):w(La,a)} -function Fc(a){return a?a.j&16||a.Qb?!0:a.j?!1:w(Ta,a):w(Ta,a)}function Gc(a,b){this.e=a;this.m=b}Gc.prototype.ga=function(){return this.m<this.e.length};Gc.prototype.next=function(){var a=this.e[this.m];this.m+=1;return a};function F(a,b){this.e=a;this.m=b;this.j=166199550;this.q=8192}k=F.prototype;k.toString=function(){return ec(this)};k.Q=function(a,b){var c=b+this.m;return c<this.e.length?this.e[c]:null};k.$=function(a,b,c){a=b+this.m;return a<this.e.length?this.e[a]:c};k.vb=!0; -k.fb=function(){return new Gc(this.e,this.m)};k.T=function(){return this.m+1<this.e.length?new F(this.e,this.m+1):null};k.L=function(){return this.e.length-this.m};k.ab=function(){var a=Ma(this);return 0<a?new Hc(this,a-1,null):null};k.B=function(){return wc(this)};k.A=function(a,b){return Ic.a?Ic.a(this,b):Ic.call(null,this,b)};k.J=function(){return J};k.R=function(a,b){return Dc.n(this.e,b,this.e[this.m],this.m+1)};k.O=function(a,b,c){return Dc.n(this.e,b,c,this.m)};k.N=function(){return this.e[this.m]}; -k.S=function(){return this.m+1<this.e.length?new F(this.e,this.m+1):J};k.D=function(){return this};k.G=function(a,b){return M.a?M.a(b,this):M.call(null,b,this)};F.prototype[Ea]=function(){return uc(this)}; -var Jc=function(){function a(a,b){return b<a.length?new F(a,b):null}function b(a){return c.a(a,0)}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),Kc=function(){function a(a,b){return Jc.a(a,b)}function b(a){return Jc.a(a,0)}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+ -arguments.length);};c.b=b;c.a=a;return c}();function Hc(a,b,c){this.qb=a;this.m=b;this.k=c;this.j=32374990;this.q=8192}k=Hc.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.k};k.T=function(){return 0<this.m?new Hc(this.qb,this.m-1,null):null};k.L=function(){return this.m+1};k.B=function(){return wc(this)};k.A=function(a,b){return Ic.a?Ic.a(this,b):Ic.call(null,this,b)};k.J=function(){var a=this.k;return O.a?O.a(J,a):O.call(null,J,a)}; -k.R=function(a,b){return P.a?P.a(b,this):P.call(null,b,this)};k.O=function(a,b,c){return P.c?P.c(b,c,this):P.call(null,b,c,this)};k.N=function(){return C.a(this.qb,this.m)};k.S=function(){return 0<this.m?new Hc(this.qb,this.m-1,null):J};k.D=function(){return this};k.F=function(a,b){return new Hc(this.qb,this.m,b)};k.G=function(a,b){return M.a?M.a(b,this):M.call(null,b,this)};Hc.prototype[Ea]=function(){return uc(this)};function Lc(a){return G(K(a))}yb._=function(a,b){return a===b}; -var Nc=function(){function a(a,b){return null!=a?Ra(a,b):Ra(J,b)}var b=null,c=function(){function a(b,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return c.call(this,b,d,l)}function c(a,d,e){for(;;)if(t(e))a=b.a(a,d),d=G(e),e=K(e);else return b.a(a,d)}a.i=2;a.f=function(a){var b=G(a);a=K(a);var d=G(a);a=H(a);return c(b,d,a)};a.d=c;return a}(),b=function(b,e,f){switch(arguments.length){case 0:return Mc;case 1:return b; -case 2:return a.call(this,b,e);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.l=function(){return Mc};b.b=function(a){return a};b.a=a;b.d=c.d;return b}();function Oc(a){return null==a?null:Na(a)} -function Q(a){if(null!=a)if(a&&(a.j&2||a.cc))a=a.L(null);else if(a instanceof Array)a=a.length;else if("string"===typeof a)a=a.length;else if(w(La,a))a=Ma(a);else a:{a=D(a);for(var b=0;;){if(Ec(a)){a=b+Ma(a);break a}a=K(a);b+=1}a=void 0}else a=0;return a} -var Pc=function(){function a(a,b,c){for(;;){if(null==a)return c;if(0===b)return D(a)?G(a):c;if(Fc(a))return C.c(a,b,c);if(D(a))a=K(a),b-=1;else return c}}function b(a,b){for(;;){if(null==a)throw Error("Index out of bounds");if(0===b){if(D(a))return G(a);throw Error("Index out of bounds");}if(Fc(a))return C.a(a,b);if(D(a)){var c=K(a),g=b-1;a=c;b=g}else throw Error("Index out of bounds");}}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this, -c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}(),R=function(){function a(a,b,c){if("number"!==typeof b)throw Error("index argument to nth must be a number.");if(null==a)return c;if(a&&(a.j&16||a.Qb))return a.$(null,b,c);if(a instanceof Array||"string"===typeof a)return b<a.length?a[b]:c;if(w(Ta,a))return C.a(a,b);if(a?a.j&64||a.jb||(a.j?0:w(Ua,a)):w(Ua,a))return Pc.c(a,b,c);throw Error([z("nth not supported on this type "),z(Da(Ba(a)))].join(""));}function b(a,b){if("number"!== -typeof b)throw Error("index argument to nth must be a number");if(null==a)return a;if(a&&(a.j&16||a.Qb))return a.Q(null,b);if(a instanceof Array||"string"===typeof a)return b<a.length?a[b]:null;if(w(Ta,a))return C.a(a,b);if(a?a.j&64||a.jb||(a.j?0:w(Ua,a)):w(Ua,a))return Pc.a(a,b);throw Error([z("nth not supported on this type "),z(Da(Ba(a)))].join(""));}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+ -arguments.length);};c.a=b;c.c=a;return c}(),S=function(){function a(a,b,c){return null!=a?a&&(a.j&256||a.Rb)?a.s(null,b,c):a instanceof Array?b<a.length?a[b]:c:"string"===typeof a?b<a.length?a[b]:c:w(Za,a)?$a.c(a,b,c):c:c}function b(a,b){return null==a?null:a&&(a.j&256||a.Rb)?a.t(null,b):a instanceof Array?b<a.length?a[b]:null:"string"===typeof a?b<a.length?a[b]:null:w(Za,a)?$a.a(a,b):null}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this, -c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}(),Rc=function(){function a(a,b,c){if(null!=a)a=cb(a,b,c);else a:{a=[b];c=[c];b=a.length;for(var g=0,h=Ob(Qc);;)if(g<b)var l=g+1,h=h.kb(null,a[g],c[g]),g=l;else{a=Qb(h);break a}a=void 0}return a}var b=null,c=function(){function a(b,d,h,l){var m=null;if(3<arguments.length){for(var m=0,p=Array(arguments.length-3);m<p.length;)p[m]=arguments[m+3],++m;m=new F(p,0)}return c.call(this,b,d,h,m)}function c(a,d,e,l){for(;;)if(a=b.c(a, -d,e),t(l))d=G(l),e=Lc(l),l=K(K(l));else return a}a.i=3;a.f=function(a){var b=G(a);a=K(a);var d=G(a);a=K(a);var l=G(a);a=H(a);return c(b,d,l,a)};a.d=c;return a}(),b=function(b,e,f,g){switch(arguments.length){case 3:return a.call(this,b,e,f);default:var h=null;if(3<arguments.length){for(var h=0,l=Array(arguments.length-3);h<l.length;)l[h]=arguments[h+3],++h;h=new F(l,0)}return c.d(b,e,f,h)}throw Error("Invalid arity: "+arguments.length);};b.i=3;b.f=c.f;b.c=a;b.d=c.d;return b}(),Sc=function(){function a(a, -b){return null==a?null:eb(a,b)}var b=null,c=function(){function a(b,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return c.call(this,b,d,l)}function c(a,d,e){for(;;){if(null==a)return null;a=b.a(a,d);if(t(e))d=G(e),e=K(e);else return a}}a.i=2;a.f=function(a){var b=G(a);a=K(a);var d=G(a);a=H(a);return c(b,d,a)};a.d=c;return a}(),b=function(b,e,f){switch(arguments.length){case 1:return b;case 2:return a.call(this,b,e); -default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.b=function(a){return a};b.a=a;b.d=c.d;return b}();function Tc(a){var b="function"==n(a);return t(b)?b:a?t(t(null)?null:a.bc)?!0:a.yb?!1:w(Ja,a):w(Ja,a)}function Uc(a,b){this.h=a;this.k=b;this.q=0;this.j=393217}k=Uc.prototype; -k.call=function(){function a(a,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N,Y,ra,I){a=this.h;return T.ub?T.ub(a,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N,Y,ra,I):T.call(null,a,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N,Y,ra,I)}function b(a,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N,Y,ra){a=this;return a.h.Fa?a.h.Fa(b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N,Y,ra):a.h.call(null,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N,Y,ra)}function c(a,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N,Y){a=this;return a.h.Ea?a.h.Ea(b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N, -Y):a.h.call(null,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N,Y)}function d(a,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N){a=this;return a.h.Da?a.h.Da(b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N):a.h.call(null,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E,N)}function e(a,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E){a=this;return a.h.Ca?a.h.Ca(b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E):a.h.call(null,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B,E)}function f(a,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B){a=this;return a.h.Ba?a.h.Ba(b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B):a.h.call(null, -b,c,d,e,f,g,h,l,m,p,q,u,s,v,y,B)}function g(a,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y){a=this;return a.h.Aa?a.h.Aa(b,c,d,e,f,g,h,l,m,p,q,u,s,v,y):a.h.call(null,b,c,d,e,f,g,h,l,m,p,q,u,s,v,y)}function h(a,b,c,d,e,f,g,h,l,m,p,q,u,s,v){a=this;return a.h.za?a.h.za(b,c,d,e,f,g,h,l,m,p,q,u,s,v):a.h.call(null,b,c,d,e,f,g,h,l,m,p,q,u,s,v)}function l(a,b,c,d,e,f,g,h,l,m,p,q,u,s){a=this;return a.h.ya?a.h.ya(b,c,d,e,f,g,h,l,m,p,q,u,s):a.h.call(null,b,c,d,e,f,g,h,l,m,p,q,u,s)}function m(a,b,c,d,e,f,g,h,l,m,p,q,u){a=this; -return a.h.xa?a.h.xa(b,c,d,e,f,g,h,l,m,p,q,u):a.h.call(null,b,c,d,e,f,g,h,l,m,p,q,u)}function p(a,b,c,d,e,f,g,h,l,m,p,q){a=this;return a.h.wa?a.h.wa(b,c,d,e,f,g,h,l,m,p,q):a.h.call(null,b,c,d,e,f,g,h,l,m,p,q)}function q(a,b,c,d,e,f,g,h,l,m,p){a=this;return a.h.va?a.h.va(b,c,d,e,f,g,h,l,m,p):a.h.call(null,b,c,d,e,f,g,h,l,m,p)}function s(a,b,c,d,e,f,g,h,l,m){a=this;return a.h.Ha?a.h.Ha(b,c,d,e,f,g,h,l,m):a.h.call(null,b,c,d,e,f,g,h,l,m)}function u(a,b,c,d,e,f,g,h,l){a=this;return a.h.Ga?a.h.Ga(b,c, -d,e,f,g,h,l):a.h.call(null,b,c,d,e,f,g,h,l)}function v(a,b,c,d,e,f,g,h){a=this;return a.h.ia?a.h.ia(b,c,d,e,f,g,h):a.h.call(null,b,c,d,e,f,g,h)}function y(a,b,c,d,e,f,g){a=this;return a.h.P?a.h.P(b,c,d,e,f,g):a.h.call(null,b,c,d,e,f,g)}function B(a,b,c,d,e,f){a=this;return a.h.r?a.h.r(b,c,d,e,f):a.h.call(null,b,c,d,e,f)}function E(a,b,c,d,e){a=this;return a.h.n?a.h.n(b,c,d,e):a.h.call(null,b,c,d,e)}function N(a,b,c,d){a=this;return a.h.c?a.h.c(b,c,d):a.h.call(null,b,c,d)}function Y(a,b,c){a=this; -return a.h.a?a.h.a(b,c):a.h.call(null,b,c)}function ra(a,b){a=this;return a.h.b?a.h.b(b):a.h.call(null,b)}function Pa(a){a=this;return a.h.l?a.h.l():a.h.call(null)}var I=null,I=function(I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob,Ab,Wb,jc,zc,Zc,Gd,De,Wf,dh){switch(arguments.length){case 1:return Pa.call(this,I);case 2:return ra.call(this,I,qa);case 3:return Y.call(this,I,qa,ta);case 4:return N.call(this,I,qa,ta,va);case 5:return E.call(this,I,qa,ta,va,xa);case 6:return B.call(this,I,qa,ta,va,xa,Ca);case 7:return y.call(this, -I,qa,ta,va,xa,Ca,Ga);case 8:return v.call(this,I,qa,ta,va,xa,Ca,Ga,Ka);case 9:return u.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa);case 10:return s.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa);case 11:return q.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya);case 12:return p.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb);case 13:return m.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob);case 14:return l.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob,Ab);case 15:return h.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb, -ob,Ab,Wb);case 16:return g.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob,Ab,Wb,jc);case 17:return f.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob,Ab,Wb,jc,zc);case 18:return e.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob,Ab,Wb,jc,zc,Zc);case 19:return d.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob,Ab,Wb,jc,zc,Zc,Gd);case 20:return c.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob,Ab,Wb,jc,zc,Zc,Gd,De);case 21:return b.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob,Ab,Wb,jc,zc,Zc,Gd,De, -Wf);case 22:return a.call(this,I,qa,ta,va,xa,Ca,Ga,Ka,Oa,Sa,Ya,gb,ob,Ab,Wb,jc,zc,Zc,Gd,De,Wf,dh)}throw Error("Invalid arity: "+arguments.length);};I.b=Pa;I.a=ra;I.c=Y;I.n=N;I.r=E;I.P=B;I.ia=y;I.Ga=v;I.Ha=u;I.va=s;I.wa=q;I.xa=p;I.ya=m;I.za=l;I.Aa=h;I.Ba=g;I.Ca=f;I.Da=e;I.Ea=d;I.Fa=c;I.hc=b;I.ub=a;return I}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.l=function(){return this.h.l?this.h.l():this.h.call(null)}; -k.b=function(a){return this.h.b?this.h.b(a):this.h.call(null,a)};k.a=function(a,b){return this.h.a?this.h.a(a,b):this.h.call(null,a,b)};k.c=function(a,b,c){return this.h.c?this.h.c(a,b,c):this.h.call(null,a,b,c)};k.n=function(a,b,c,d){return this.h.n?this.h.n(a,b,c,d):this.h.call(null,a,b,c,d)};k.r=function(a,b,c,d,e){return this.h.r?this.h.r(a,b,c,d,e):this.h.call(null,a,b,c,d,e)};k.P=function(a,b,c,d,e,f){return this.h.P?this.h.P(a,b,c,d,e,f):this.h.call(null,a,b,c,d,e,f)}; -k.ia=function(a,b,c,d,e,f,g){return this.h.ia?this.h.ia(a,b,c,d,e,f,g):this.h.call(null,a,b,c,d,e,f,g)};k.Ga=function(a,b,c,d,e,f,g,h){return this.h.Ga?this.h.Ga(a,b,c,d,e,f,g,h):this.h.call(null,a,b,c,d,e,f,g,h)};k.Ha=function(a,b,c,d,e,f,g,h,l){return this.h.Ha?this.h.Ha(a,b,c,d,e,f,g,h,l):this.h.call(null,a,b,c,d,e,f,g,h,l)};k.va=function(a,b,c,d,e,f,g,h,l,m){return this.h.va?this.h.va(a,b,c,d,e,f,g,h,l,m):this.h.call(null,a,b,c,d,e,f,g,h,l,m)}; -k.wa=function(a,b,c,d,e,f,g,h,l,m,p){return this.h.wa?this.h.wa(a,b,c,d,e,f,g,h,l,m,p):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p)};k.xa=function(a,b,c,d,e,f,g,h,l,m,p,q){return this.h.xa?this.h.xa(a,b,c,d,e,f,g,h,l,m,p,q):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p,q)};k.ya=function(a,b,c,d,e,f,g,h,l,m,p,q,s){return this.h.ya?this.h.ya(a,b,c,d,e,f,g,h,l,m,p,q,s):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p,q,s)}; -k.za=function(a,b,c,d,e,f,g,h,l,m,p,q,s,u){return this.h.za?this.h.za(a,b,c,d,e,f,g,h,l,m,p,q,s,u):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p,q,s,u)};k.Aa=function(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v){return this.h.Aa?this.h.Aa(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p,q,s,u,v)};k.Ba=function(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y){return this.h.Ba?this.h.Ba(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y)}; -k.Ca=function(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B){return this.h.Ca?this.h.Ca(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B)};k.Da=function(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E){return this.h.Da?this.h.Da(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E)}; -k.Ea=function(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N){return this.h.Ea?this.h.Ea(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N)};k.Fa=function(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y){return this.h.Fa?this.h.Fa(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y):this.h.call(null,a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y)}; -k.hc=function(a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y,ra){var Pa=this.h;return T.ub?T.ub(Pa,a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y,ra):T.call(null,Pa,a,b,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y,ra)};k.bc=!0;k.F=function(a,b){return new Uc(this.h,b)};k.H=function(){return this.k};function O(a,b){return Tc(a)&&!(a?a.j&262144||a.Bc||(a.j?0:w(tb,a)):w(tb,a))?new Uc(a,b):null==a?null:ub(a,b)}function Vc(a){var b=null!=a;return(b?a?a.j&131072||a.kc||(a.j?0:w(rb,a)):w(rb,a):b)?sb(a):null} -function Wc(a){return null==a?null:lb(a)} -var Xc=function(){function a(a,b){return null==a?null:kb(a,b)}var b=null,c=function(){function a(b,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return c.call(this,b,d,l)}function c(a,d,e){for(;;){if(null==a)return null;a=b.a(a,d);if(t(e))d=G(e),e=K(e);else return a}}a.i=2;a.f=function(a){var b=G(a);a=K(a);var d=G(a);a=H(a);return c(b,d,a)};a.d=c;return a}(),b=function(b,e,f){switch(arguments.length){case 1:return b;case 2:return a.call(this, -b,e);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.b=function(a){return a};b.a=a;b.d=c.d;return b}();function Yc(a){return null==a||Aa(D(a))}function $c(a){return null==a?!1:a?a.j&8||a.tc?!0:a.j?!1:w(Qa,a):w(Qa,a)}function ad(a){return null==a?!1:a?a.j&4096||a.zc?!0:a.j?!1:w(jb,a):w(jb,a)} -function bd(a){return a?a.j&512||a.rc?!0:a.j?!1:w(ab,a):w(ab,a)}function cd(a){return a?a.j&16777216||a.yc?!0:a.j?!1:w(Db,a):w(Db,a)}function dd(a){return null==a?!1:a?a.j&1024||a.ic?!0:a.j?!1:w(db,a):w(db,a)}function ed(a){return a?a.j&16384||a.Ac?!0:a.j?!1:w(nb,a):w(nb,a)}function fd(a){return a?a.q&512||a.sc?!0:!1:!1}function gd(a){var b=[];ea(a,function(a,b){return function(a,c){return b.push(c)}}(a,b));return b}function hd(a,b,c,d,e){for(;0!==e;)c[d]=a[b],d+=1,e-=1,b+=1} -function id(a,b,c,d,e){b+=e-1;for(d+=e-1;0!==e;)c[d]=a[b],d-=1,e-=1,b-=1}var jd={};function kd(a){return null==a?!1:a?a.j&64||a.jb?!0:a.j?!1:w(Ua,a):w(Ua,a)}function ld(a){return a?a.j&8388608||a.mc?!0:a.j?!1:w(Bb,a):w(Bb,a)}function md(a){return t(a)?!0:!1}function nd(a,b){return S.c(a,b,jd)===jd?!1:!0} -function od(a,b){if(a===b)return 0;if(null==a)return-1;if(null==b)return 1;if(Ba(a)===Ba(b))return a&&(a.q&2048||a.sb)?a.tb(null,b):ha(a,b);throw Error("compare on non-nil objects of different types");} -var pd=function(){function a(a,b,c,g){for(;;){var h=od(R.a(a,g),R.a(b,g));if(0===h&&g+1<c)g+=1;else return h}}function b(a,b){var f=Q(a),g=Q(b);return f<g?-1:f>g?1:c.n(a,b,f,0)}var c=null,c=function(c,e,f,g){switch(arguments.length){case 2:return b.call(this,c,e);case 4:return a.call(this,c,e,f,g)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.n=a;return c}(); -function qd(a){return sc.a(a,od)?od:function(b,c){var d=a.a?a.a(b,c):a.call(null,b,c);return"number"===typeof d?d:t(d)?-1:t(a.a?a.a(c,b):a.call(null,c,b))?1:0}} -var sd=function(){function a(a,b){if(D(b)){var c=rd.b?rd.b(b):rd.call(null,b),g=qd(a);ia(c,g);return D(c)}return J}function b(a){return c.a(od,a)}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),td=function(){function a(a,b,c){return sd.a(function(c,f){return qd(b).call(null,a.b?a.b(c):a.call(null,c),a.b?a.b(f):a.call(null,f))},c)}function b(a,b){return c.c(a,od, -b)}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}(),P=function(){function a(a,b,c){for(c=D(c);;)if(c){var g=G(c);b=a.a?a.a(b,g):a.call(null,b,g);if(Ac(b))return qb(b);c=K(c)}else return b}function b(a,b){var c=D(b);if(c){var g=G(c),c=K(c);return A.c?A.c(a,g,c):A.call(null,a,g,c)}return a.l?a.l():a.call(null)}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this, -c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}(),A=function(){function a(a,b,c){return c&&(c.j&524288||c.Sb)?c.O(null,a,b):c instanceof Array?Dc.c(c,a,b):"string"===typeof c?Dc.c(c,a,b):w(vb,c)?wb.c(c,a,b):P.c(a,b,c)}function b(a,b){return b&&(b.j&524288||b.Sb)?b.R(null,a):b instanceof Array?Dc.a(b,a):"string"===typeof b?Dc.a(b,a):w(vb,b)?wb.a(b,a):P.a(a,b)}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this, -c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}();function ud(a){return a} -var vd=function(){function a(a,b){return function(){function c(b,e){return a.a?a.a(b,e):a.call(null,b,e)}function g(a){return b.b?b.b(a):b.call(null,a)}function h(){return a.l?a.l():a.call(null)}var l=null,l=function(a,b){switch(arguments.length){case 0:return h.call(this);case 1:return g.call(this,a);case 2:return c.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};l.l=h;l.b=g;l.a=c;return l}()}function b(a){return c.a(a,ud)}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this, -c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),wd=function(){function a(a,b,c,g){a=a.b?a.b(b):a.call(null,b);c=A.c(a,c,g);return a.b?a.b(c):a.call(null,c)}function b(a,b,f){return c.n(a,b,b.l?b.l():b.call(null),f)}var c=null,c=function(c,e,f,g){switch(arguments.length){case 3:return b.call(this,c,e,f);case 4:return a.call(this,c,e,f,g)}throw Error("Invalid arity: "+arguments.length);};c.c=b;c.n=a;return c}(),xd=function(){var a=null,b=function(){function b(a, -c,g){var h=null;if(2<arguments.length){for(var h=0,l=Array(arguments.length-2);h<l.length;)l[h]=arguments[h+2],++h;h=new F(l,0)}return d.call(this,a,c,h)}function d(b,c,d){return A.c(a,b+c,d)}b.i=2;b.f=function(a){var b=G(a);a=K(a);var c=G(a);a=H(a);return d(b,c,a)};b.d=d;return b}(),a=function(a,d,e){switch(arguments.length){case 0:return 0;case 1:return a;case 2:return a+d;default:var f=null;if(2<arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+2],++f;f=new F(g, -0)}return b.d(a,d,f)}throw Error("Invalid arity: "+arguments.length);};a.i=2;a.f=b.f;a.l=function(){return 0};a.b=function(a){return a};a.a=function(a,b){return a+b};a.d=b.d;return a}(),yd=function(){var a=null,b=function(){function a(c,f,g){var h=null;if(2<arguments.length){for(var h=0,l=Array(arguments.length-2);h<l.length;)l[h]=arguments[h+2],++h;h=new F(l,0)}return b.call(this,c,f,h)}function b(a,c,d){for(;;)if(a<c)if(K(d))a=c,c=G(d),d=K(d);else return c<G(d);else return!1}a.i=2;a.f=function(a){var c= -G(a);a=K(a);var g=G(a);a=H(a);return b(c,g,a)};a.d=b;return a}(),a=function(a,d,e){switch(arguments.length){case 1:return!0;case 2:return a<d;default:var f=null;if(2<arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+2],++f;f=new F(g,0)}return b.d(a,d,f)}throw Error("Invalid arity: "+arguments.length);};a.i=2;a.f=b.f;a.b=function(){return!0};a.a=function(a,b){return a<b};a.d=b.d;return a}(),zd=function(){var a=null,b=function(){function a(c,f,g){var h=null;if(2< -arguments.length){for(var h=0,l=Array(arguments.length-2);h<l.length;)l[h]=arguments[h+2],++h;h=new F(l,0)}return b.call(this,c,f,h)}function b(a,c,d){for(;;)if(a<=c)if(K(d))a=c,c=G(d),d=K(d);else return c<=G(d);else return!1}a.i=2;a.f=function(a){var c=G(a);a=K(a);var g=G(a);a=H(a);return b(c,g,a)};a.d=b;return a}(),a=function(a,d,e){switch(arguments.length){case 1:return!0;case 2:return a<=d;default:var f=null;if(2<arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+ -2],++f;f=new F(g,0)}return b.d(a,d,f)}throw Error("Invalid arity: "+arguments.length);};a.i=2;a.f=b.f;a.b=function(){return!0};a.a=function(a,b){return a<=b};a.d=b.d;return a}(),Ad=function(){var a=null,b=function(){function a(c,f,g){var h=null;if(2<arguments.length){for(var h=0,l=Array(arguments.length-2);h<l.length;)l[h]=arguments[h+2],++h;h=new F(l,0)}return b.call(this,c,f,h)}function b(a,c,d){for(;;)if(a>c)if(K(d))a=c,c=G(d),d=K(d);else return c>G(d);else return!1}a.i=2;a.f=function(a){var c= -G(a);a=K(a);var g=G(a);a=H(a);return b(c,g,a)};a.d=b;return a}(),a=function(a,d,e){switch(arguments.length){case 1:return!0;case 2:return a>d;default:var f=null;if(2<arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+2],++f;f=new F(g,0)}return b.d(a,d,f)}throw Error("Invalid arity: "+arguments.length);};a.i=2;a.f=b.f;a.b=function(){return!0};a.a=function(a,b){return a>b};a.d=b.d;return a}(),Bd=function(){var a=null,b=function(){function a(c,f,g){var h=null;if(2< -arguments.length){for(var h=0,l=Array(arguments.length-2);h<l.length;)l[h]=arguments[h+2],++h;h=new F(l,0)}return b.call(this,c,f,h)}function b(a,c,d){for(;;)if(a>=c)if(K(d))a=c,c=G(d),d=K(d);else return c>=G(d);else return!1}a.i=2;a.f=function(a){var c=G(a);a=K(a);var g=G(a);a=H(a);return b(c,g,a)};a.d=b;return a}(),a=function(a,d,e){switch(arguments.length){case 1:return!0;case 2:return a>=d;default:var f=null;if(2<arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+ -2],++f;f=new F(g,0)}return b.d(a,d,f)}throw Error("Invalid arity: "+arguments.length);};a.i=2;a.f=b.f;a.b=function(){return!0};a.a=function(a,b){return a>=b};a.d=b.d;return a}();function Cd(a,b){var c=(a-a%b)/b;return 0<=c?Math.floor.b?Math.floor.b(c):Math.floor.call(null,c):Math.ceil.b?Math.ceil.b(c):Math.ceil.call(null,c)}function Dd(a){a-=a>>1&1431655765;a=(a&858993459)+(a>>2&858993459);return 16843009*(a+(a>>4)&252645135)>>24} -function Ed(a){var b=1;for(a=D(a);;)if(a&&0<b)b-=1,a=K(a);else return a} -var z=function(){function a(a){return null==a?"":da(a)}var b=null,c=function(){function a(b,d){var h=null;if(1<arguments.length){for(var h=0,l=Array(arguments.length-1);h<l.length;)l[h]=arguments[h+1],++h;h=new F(l,0)}return c.call(this,b,h)}function c(a,d){for(var e=new fa(b.b(a)),l=d;;)if(t(l))e=e.append(b.b(G(l))),l=K(l);else return e.toString()}a.i=1;a.f=function(a){var b=G(a);a=H(a);return c(b,a)};a.d=c;return a}(),b=function(b,e){switch(arguments.length){case 0:return"";case 1:return a.call(this, -b);default:var f=null;if(1<arguments.length){for(var f=0,g=Array(arguments.length-1);f<g.length;)g[f]=arguments[f+1],++f;f=new F(g,0)}return c.d(b,f)}throw Error("Invalid arity: "+arguments.length);};b.i=1;b.f=c.f;b.l=function(){return""};b.b=a;b.d=c.d;return b}();function Ic(a,b){var c;if(cd(b))if(Ec(a)&&Ec(b)&&Q(a)!==Q(b))c=!1;else a:{c=D(a);for(var d=D(b);;){if(null==c){c=null==d;break a}if(null!=d&&sc.a(G(c),G(d)))c=K(c),d=K(d);else{c=!1;break a}}c=void 0}else c=null;return md(c)} -function Fd(a,b,c,d,e){this.k=a;this.first=b;this.M=c;this.count=d;this.p=e;this.j=65937646;this.q=8192}k=Fd.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.k};k.T=function(){return 1===this.count?null:this.M};k.L=function(){return this.count};k.La=function(){return this.first};k.Ma=function(){return Wa(this)};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return ub(J,this.k)}; -k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){return this.first};k.S=function(){return 1===this.count?J:this.M};k.D=function(){return this};k.F=function(a,b){return new Fd(b,this.first,this.M,this.count,this.p)};k.G=function(a,b){return new Fd(this.k,b,this,this.count+1,null)};Fd.prototype[Ea]=function(){return uc(this)};function Hd(a){this.k=a;this.j=65937614;this.q=8192}k=Hd.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.k}; -k.T=function(){return null};k.L=function(){return 0};k.La=function(){return null};k.Ma=function(){throw Error("Can't pop empty list");};k.B=function(){return 0};k.A=function(a,b){return Ic(this,b)};k.J=function(){return this};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){return null};k.S=function(){return J};k.D=function(){return null};k.F=function(a,b){return new Hd(b)};k.G=function(a,b){return new Fd(this.k,b,null,1,null)};var J=new Hd(null); -Hd.prototype[Ea]=function(){return uc(this)};function Id(a){return a?a.j&134217728||a.xc?!0:a.j?!1:w(Fb,a):w(Fb,a)}function Jd(a){return Id(a)?Gb(a):A.c(Nc,J,a)} -var Kd=function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){var b;if(a instanceof F&&0===a.m)b=a.e;else a:{for(b=[];;)if(null!=a)b.push(a.N(null)),a=a.T(null);else break a;b=void 0}a=b.length;for(var e=J;;)if(0<a){var f=a-1,e=e.G(null,b[a-1]);a=f}else return e}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}(); -function Ld(a,b,c,d){this.k=a;this.first=b;this.M=c;this.p=d;this.j=65929452;this.q=8192}k=Ld.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.k};k.T=function(){return null==this.M?null:D(this.M)};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.k)};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){return this.first}; -k.S=function(){return null==this.M?J:this.M};k.D=function(){return this};k.F=function(a,b){return new Ld(b,this.first,this.M,this.p)};k.G=function(a,b){return new Ld(null,b,this,this.p)};Ld.prototype[Ea]=function(){return uc(this)};function M(a,b){var c=null==b;return(c?c:b&&(b.j&64||b.jb))?new Ld(null,a,b,null):new Ld(null,a,D(b),null)} -function Md(a,b){if(a.pa===b.pa)return 0;var c=Aa(a.ba);if(t(c?b.ba:c))return-1;if(t(a.ba)){if(Aa(b.ba))return 1;c=ha(a.ba,b.ba);return 0===c?ha(a.name,b.name):c}return ha(a.name,b.name)}function U(a,b,c,d){this.ba=a;this.name=b;this.pa=c;this.Ya=d;this.j=2153775105;this.q=4096}k=U.prototype;k.v=function(a,b){return Lb(b,[z(":"),z(this.pa)].join(""))};k.B=function(){var a=this.Ya;return null!=a?a:this.Ya=a=oc(this)+2654435769|0}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return S.a(c,this);case 3:return S.c(c,this,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return S.a(c,this)};a.c=function(a,c,d){return S.c(c,this,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return S.a(a,this)};k.a=function(a,b){return S.c(a,this,b)};k.A=function(a,b){return b instanceof U?this.pa===b.pa:!1}; -k.toString=function(){return[z(":"),z(this.pa)].join("")};function Nd(a,b){return a===b?!0:a instanceof U&&b instanceof U?a.pa===b.pa:!1} -var Pd=function(){function a(a,b){return new U(a,b,[z(t(a)?[z(a),z("/")].join(""):null),z(b)].join(""),null)}function b(a){if(a instanceof U)return a;if(a instanceof qc){var b;if(a&&(a.q&4096||a.lc))b=a.ba;else throw Error([z("Doesn't support namespace: "),z(a)].join(""));return new U(b,Od.b?Od.b(a):Od.call(null,a),a.ta,null)}return"string"===typeof a?(b=a.split("/"),2===b.length?new U(b[0],b[1],a,null):new U(null,b[0],a,null)):null}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this, -c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}();function V(a,b,c,d){this.k=a;this.cb=b;this.C=c;this.p=d;this.q=0;this.j=32374988}k=V.prototype;k.toString=function(){return ec(this)};function Qd(a){null!=a.cb&&(a.C=a.cb.l?a.cb.l():a.cb.call(null),a.cb=null);return a.C}k.H=function(){return this.k};k.T=function(){Cb(this);return null==this.C?null:K(this.C)};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)}; -k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.k)};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){Cb(this);return null==this.C?null:G(this.C)};k.S=function(){Cb(this);return null!=this.C?H(this.C):J};k.D=function(){Qd(this);if(null==this.C)return null;for(var a=this.C;;)if(a instanceof V)a=Qd(a);else return this.C=a,D(this.C)};k.F=function(a,b){return new V(b,this.cb,this.C,this.p)};k.G=function(a,b){return M(b,this)}; -V.prototype[Ea]=function(){return uc(this)};function Rd(a,b){this.Ab=a;this.end=b;this.q=0;this.j=2}Rd.prototype.L=function(){return this.end};Rd.prototype.add=function(a){this.Ab[this.end]=a;return this.end+=1};Rd.prototype.ca=function(){var a=new Sd(this.Ab,0,this.end);this.Ab=null;return a};function Td(a){return new Rd(Array(a),0)}function Sd(a,b,c){this.e=a;this.V=b;this.end=c;this.q=0;this.j=524306}k=Sd.prototype;k.R=function(a,b){return Dc.n(this.e,b,this.e[this.V],this.V+1)}; -k.O=function(a,b,c){return Dc.n(this.e,b,c,this.V)};k.Pb=function(){if(this.V===this.end)throw Error("-drop-first of empty chunk");return new Sd(this.e,this.V+1,this.end)};k.Q=function(a,b){return this.e[this.V+b]};k.$=function(a,b,c){return 0<=b&&b<this.end-this.V?this.e[this.V+b]:c};k.L=function(){return this.end-this.V}; -var Ud=function(){function a(a,b,c){return new Sd(a,b,c)}function b(a,b){return new Sd(a,b,a.length)}function c(a){return new Sd(a,0,a.length)}var d=null,d=function(d,f,g){switch(arguments.length){case 1:return c.call(this,d);case 2:return b.call(this,d,f);case 3:return a.call(this,d,f,g)}throw Error("Invalid arity: "+arguments.length);};d.b=c;d.a=b;d.c=a;return d}();function Vd(a,b,c,d){this.ca=a;this.ra=b;this.k=c;this.p=d;this.j=31850732;this.q=1536}k=Vd.prototype;k.toString=function(){return ec(this)}; -k.H=function(){return this.k};k.T=function(){if(1<Ma(this.ca))return new Vd(Xb(this.ca),this.ra,this.k,null);var a=Cb(this.ra);return null==a?null:a};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.k)};k.N=function(){return C.a(this.ca,0)};k.S=function(){return 1<Ma(this.ca)?new Vd(Xb(this.ca),this.ra,this.k,null):null==this.ra?J:this.ra};k.D=function(){return this};k.Cb=function(){return this.ca}; -k.Db=function(){return null==this.ra?J:this.ra};k.F=function(a,b){return new Vd(this.ca,this.ra,b,this.p)};k.G=function(a,b){return M(b,this)};k.Bb=function(){return null==this.ra?null:this.ra};Vd.prototype[Ea]=function(){return uc(this)};function Wd(a,b){return 0===Ma(a)?b:new Vd(a,b,null,null)}function Xd(a,b){a.add(b)}function rd(a){for(var b=[];;)if(D(a))b.push(G(a)),a=K(a);else return b}function Yd(a,b){if(Ec(a))return Q(a);for(var c=a,d=b,e=0;;)if(0<d&&D(c))c=K(c),d-=1,e+=1;else return e} -var $d=function Zd(b){return null==b?null:null==K(b)?D(G(b)):M(G(b),Zd(K(b)))},ae=function(){function a(a,b){return new V(null,function(){var c=D(a);return c?fd(c)?Wd(Yb(c),d.a(Zb(c),b)):M(G(c),d.a(H(c),b)):b},null,null)}function b(a){return new V(null,function(){return a},null,null)}function c(){return new V(null,function(){return null},null,null)}var d=null,e=function(){function a(c,d,e){var f=null;if(2<arguments.length){for(var f=0,q=Array(arguments.length-2);f<q.length;)q[f]=arguments[f+2],++f; -f=new F(q,0)}return b.call(this,c,d,f)}function b(a,c,e){return function q(a,b){return new V(null,function(){var c=D(a);return c?fd(c)?Wd(Yb(c),q(Zb(c),b)):M(G(c),q(H(c),b)):t(b)?q(G(b),K(b)):null},null,null)}(d.a(a,c),e)}a.i=2;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=H(a);return b(c,d,a)};a.d=b;return a}(),d=function(d,g,h){switch(arguments.length){case 0:return c.call(this);case 1:return b.call(this,d);case 2:return a.call(this,d,g);default:var l=null;if(2<arguments.length){for(var l=0,m= -Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return e.d(d,g,l)}throw Error("Invalid arity: "+arguments.length);};d.i=2;d.f=e.f;d.l=c;d.b=b;d.a=a;d.d=e.d;return d}(),be=function(){function a(a,b,c,d){return M(a,M(b,M(c,d)))}function b(a,b,c){return M(a,M(b,c))}var c=null,d=function(){function a(c,d,e,m,p){var q=null;if(4<arguments.length){for(var q=0,s=Array(arguments.length-4);q<s.length;)s[q]=arguments[q+4],++q;q=new F(s,0)}return b.call(this,c,d,e,m,q)}function b(a, -c,d,e,f){return M(a,M(c,M(d,M(e,$d(f)))))}a.i=4;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=K(a);var e=G(a);a=K(a);var p=G(a);a=H(a);return b(c,d,e,p,a)};a.d=b;return a}(),c=function(c,f,g,h,l){switch(arguments.length){case 1:return D(c);case 2:return M(c,f);case 3:return b.call(this,c,f,g);case 4:return a.call(this,c,f,g,h);default:var m=null;if(4<arguments.length){for(var m=0,p=Array(arguments.length-4);m<p.length;)p[m]=arguments[m+4],++m;m=new F(p,0)}return d.d(c,f,g,h,m)}throw Error("Invalid arity: "+ -arguments.length);};c.i=4;c.f=d.f;c.b=function(a){return D(a)};c.a=function(a,b){return M(a,b)};c.c=b;c.n=a;c.d=d.d;return c}();function ce(a){return Qb(a)} -var de=function(){function a(){return Ob(Mc)}var b=null,c=function(){function a(c,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return b.call(this,c,d,l)}function b(a,c,d){for(;;)if(a=Pb(a,c),t(d))c=G(d),d=K(d);else return a}a.i=2;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=H(a);return b(c,d,a)};a.d=b;return a}(),b=function(b,e,f){switch(arguments.length){case 0:return a.call(this);case 1:return b;case 2:return Pb(b, -e);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.l=a;b.b=function(a){return a};b.a=function(a,b){return Pb(a,b)};b.d=c.d;return b}(),ee=function(){var a=null,b=function(){function a(c,f,g,h){var l=null;if(3<arguments.length){for(var l=0,m=Array(arguments.length-3);l<m.length;)m[l]=arguments[l+3],++l;l=new F(m,0)}return b.call(this, -c,f,g,l)}function b(a,c,d,h){for(;;)if(a=Rb(a,c,d),t(h))c=G(h),d=Lc(h),h=K(K(h));else return a}a.i=3;a.f=function(a){var c=G(a);a=K(a);var g=G(a);a=K(a);var h=G(a);a=H(a);return b(c,g,h,a)};a.d=b;return a}(),a=function(a,d,e,f){switch(arguments.length){case 3:return Rb(a,d,e);default:var g=null;if(3<arguments.length){for(var g=0,h=Array(arguments.length-3);g<h.length;)h[g]=arguments[g+3],++g;g=new F(h,0)}return b.d(a,d,e,g)}throw Error("Invalid arity: "+arguments.length);};a.i=3;a.f=b.f;a.c=function(a, -b,e){return Rb(a,b,e)};a.d=b.d;return a}(),fe=function(){var a=null,b=function(){function a(c,f,g){var h=null;if(2<arguments.length){for(var h=0,l=Array(arguments.length-2);h<l.length;)l[h]=arguments[h+2],++h;h=new F(l,0)}return b.call(this,c,f,h)}function b(a,c,d){for(;;)if(a=Sb(a,c),t(d))c=G(d),d=K(d);else return a}a.i=2;a.f=function(a){var c=G(a);a=K(a);var g=G(a);a=H(a);return b(c,g,a)};a.d=b;return a}(),a=function(a,d,e){switch(arguments.length){case 2:return Sb(a,d);default:var f=null;if(2< -arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+2],++f;f=new F(g,0)}return b.d(a,d,f)}throw Error("Invalid arity: "+arguments.length);};a.i=2;a.f=b.f;a.a=function(a,b){return Sb(a,b)};a.d=b.d;return a}(),ge=function(){var a=null,b=function(){function a(c,f,g){var h=null;if(2<arguments.length){for(var h=0,l=Array(arguments.length-2);h<l.length;)l[h]=arguments[h+2],++h;h=new F(l,0)}return b.call(this,c,f,h)}function b(a,c,d){for(;;)if(a=Vb(a,c),t(d))c=G(d),d=K(d); -else return a}a.i=2;a.f=function(a){var c=G(a);a=K(a);var g=G(a);a=H(a);return b(c,g,a)};a.d=b;return a}(),a=function(a,d,e){switch(arguments.length){case 2:return Vb(a,d);default:var f=null;if(2<arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+2],++f;f=new F(g,0)}return b.d(a,d,f)}throw Error("Invalid arity: "+arguments.length);};a.i=2;a.f=b.f;a.a=function(a,b){return Vb(a,b)};a.d=b.d;return a}(); -function he(a,b,c){var d=D(c);if(0===b)return a.l?a.l():a.call(null);c=Va(d);var e=Wa(d);if(1===b)return a.b?a.b(c):a.b?a.b(c):a.call(null,c);var d=Va(e),f=Wa(e);if(2===b)return a.a?a.a(c,d):a.a?a.a(c,d):a.call(null,c,d);var e=Va(f),g=Wa(f);if(3===b)return a.c?a.c(c,d,e):a.c?a.c(c,d,e):a.call(null,c,d,e);var f=Va(g),h=Wa(g);if(4===b)return a.n?a.n(c,d,e,f):a.n?a.n(c,d,e,f):a.call(null,c,d,e,f);var g=Va(h),l=Wa(h);if(5===b)return a.r?a.r(c,d,e,f,g):a.r?a.r(c,d,e,f,g):a.call(null,c,d,e,f,g);var h=Va(l), -m=Wa(l);if(6===b)return a.P?a.P(c,d,e,f,g,h):a.P?a.P(c,d,e,f,g,h):a.call(null,c,d,e,f,g,h);var l=Va(m),p=Wa(m);if(7===b)return a.ia?a.ia(c,d,e,f,g,h,l):a.ia?a.ia(c,d,e,f,g,h,l):a.call(null,c,d,e,f,g,h,l);var m=Va(p),q=Wa(p);if(8===b)return a.Ga?a.Ga(c,d,e,f,g,h,l,m):a.Ga?a.Ga(c,d,e,f,g,h,l,m):a.call(null,c,d,e,f,g,h,l,m);var p=Va(q),s=Wa(q);if(9===b)return a.Ha?a.Ha(c,d,e,f,g,h,l,m,p):a.Ha?a.Ha(c,d,e,f,g,h,l,m,p):a.call(null,c,d,e,f,g,h,l,m,p);var q=Va(s),u=Wa(s);if(10===b)return a.va?a.va(c,d,e, -f,g,h,l,m,p,q):a.va?a.va(c,d,e,f,g,h,l,m,p,q):a.call(null,c,d,e,f,g,h,l,m,p,q);var s=Va(u),v=Wa(u);if(11===b)return a.wa?a.wa(c,d,e,f,g,h,l,m,p,q,s):a.wa?a.wa(c,d,e,f,g,h,l,m,p,q,s):a.call(null,c,d,e,f,g,h,l,m,p,q,s);var u=Va(v),y=Wa(v);if(12===b)return a.xa?a.xa(c,d,e,f,g,h,l,m,p,q,s,u):a.xa?a.xa(c,d,e,f,g,h,l,m,p,q,s,u):a.call(null,c,d,e,f,g,h,l,m,p,q,s,u);var v=Va(y),B=Wa(y);if(13===b)return a.ya?a.ya(c,d,e,f,g,h,l,m,p,q,s,u,v):a.ya?a.ya(c,d,e,f,g,h,l,m,p,q,s,u,v):a.call(null,c,d,e,f,g,h,l,m,p, -q,s,u,v);var y=Va(B),E=Wa(B);if(14===b)return a.za?a.za(c,d,e,f,g,h,l,m,p,q,s,u,v,y):a.za?a.za(c,d,e,f,g,h,l,m,p,q,s,u,v,y):a.call(null,c,d,e,f,g,h,l,m,p,q,s,u,v,y);var B=Va(E),N=Wa(E);if(15===b)return a.Aa?a.Aa(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B):a.Aa?a.Aa(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B):a.call(null,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B);var E=Va(N),Y=Wa(N);if(16===b)return a.Ba?a.Ba(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E):a.Ba?a.Ba(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E):a.call(null,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E);var N= -Va(Y),ra=Wa(Y);if(17===b)return a.Ca?a.Ca(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N):a.Ca?a.Ca(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N):a.call(null,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N);var Y=Va(ra),Pa=Wa(ra);if(18===b)return a.Da?a.Da(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y):a.Da?a.Da(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y):a.call(null,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y);ra=Va(Pa);Pa=Wa(Pa);if(19===b)return a.Ea?a.Ea(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y,ra):a.Ea?a.Ea(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y,ra):a.call(null, -c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y,ra);var I=Va(Pa);Wa(Pa);if(20===b)return a.Fa?a.Fa(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y,ra,I):a.Fa?a.Fa(c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y,ra,I):a.call(null,c,d,e,f,g,h,l,m,p,q,s,u,v,y,B,E,N,Y,ra,I);throw Error("Only up to 20 arguments supported on functions");} -var T=function(){function a(a,b,c,d,e){b=be.n(b,c,d,e);c=a.i;return a.f?(d=Yd(b,c+1),d<=c?he(a,d,b):a.f(b)):a.apply(a,rd(b))}function b(a,b,c,d){b=be.c(b,c,d);c=a.i;return a.f?(d=Yd(b,c+1),d<=c?he(a,d,b):a.f(b)):a.apply(a,rd(b))}function c(a,b,c){b=be.a(b,c);c=a.i;if(a.f){var d=Yd(b,c+1);return d<=c?he(a,d,b):a.f(b)}return a.apply(a,rd(b))}function d(a,b){var c=a.i;if(a.f){var d=Yd(b,c+1);return d<=c?he(a,d,b):a.f(b)}return a.apply(a,rd(b))}var e=null,f=function(){function a(c,d,e,f,g,u){var v=null; -if(5<arguments.length){for(var v=0,y=Array(arguments.length-5);v<y.length;)y[v]=arguments[v+5],++v;v=new F(y,0)}return b.call(this,c,d,e,f,g,v)}function b(a,c,d,e,f,g){c=M(c,M(d,M(e,M(f,$d(g)))));d=a.i;return a.f?(e=Yd(c,d+1),e<=d?he(a,e,c):a.f(c)):a.apply(a,rd(c))}a.i=5;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=K(a);var e=G(a);a=K(a);var f=G(a);a=K(a);var g=G(a);a=H(a);return b(c,d,e,f,g,a)};a.d=b;return a}(),e=function(e,h,l,m,p,q){switch(arguments.length){case 2:return d.call(this,e,h);case 3:return c.call(this, -e,h,l);case 4:return b.call(this,e,h,l,m);case 5:return a.call(this,e,h,l,m,p);default:var s=null;if(5<arguments.length){for(var s=0,u=Array(arguments.length-5);s<u.length;)u[s]=arguments[s+5],++s;s=new F(u,0)}return f.d(e,h,l,m,p,s)}throw Error("Invalid arity: "+arguments.length);};e.i=5;e.f=f.f;e.a=d;e.c=c;e.n=b;e.r=a;e.d=f.d;return e}(),ie=function(){function a(a,b,c,d,e,f){var g=O,v=Vc(a);b=b.r?b.r(v,c,d,e,f):b.call(null,v,c,d,e,f);return g(a,b)}function b(a,b,c,d,e){var f=O,g=Vc(a);b=b.n?b.n(g, -c,d,e):b.call(null,g,c,d,e);return f(a,b)}function c(a,b,c,d){var e=O,f=Vc(a);b=b.c?b.c(f,c,d):b.call(null,f,c,d);return e(a,b)}function d(a,b,c){var d=O,e=Vc(a);b=b.a?b.a(e,c):b.call(null,e,c);return d(a,b)}function e(a,b){var c=O,d;d=Vc(a);d=b.b?b.b(d):b.call(null,d);return c(a,d)}var f=null,g=function(){function a(c,d,e,f,g,h,y){var B=null;if(6<arguments.length){for(var B=0,E=Array(arguments.length-6);B<E.length;)E[B]=arguments[B+6],++B;B=new F(E,0)}return b.call(this,c,d,e,f,g,h,B)}function b(a, -c,d,e,f,g,h){return O(a,T.d(c,Vc(a),d,e,f,Kc([g,h],0)))}a.i=6;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=K(a);var e=G(a);a=K(a);var f=G(a);a=K(a);var g=G(a);a=K(a);var h=G(a);a=H(a);return b(c,d,e,f,g,h,a)};a.d=b;return a}(),f=function(f,l,m,p,q,s,u){switch(arguments.length){case 2:return e.call(this,f,l);case 3:return d.call(this,f,l,m);case 4:return c.call(this,f,l,m,p);case 5:return b.call(this,f,l,m,p,q);case 6:return a.call(this,f,l,m,p,q,s);default:var v=null;if(6<arguments.length){for(var v= -0,y=Array(arguments.length-6);v<y.length;)y[v]=arguments[v+6],++v;v=new F(y,0)}return g.d(f,l,m,p,q,s,v)}throw Error("Invalid arity: "+arguments.length);};f.i=6;f.f=g.f;f.a=e;f.c=d;f.n=c;f.r=b;f.P=a;f.d=g.d;return f}(),je=function(){function a(a,b){return!sc.a(a,b)}var b=null,c=function(){function a(c,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return b.call(this,c,d,l)}function b(a,c,d){return Aa(T.n(sc,a,c,d))}a.i= -2;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=H(a);return b(c,d,a)};a.d=b;return a}(),b=function(b,e,f){switch(arguments.length){case 1:return!1;case 2:return a.call(this,b,e);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.b=function(){return!1};b.a=a;b.d=c.d;return b}(),qe=function ke(){"undefined"===typeof ja&&(ja=function(b,c){this.pc= -b;this.oc=c;this.q=0;this.j=393216},ja.prototype.ga=function(){return!1},ja.prototype.next=function(){return Error("No such element")},ja.prototype.H=function(){return this.oc},ja.prototype.F=function(b,c){return new ja(this.pc,c)},ja.Yb=!0,ja.Xb="cljs.core/t12660",ja.nc=function(b){return Lb(b,"cljs.core/t12660")});return new ja(ke,new pa(null,5,[le,54,me,2998,ne,3,oe,2994,pe,"/Users/davidnolen/development/clojure/mori/out-mori-adv/cljs/core.cljs"],null))};function re(a,b){this.C=a;this.m=b} -re.prototype.ga=function(){return this.m<this.C.length};re.prototype.next=function(){var a=this.C.charAt(this.m);this.m+=1;return a};function se(a,b){this.e=a;this.m=b}se.prototype.ga=function(){return this.m<this.e.length};se.prototype.next=function(){var a=this.e[this.m];this.m+=1;return a};var te={},ue={};function ve(a,b){this.eb=a;this.Qa=b}ve.prototype.ga=function(){this.eb===te?(this.eb=ue,this.Qa=D(this.Qa)):this.eb===this.Qa&&(this.Qa=K(this.eb));return null!=this.Qa}; -ve.prototype.next=function(){if(Aa(this.ga()))throw Error("No such element");this.eb=this.Qa;return G(this.Qa)};function we(a){if(null==a)return qe();if("string"===typeof a)return new re(a,0);if(a instanceof Array)return new se(a,0);if(a?t(t(null)?null:a.vb)||(a.yb?0:w(bc,a)):w(bc,a))return cc(a);if(ld(a))return new ve(te,a);throw Error([z("Cannot create iterator from "),z(a)].join(""));}function xe(a,b){this.fa=a;this.$b=b} -xe.prototype.step=function(a){for(var b=this;;){if(t(function(){var c=null!=a.X;return c?b.$b.ga():c}()))if(Ac(function(){var c=b.$b.next();return b.fa.a?b.fa.a(a,c):b.fa.call(null,a,c)}()))null!=a.M&&(a.M.X=null);else continue;break}return null==a.X?null:b.fa.b?b.fa.b(a):b.fa.call(null,a)}; -function ye(a,b){var c=function(){function a(b,c){b.first=c;b.M=new ze(b.X,null,null,null);b.X=null;return b.M}function b(a){(Ac(a)?qb(a):a).X=null;return a}var c=null,c=function(c,f){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,f)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}();return new xe(a.b?a.b(c):a.call(null,c),b)}function Ae(a,b,c){this.fa=a;this.Kb=b;this.ac=c} -Ae.prototype.ga=function(){for(var a=D(this.Kb);;)if(null!=a){var b=G(a);if(Aa(b.ga()))return!1;a=K(a)}else return!0};Ae.prototype.next=function(){for(var a=this.Kb.length,b=0;;)if(b<a)this.ac[b]=this.Kb[b].next(),b+=1;else break;return Jc.a(this.ac,0)};Ae.prototype.step=function(a){for(;;){var b;b=(b=null!=a.X)?this.ga():b;if(t(b))if(Ac(T.a(this.fa,M(a,this.next()))))null!=a.M&&(a.M.X=null);else continue;break}return null==a.X?null:this.fa.b?this.fa.b(a):this.fa.call(null,a)}; -var Be=function(){function a(a,b,c){var g=function(){function a(b,c){b.first=c;b.M=new ze(b.X,null,null,null);b.X=null;return b.M}function b(a){a=Ac(a)?qb(a):a;a.X=null;return a}var c=null,c=function(c,d){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,d)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}();return new Ae(a.b?a.b(g):a.call(null,g),b,c)}function b(a,b){return c.c(a,b,Array(b.length))}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this, -c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}();function ze(a,b,c,d){this.X=a;this.first=b;this.M=c;this.k=d;this.q=0;this.j=31719628}k=ze.prototype;k.T=function(){null!=this.X&&Cb(this);return null==this.M?null:Cb(this.M)};k.N=function(){null!=this.X&&Cb(this);return null==this.M?null:this.first};k.S=function(){null!=this.X&&Cb(this);return null==this.M?J:this.M}; -k.D=function(){null!=this.X&&this.X.step(this);return null==this.M?null:this};k.B=function(){return wc(this)};k.A=function(a,b){return null!=Cb(this)?Ic(this,b):cd(b)&&null==D(b)};k.J=function(){return J};k.G=function(a,b){return M(b,Cb(this))};k.F=function(a,b){return new ze(this.X,this.first,this.M,b)};ze.prototype[Ea]=function(){return uc(this)}; -var Ce=function(){function a(a){return kd(a)?a:(a=D(a))?a:J}var b=null,c=function(){function a(c,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return b.call(this,c,d,l)}function b(a,c,d){d=rd(M(c,d));c=[];d=D(d);for(var e=null,m=0,p=0;;)if(p<m){var q=e.Q(null,p);c.push(we(q));p+=1}else if(d=D(d))e=d,fd(e)?(d=Yb(e),p=Zb(e),e=d,m=Q(d),d=p):(d=G(e),c.push(we(d)),d=K(e),e=null,m=0),p=0;else break;return new ze(Be.c(a,c, -Array(c.length)),null,null,null)}a.i=2;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=H(a);return b(c,d,a)};a.d=b;return a}(),b=function(b,e,f){switch(arguments.length){case 1:return a.call(this,b);case 2:return new ze(ye(b,we(e)),null,null,null);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.b=a;b.a=function(a,b){return new ze(ye(a, -we(b)),null,null,null)};b.d=c.d;return b}();function Ee(a,b){for(;;){if(null==D(b))return!0;var c;c=G(b);c=a.b?a.b(c):a.call(null,c);if(t(c)){c=a;var d=K(b);a=c;b=d}else return!1}}function Fe(a,b){for(;;)if(D(b)){var c;c=G(b);c=a.b?a.b(c):a.call(null,c);if(t(c))return c;c=a;var d=K(b);a=c;b=d}else return null}function Ge(a){if("number"===typeof a&&Aa(isNaN(a))&&Infinity!==a&&parseFloat(a)===parseInt(a,10))return 0===(a&1);throw Error([z("Argument must be an integer: "),z(a)].join(""));} -function He(a){return function(){function b(b,c){return Aa(a.a?a.a(b,c):a.call(null,b,c))}function c(b){return Aa(a.b?a.b(b):a.call(null,b))}function d(){return Aa(a.l?a.l():a.call(null))}var e=null,f=function(){function b(a,d,e){var f=null;if(2<arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+2],++f;f=new F(g,0)}return c.call(this,a,d,f)}function c(b,d,e){return Aa(T.n(a,b,d,e))}b.i=2;b.f=function(a){var b=G(a);a=K(a);var d=G(a);a=H(a);return c(b,d,a)};b.d=c; -return b}(),e=function(a,e,l){switch(arguments.length){case 0:return d.call(this);case 1:return c.call(this,a);case 2:return b.call(this,a,e);default:var m=null;if(2<arguments.length){for(var m=0,p=Array(arguments.length-2);m<p.length;)p[m]=arguments[m+2],++m;m=new F(p,0)}return f.d(a,e,m)}throw Error("Invalid arity: "+arguments.length);};e.i=2;e.f=f.f;e.l=d;e.b=c;e.a=b;e.d=f.d;return e}()} -var Ie=function(){function a(a,b,c){return function(){function d(h,l,m){h=c.c?c.c(h,l,m):c.call(null,h,l,m);h=b.b?b.b(h):b.call(null,h);return a.b?a.b(h):a.call(null,h)}function l(d,h){var l;l=c.a?c.a(d,h):c.call(null,d,h);l=b.b?b.b(l):b.call(null,l);return a.b?a.b(l):a.call(null,l)}function m(d){d=c.b?c.b(d):c.call(null,d);d=b.b?b.b(d):b.call(null,d);return a.b?a.b(d):a.call(null,d)}function p(){var d;d=c.l?c.l():c.call(null);d=b.b?b.b(d):b.call(null,d);return a.b?a.b(d):a.call(null,d)}var q=null, -s=function(){function d(a,b,c,e){var f=null;if(3<arguments.length){for(var f=0,g=Array(arguments.length-3);f<g.length;)g[f]=arguments[f+3],++f;f=new F(g,0)}return h.call(this,a,b,c,f)}function h(d,l,m,p){d=T.r(c,d,l,m,p);d=b.b?b.b(d):b.call(null,d);return a.b?a.b(d):a.call(null,d)}d.i=3;d.f=function(a){var b=G(a);a=K(a);var c=G(a);a=K(a);var d=G(a);a=H(a);return h(b,c,d,a)};d.d=h;return d}(),q=function(a,b,c,e){switch(arguments.length){case 0:return p.call(this);case 1:return m.call(this,a);case 2:return l.call(this, -a,b);case 3:return d.call(this,a,b,c);default:var f=null;if(3<arguments.length){for(var f=0,g=Array(arguments.length-3);f<g.length;)g[f]=arguments[f+3],++f;f=new F(g,0)}return s.d(a,b,c,f)}throw Error("Invalid arity: "+arguments.length);};q.i=3;q.f=s.f;q.l=p;q.b=m;q.a=l;q.c=d;q.d=s.d;return q}()}function b(a,b){return function(){function c(d,g,h){d=b.c?b.c(d,g,h):b.call(null,d,g,h);return a.b?a.b(d):a.call(null,d)}function d(c,g){var h=b.a?b.a(c,g):b.call(null,c,g);return a.b?a.b(h):a.call(null,h)} -function l(c){c=b.b?b.b(c):b.call(null,c);return a.b?a.b(c):a.call(null,c)}function m(){var c=b.l?b.l():b.call(null);return a.b?a.b(c):a.call(null,c)}var p=null,q=function(){function c(a,b,e,f){var g=null;if(3<arguments.length){for(var g=0,h=Array(arguments.length-3);g<h.length;)h[g]=arguments[g+3],++g;g=new F(h,0)}return d.call(this,a,b,e,g)}function d(c,g,h,l){c=T.r(b,c,g,h,l);return a.b?a.b(c):a.call(null,c)}c.i=3;c.f=function(a){var b=G(a);a=K(a);var c=G(a);a=K(a);var e=G(a);a=H(a);return d(b, -c,e,a)};c.d=d;return c}(),p=function(a,b,e,f){switch(arguments.length){case 0:return m.call(this);case 1:return l.call(this,a);case 2:return d.call(this,a,b);case 3:return c.call(this,a,b,e);default:var p=null;if(3<arguments.length){for(var p=0,E=Array(arguments.length-3);p<E.length;)E[p]=arguments[p+3],++p;p=new F(E,0)}return q.d(a,b,e,p)}throw Error("Invalid arity: "+arguments.length);};p.i=3;p.f=q.f;p.l=m;p.b=l;p.a=d;p.c=c;p.d=q.d;return p}()}var c=null,d=function(){function a(c,d,e,m){var p=null; -if(3<arguments.length){for(var p=0,q=Array(arguments.length-3);p<q.length;)q[p]=arguments[p+3],++p;p=new F(q,0)}return b.call(this,c,d,e,p)}function b(a,c,d,e){return function(a){return function(){function b(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return c.call(this,d)}function c(b){b=T.a(G(a),b);for(var d=K(a);;)if(d)b=G(d).call(null,b),d=K(d);else return b}b.i=0;b.f=function(a){a=D(a);return c(a)};b.d=c;return b}()}(Jd(be.n(a, -c,d,e)))}a.i=3;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=K(a);var e=G(a);a=H(a);return b(c,d,e,a)};a.d=b;return a}(),c=function(c,f,g,h){switch(arguments.length){case 0:return ud;case 1:return c;case 2:return b.call(this,c,f);case 3:return a.call(this,c,f,g);default:var l=null;if(3<arguments.length){for(var l=0,m=Array(arguments.length-3);l<m.length;)m[l]=arguments[l+3],++l;l=new F(m,0)}return d.d(c,f,g,l)}throw Error("Invalid arity: "+arguments.length);};c.i=3;c.f=d.f;c.l=function(){return ud}; -c.b=function(a){return a};c.a=b;c.c=a;c.d=d.d;return c}(),Je=function(){function a(a,b,c,d){return function(){function e(m,p,q){return a.P?a.P(b,c,d,m,p,q):a.call(null,b,c,d,m,p,q)}function p(e,m){return a.r?a.r(b,c,d,e,m):a.call(null,b,c,d,e,m)}function q(e){return a.n?a.n(b,c,d,e):a.call(null,b,c,d,e)}function s(){return a.c?a.c(b,c,d):a.call(null,b,c,d)}var u=null,v=function(){function e(a,b,c,d){var f=null;if(3<arguments.length){for(var f=0,g=Array(arguments.length-3);f<g.length;)g[f]=arguments[f+ -3],++f;f=new F(g,0)}return m.call(this,a,b,c,f)}function m(e,p,q,s){return T.d(a,b,c,d,e,Kc([p,q,s],0))}e.i=3;e.f=function(a){var b=G(a);a=K(a);var c=G(a);a=K(a);var d=G(a);a=H(a);return m(b,c,d,a)};e.d=m;return e}(),u=function(a,b,c,d){switch(arguments.length){case 0:return s.call(this);case 1:return q.call(this,a);case 2:return p.call(this,a,b);case 3:return e.call(this,a,b,c);default:var f=null;if(3<arguments.length){for(var f=0,g=Array(arguments.length-3);f<g.length;)g[f]=arguments[f+3],++f;f= -new F(g,0)}return v.d(a,b,c,f)}throw Error("Invalid arity: "+arguments.length);};u.i=3;u.f=v.f;u.l=s;u.b=q;u.a=p;u.c=e;u.d=v.d;return u}()}function b(a,b,c){return function(){function d(e,l,m){return a.r?a.r(b,c,e,l,m):a.call(null,b,c,e,l,m)}function e(d,l){return a.n?a.n(b,c,d,l):a.call(null,b,c,d,l)}function p(d){return a.c?a.c(b,c,d):a.call(null,b,c,d)}function q(){return a.a?a.a(b,c):a.call(null,b,c)}var s=null,u=function(){function d(a,b,c,f){var g=null;if(3<arguments.length){for(var g=0,h=Array(arguments.length- -3);g<h.length;)h[g]=arguments[g+3],++g;g=new F(h,0)}return e.call(this,a,b,c,g)}function e(d,l,m,p){return T.d(a,b,c,d,l,Kc([m,p],0))}d.i=3;d.f=function(a){var b=G(a);a=K(a);var c=G(a);a=K(a);var d=G(a);a=H(a);return e(b,c,d,a)};d.d=e;return d}(),s=function(a,b,c,f){switch(arguments.length){case 0:return q.call(this);case 1:return p.call(this,a);case 2:return e.call(this,a,b);case 3:return d.call(this,a,b,c);default:var g=null;if(3<arguments.length){for(var g=0,h=Array(arguments.length-3);g<h.length;)h[g]= -arguments[g+3],++g;g=new F(h,0)}return u.d(a,b,c,g)}throw Error("Invalid arity: "+arguments.length);};s.i=3;s.f=u.f;s.l=q;s.b=p;s.a=e;s.c=d;s.d=u.d;return s}()}function c(a,b){return function(){function c(d,e,h){return a.n?a.n(b,d,e,h):a.call(null,b,d,e,h)}function d(c,e){return a.c?a.c(b,c,e):a.call(null,b,c,e)}function e(c){return a.a?a.a(b,c):a.call(null,b,c)}function p(){return a.b?a.b(b):a.call(null,b)}var q=null,s=function(){function c(a,b,e,f){var g=null;if(3<arguments.length){for(var g=0, -h=Array(arguments.length-3);g<h.length;)h[g]=arguments[g+3],++g;g=new F(h,0)}return d.call(this,a,b,e,g)}function d(c,e,h,l){return T.d(a,b,c,e,h,Kc([l],0))}c.i=3;c.f=function(a){var b=G(a);a=K(a);var c=G(a);a=K(a);var e=G(a);a=H(a);return d(b,c,e,a)};c.d=d;return c}(),q=function(a,b,f,g){switch(arguments.length){case 0:return p.call(this);case 1:return e.call(this,a);case 2:return d.call(this,a,b);case 3:return c.call(this,a,b,f);default:var q=null;if(3<arguments.length){for(var q=0,N=Array(arguments.length- -3);q<N.length;)N[q]=arguments[q+3],++q;q=new F(N,0)}return s.d(a,b,f,q)}throw Error("Invalid arity: "+arguments.length);};q.i=3;q.f=s.f;q.l=p;q.b=e;q.a=d;q.c=c;q.d=s.d;return q}()}var d=null,e=function(){function a(c,d,e,f,q){var s=null;if(4<arguments.length){for(var s=0,u=Array(arguments.length-4);s<u.length;)u[s]=arguments[s+4],++s;s=new F(u,0)}return b.call(this,c,d,e,f,s)}function b(a,c,d,e,f){return function(){function b(a){var c=null;if(0<arguments.length){for(var c=0,d=Array(arguments.length- -0);c<d.length;)d[c]=arguments[c+0],++c;c=new F(d,0)}return g.call(this,c)}function g(b){return T.r(a,c,d,e,ae.a(f,b))}b.i=0;b.f=function(a){a=D(a);return g(a)};b.d=g;return b}()}a.i=4;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=K(a);var e=G(a);a=K(a);var f=G(a);a=H(a);return b(c,d,e,f,a)};a.d=b;return a}(),d=function(d,g,h,l,m){switch(arguments.length){case 1:return d;case 2:return c.call(this,d,g);case 3:return b.call(this,d,g,h);case 4:return a.call(this,d,g,h,l);default:var p=null;if(4<arguments.length){for(var p= -0,q=Array(arguments.length-4);p<q.length;)q[p]=arguments[p+4],++p;p=new F(q,0)}return e.d(d,g,h,l,p)}throw Error("Invalid arity: "+arguments.length);};d.i=4;d.f=e.f;d.b=function(a){return a};d.a=c;d.c=b;d.n=a;d.d=e.d;return d}(),Ke=function(){function a(a,b,c,d){return function(){function l(l,m,p){l=null==l?b:l;m=null==m?c:m;p=null==p?d:p;return a.c?a.c(l,m,p):a.call(null,l,m,p)}function m(d,h){var l=null==d?b:d,m=null==h?c:h;return a.a?a.a(l,m):a.call(null,l,m)}var p=null,q=function(){function l(a, -b,c,d){var e=null;if(3<arguments.length){for(var e=0,f=Array(arguments.length-3);e<f.length;)f[e]=arguments[e+3],++e;e=new F(f,0)}return m.call(this,a,b,c,e)}function m(l,p,q,s){return T.r(a,null==l?b:l,null==p?c:p,null==q?d:q,s)}l.i=3;l.f=function(a){var b=G(a);a=K(a);var c=G(a);a=K(a);var d=G(a);a=H(a);return m(b,c,d,a)};l.d=m;return l}(),p=function(a,b,c,d){switch(arguments.length){case 2:return m.call(this,a,b);case 3:return l.call(this,a,b,c);default:var e=null;if(3<arguments.length){for(var e= -0,f=Array(arguments.length-3);e<f.length;)f[e]=arguments[e+3],++e;e=new F(f,0)}return q.d(a,b,c,e)}throw Error("Invalid arity: "+arguments.length);};p.i=3;p.f=q.f;p.a=m;p.c=l;p.d=q.d;return p}()}function b(a,b,c){return function(){function d(h,l,m){h=null==h?b:h;l=null==l?c:l;return a.c?a.c(h,l,m):a.call(null,h,l,m)}function l(d,h){var l=null==d?b:d,m=null==h?c:h;return a.a?a.a(l,m):a.call(null,l,m)}var m=null,p=function(){function d(a,b,c,e){var f=null;if(3<arguments.length){for(var f=0,g=Array(arguments.length- -3);f<g.length;)g[f]=arguments[f+3],++f;f=new F(g,0)}return h.call(this,a,b,c,f)}function h(d,l,m,p){return T.r(a,null==d?b:d,null==l?c:l,m,p)}d.i=3;d.f=function(a){var b=G(a);a=K(a);var c=G(a);a=K(a);var d=G(a);a=H(a);return h(b,c,d,a)};d.d=h;return d}(),m=function(a,b,c,e){switch(arguments.length){case 2:return l.call(this,a,b);case 3:return d.call(this,a,b,c);default:var f=null;if(3<arguments.length){for(var f=0,g=Array(arguments.length-3);f<g.length;)g[f]=arguments[f+3],++f;f=new F(g,0)}return p.d(a, -b,c,f)}throw Error("Invalid arity: "+arguments.length);};m.i=3;m.f=p.f;m.a=l;m.c=d;m.d=p.d;return m}()}function c(a,b){return function(){function c(d,g,h){d=null==d?b:d;return a.c?a.c(d,g,h):a.call(null,d,g,h)}function d(c,g){var h=null==c?b:c;return a.a?a.a(h,g):a.call(null,h,g)}function l(c){c=null==c?b:c;return a.b?a.b(c):a.call(null,c)}var m=null,p=function(){function c(a,b,e,f){var g=null;if(3<arguments.length){for(var g=0,h=Array(arguments.length-3);g<h.length;)h[g]=arguments[g+3],++g;g=new F(h, -0)}return d.call(this,a,b,e,g)}function d(c,g,h,l){return T.r(a,null==c?b:c,g,h,l)}c.i=3;c.f=function(a){var b=G(a);a=K(a);var c=G(a);a=K(a);var e=G(a);a=H(a);return d(b,c,e,a)};c.d=d;return c}(),m=function(a,b,e,f){switch(arguments.length){case 1:return l.call(this,a);case 2:return d.call(this,a,b);case 3:return c.call(this,a,b,e);default:var m=null;if(3<arguments.length){for(var m=0,B=Array(arguments.length-3);m<B.length;)B[m]=arguments[m+3],++m;m=new F(B,0)}return p.d(a,b,e,m)}throw Error("Invalid arity: "+ -arguments.length);};m.i=3;m.f=p.f;m.b=l;m.a=d;m.c=c;m.d=p.d;return m}()}var d=null,d=function(d,f,g,h){switch(arguments.length){case 2:return c.call(this,d,f);case 3:return b.call(this,d,f,g);case 4:return a.call(this,d,f,g,h)}throw Error("Invalid arity: "+arguments.length);};d.a=c;d.c=b;d.n=a;return d}(),Le=function(){function a(a,b){return new V(null,function(){var f=D(b);if(f){if(fd(f)){for(var g=Yb(f),h=Q(g),l=Td(h),m=0;;)if(m<h){var p=function(){var b=C.a(g,m);return a.b?a.b(b):a.call(null,b)}(); -null!=p&&l.add(p);m+=1}else break;return Wd(l.ca(),c.a(a,Zb(f)))}h=function(){var b=G(f);return a.b?a.b(b):a.call(null,b)}();return null==h?c.a(a,H(f)):M(h,c.a(a,H(f)))}return null},null,null)}function b(a){return function(b){return function(){function c(f,g){var h=a.b?a.b(g):a.call(null,g);return null==h?f:b.a?b.a(f,h):b.call(null,f,h)}function g(a){return b.b?b.b(a):b.call(null,a)}function h(){return b.l?b.l():b.call(null)}var l=null,l=function(a,b){switch(arguments.length){case 0:return h.call(this); -case 1:return g.call(this,a);case 2:return c.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};l.l=h;l.b=g;l.a=c;return l}()}}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}();function Me(a){this.state=a;this.q=0;this.j=32768}Me.prototype.Ra=function(){return this.state};Me.prototype.bb=function(a,b){return this.state=b}; -var Ne=function(){function a(a,b){return function g(b,c){return new V(null,function(){var e=D(c);if(e){if(fd(e)){for(var p=Yb(e),q=Q(p),s=Td(q),u=0;;)if(u<q){var v=function(){var c=b+u,e=C.a(p,u);return a.a?a.a(c,e):a.call(null,c,e)}();null!=v&&s.add(v);u+=1}else break;return Wd(s.ca(),g(b+q,Zb(e)))}q=function(){var c=G(e);return a.a?a.a(b,c):a.call(null,b,c)}();return null==q?g(b+1,H(e)):M(q,g(b+1,H(e)))}return null},null,null)}(0,b)}function b(a){return function(b){return function(c){return function(){function g(g, -h){var l=c.bb(0,c.Ra(null)+1),l=a.a?a.a(l,h):a.call(null,l,h);return null==l?g:b.a?b.a(g,l):b.call(null,g,l)}function h(a){return b.b?b.b(a):b.call(null,a)}function l(){return b.l?b.l():b.call(null)}var m=null,m=function(a,b){switch(arguments.length){case 0:return l.call(this);case 1:return h.call(this,a);case 2:return g.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};m.l=l;m.b=h;m.a=g;return m}()}(new Me(-1))}}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this, -c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),Oe=function(){function a(a,b,c,d){return new V(null,function(){var f=D(b),q=D(c),s=D(d);if(f&&q&&s){var u=M,v;v=G(f);var y=G(q),B=G(s);v=a.c?a.c(v,y,B):a.call(null,v,y,B);f=u(v,e.n(a,H(f),H(q),H(s)))}else f=null;return f},null,null)}function b(a,b,c){return new V(null,function(){var d=D(b),f=D(c);if(d&&f){var q=M,s;s=G(d);var u=G(f);s=a.a?a.a(s,u):a.call(null,s,u);d=q(s,e.c(a,H(d),H(f)))}else d= -null;return d},null,null)}function c(a,b){return new V(null,function(){var c=D(b);if(c){if(fd(c)){for(var d=Yb(c),f=Q(d),q=Td(f),s=0;;)if(s<f)Xd(q,function(){var b=C.a(d,s);return a.b?a.b(b):a.call(null,b)}()),s+=1;else break;return Wd(q.ca(),e.a(a,Zb(c)))}return M(function(){var b=G(c);return a.b?a.b(b):a.call(null,b)}(),e.a(a,H(c)))}return null},null,null)}function d(a){return function(b){return function(){function c(d,e){var f=a.b?a.b(e):a.call(null,e);return b.a?b.a(d,f):b.call(null,d,f)}function d(a){return b.b? -b.b(a):b.call(null,a)}function e(){return b.l?b.l():b.call(null)}var f=null,s=function(){function c(a,b,e){var f=null;if(2<arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+2],++f;f=new F(g,0)}return d.call(this,a,b,f)}function d(c,e,f){e=T.c(a,e,f);return b.a?b.a(c,e):b.call(null,c,e)}c.i=2;c.f=function(a){var b=G(a);a=K(a);var c=G(a);a=H(a);return d(b,c,a)};c.d=d;return c}(),f=function(a,b,f){switch(arguments.length){case 0:return e.call(this);case 1:return d.call(this, -a);case 2:return c.call(this,a,b);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return s.d(a,b,g)}throw Error("Invalid arity: "+arguments.length);};f.i=2;f.f=s.f;f.l=e;f.b=d;f.a=c;f.d=s.d;return f}()}}var e=null,f=function(){function a(c,d,e,f,g){var u=null;if(4<arguments.length){for(var u=0,v=Array(arguments.length-4);u<v.length;)v[u]=arguments[u+4],++u;u=new F(v,0)}return b.call(this,c,d,e,f,u)}function b(a,c,d, -f,g){var h=function y(a){return new V(null,function(){var b=e.a(D,a);return Ee(ud,b)?M(e.a(G,b),y(e.a(H,b))):null},null,null)};return e.a(function(){return function(b){return T.a(a,b)}}(h),h(Nc.d(g,f,Kc([d,c],0))))}a.i=4;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=K(a);var e=G(a);a=K(a);var f=G(a);a=H(a);return b(c,d,e,f,a)};a.d=b;return a}(),e=function(e,h,l,m,p){switch(arguments.length){case 1:return d.call(this,e);case 2:return c.call(this,e,h);case 3:return b.call(this,e,h,l);case 4:return a.call(this, -e,h,l,m);default:var q=null;if(4<arguments.length){for(var q=0,s=Array(arguments.length-4);q<s.length;)s[q]=arguments[q+4],++q;q=new F(s,0)}return f.d(e,h,l,m,q)}throw Error("Invalid arity: "+arguments.length);};e.i=4;e.f=f.f;e.b=d;e.a=c;e.c=b;e.n=a;e.d=f.d;return e}(),Pe=function(){function a(a,b){return new V(null,function(){if(0<a){var f=D(b);return f?M(G(f),c.a(a-1,H(f))):null}return null},null,null)}function b(a){return function(b){return function(a){return function(){function c(d,g){var h=qb(a), -l=a.bb(0,a.Ra(null)-1),h=0<h?b.a?b.a(d,g):b.call(null,d,g):d;return 0<l?h:Ac(h)?h:new yc(h)}function d(a){return b.b?b.b(a):b.call(null,a)}function l(){return b.l?b.l():b.call(null)}var m=null,m=function(a,b){switch(arguments.length){case 0:return l.call(this);case 1:return d.call(this,a);case 2:return c.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};m.l=l;m.b=d;m.a=c;return m}()}(new Me(a))}}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this, -c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),Qe=function(){function a(a,b){return new V(null,function(c){return function(){return c(a,b)}}(function(a,b){for(;;){var c=D(b);if(0<a&&c){var d=a-1,c=H(c);a=d;b=c}else return c}}),null,null)}function b(a){return function(b){return function(a){return function(){function c(d,g){var h=qb(a);a.bb(0,a.Ra(null)-1);return 0<h?d:b.a?b.a(d,g):b.call(null,d,g)}function d(a){return b.b?b.b(a):b.call(null,a)}function l(){return b.l? -b.l():b.call(null)}var m=null,m=function(a,b){switch(arguments.length){case 0:return l.call(this);case 1:return d.call(this,a);case 2:return c.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};m.l=l;m.b=d;m.a=c;return m}()}(new Me(a))}}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),Re=function(){function a(a,b){return new V(null,function(c){return function(){return c(a, -b)}}(function(a,b){for(;;){var c=D(b),d;if(d=c)d=G(c),d=a.b?a.b(d):a.call(null,d);if(t(d))d=a,c=H(c),a=d,b=c;else return c}}),null,null)}function b(a){return function(b){return function(c){return function(){function g(g,h){var l=qb(c);if(t(t(l)?a.b?a.b(h):a.call(null,h):l))return g;ac(c,null);return b.a?b.a(g,h):b.call(null,g,h)}function h(a){return b.b?b.b(a):b.call(null,a)}function l(){return b.l?b.l():b.call(null)}var m=null,m=function(a,b){switch(arguments.length){case 0:return l.call(this);case 1:return h.call(this, -a);case 2:return g.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};m.l=l;m.b=h;m.a=g;return m}()}(new Me(!0))}}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),Se=function(){function a(a,b){return Pe.a(a,c.b(b))}function b(a){return new V(null,function(){return M(a,c.b(a))},null,null)}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this, -c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),Te=function(){function a(a,b){return Pe.a(a,c.b(b))}function b(a){return new V(null,function(){return M(a.l?a.l():a.call(null),c.b(a))},null,null)}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),Ue=function(){function a(a,c){return new V(null,function(){var f= -D(a),g=D(c);return f&&g?M(G(f),M(G(g),b.a(H(f),H(g)))):null},null,null)}var b=null,c=function(){function a(b,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return c.call(this,b,d,l)}function c(a,d,e){return new V(null,function(){var c=Oe.a(D,Nc.d(e,d,Kc([a],0)));return Ee(ud,c)?ae.a(Oe.a(G,c),T.a(b,Oe.a(H,c))):null},null,null)}a.i=2;a.f=function(a){var b=G(a);a=K(a);var d=G(a);a=H(a);return c(b,d,a)};a.d=c;return a}(), -b=function(b,e,f){switch(arguments.length){case 2:return a.call(this,b,e);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.a=a;b.d=c.d;return b}(),We=function(){function a(a){return Ie.a(Oe.b(a),Ve)}var b=null,c=function(){function a(c,d){var h=null;if(1<arguments.length){for(var h=0,l=Array(arguments.length-1);h<l.length;)l[h]=arguments[h+ -1],++h;h=new F(l,0)}return b.call(this,c,h)}function b(a,c){return T.a(ae,T.c(Oe,a,c))}a.i=1;a.f=function(a){var c=G(a);a=H(a);return b(c,a)};a.d=b;return a}(),b=function(b,e){switch(arguments.length){case 1:return a.call(this,b);default:var f=null;if(1<arguments.length){for(var f=0,g=Array(arguments.length-1);f<g.length;)g[f]=arguments[f+1],++f;f=new F(g,0)}return c.d(b,f)}throw Error("Invalid arity: "+arguments.length);};b.i=1;b.f=c.f;b.b=a;b.d=c.d;return b}(),Xe=function(){function a(a,b){return new V(null, -function(){var f=D(b);if(f){if(fd(f)){for(var g=Yb(f),h=Q(g),l=Td(h),m=0;;)if(m<h){var p;p=C.a(g,m);p=a.b?a.b(p):a.call(null,p);t(p)&&(p=C.a(g,m),l.add(p));m+=1}else break;return Wd(l.ca(),c.a(a,Zb(f)))}g=G(f);f=H(f);return t(a.b?a.b(g):a.call(null,g))?M(g,c.a(a,f)):c.a(a,f)}return null},null,null)}function b(a){return function(b){return function(){function c(f,g){return t(a.b?a.b(g):a.call(null,g))?b.a?b.a(f,g):b.call(null,f,g):f}function g(a){return b.b?b.b(a):b.call(null,a)}function h(){return b.l? -b.l():b.call(null)}var l=null,l=function(a,b){switch(arguments.length){case 0:return h.call(this);case 1:return g.call(this,a);case 2:return c.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};l.l=h;l.b=g;l.a=c;return l}()}}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),Ye=function(){function a(a,b){return Xe.a(He(a),b)}function b(a){return Xe.b(He(a))} -var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}();function Ze(a){var b=$e;return function d(a){return new V(null,function(){return M(a,t(b.b?b.b(a):b.call(null,a))?We.d(d,Kc([D.b?D.b(a):D.call(null,a)],0)):null)},null,null)}(a)} -var af=function(){function a(a,b,c){return a&&(a.q&4||a.dc)?O(ce(wd.n(b,de,Ob(a),c)),Vc(a)):wd.n(b,Nc,a,c)}function b(a,b){return null!=a?a&&(a.q&4||a.dc)?O(ce(A.c(Pb,Ob(a),b)),Vc(a)):A.c(Ra,a,b):A.c(Nc,J,b)}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}(),bf=function(){function a(a,b,c,h){return new V(null,function(){var l=D(h);if(l){var m=Pe.a(a,l);return a=== -Q(m)?M(m,d.n(a,b,c,Qe.a(b,l))):Ra(J,Pe.a(a,ae.a(m,c)))}return null},null,null)}function b(a,b,c){return new V(null,function(){var h=D(c);if(h){var l=Pe.a(a,h);return a===Q(l)?M(l,d.c(a,b,Qe.a(b,h))):null}return null},null,null)}function c(a,b){return d.c(a,a,b)}var d=null,d=function(d,f,g,h){switch(arguments.length){case 2:return c.call(this,d,f);case 3:return b.call(this,d,f,g);case 4:return a.call(this,d,f,g,h)}throw Error("Invalid arity: "+arguments.length);};d.a=c;d.c=b;d.n=a;return d}(),cf=function(){function a(a, -b,c){var g=jd;for(b=D(b);;)if(b){var h=a;if(h?h.j&256||h.Rb||(h.j?0:w(Za,h)):w(Za,h)){a=S.c(a,G(b),g);if(g===a)return c;b=K(b)}else return c}else return a}function b(a,b){return c.c(a,b,null)}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}(),df=function(){function a(a,b,c,d,f,q){var s=R.c(b,0,null);return(b=Ed(b))?Rc.c(a,s,e.P(S.a(a,s),b,c,d,f,q)):Rc.c(a,s, -function(){var b=S.a(a,s);return c.n?c.n(b,d,f,q):c.call(null,b,d,f,q)}())}function b(a,b,c,d,f){var q=R.c(b,0,null);return(b=Ed(b))?Rc.c(a,q,e.r(S.a(a,q),b,c,d,f)):Rc.c(a,q,function(){var b=S.a(a,q);return c.c?c.c(b,d,f):c.call(null,b,d,f)}())}function c(a,b,c,d){var f=R.c(b,0,null);return(b=Ed(b))?Rc.c(a,f,e.n(S.a(a,f),b,c,d)):Rc.c(a,f,function(){var b=S.a(a,f);return c.a?c.a(b,d):c.call(null,b,d)}())}function d(a,b,c){var d=R.c(b,0,null);return(b=Ed(b))?Rc.c(a,d,e.c(S.a(a,d),b,c)):Rc.c(a,d,function(){var b= -S.a(a,d);return c.b?c.b(b):c.call(null,b)}())}var e=null,f=function(){function a(c,d,e,f,g,u,v){var y=null;if(6<arguments.length){for(var y=0,B=Array(arguments.length-6);y<B.length;)B[y]=arguments[y+6],++y;y=new F(B,0)}return b.call(this,c,d,e,f,g,u,y)}function b(a,c,d,f,g,h,v){var y=R.c(c,0,null);return(c=Ed(c))?Rc.c(a,y,T.d(e,S.a(a,y),c,d,f,Kc([g,h,v],0))):Rc.c(a,y,T.d(d,S.a(a,y),f,g,h,Kc([v],0)))}a.i=6;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=K(a);var e=G(a);a=K(a);var f=G(a);a=K(a);var g= -G(a);a=K(a);var v=G(a);a=H(a);return b(c,d,e,f,g,v,a)};a.d=b;return a}(),e=function(e,h,l,m,p,q,s){switch(arguments.length){case 3:return d.call(this,e,h,l);case 4:return c.call(this,e,h,l,m);case 5:return b.call(this,e,h,l,m,p);case 6:return a.call(this,e,h,l,m,p,q);default:var u=null;if(6<arguments.length){for(var u=0,v=Array(arguments.length-6);u<v.length;)v[u]=arguments[u+6],++u;u=new F(v,0)}return f.d(e,h,l,m,p,q,u)}throw Error("Invalid arity: "+arguments.length);};e.i=6;e.f=f.f;e.c=d;e.n=c; -e.r=b;e.P=a;e.d=f.d;return e}();function ef(a,b){this.u=a;this.e=b}function ff(a){return new ef(a,[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null])}function gf(a){return new ef(a.u,Fa(a.e))}function hf(a){a=a.g;return 32>a?0:a-1>>>5<<5}function jf(a,b,c){for(;;){if(0===b)return c;var d=ff(a);d.e[0]=c;c=d;b-=5}} -var lf=function kf(b,c,d,e){var f=gf(d),g=b.g-1>>>c&31;5===c?f.e[g]=e:(d=d.e[g],b=null!=d?kf(b,c-5,d,e):jf(null,c-5,e),f.e[g]=b);return f};function mf(a,b){throw Error([z("No item "),z(a),z(" in vector of length "),z(b)].join(""));}function nf(a,b){if(b>=hf(a))return a.W;for(var c=a.root,d=a.shift;;)if(0<d)var e=d-5,c=c.e[b>>>d&31],d=e;else return c.e}function of(a,b){return 0<=b&&b<a.g?nf(a,b):mf(b,a.g)} -var qf=function pf(b,c,d,e,f){var g=gf(d);if(0===c)g.e[e&31]=f;else{var h=e>>>c&31;b=pf(b,c-5,d.e[h],e,f);g.e[h]=b}return g},sf=function rf(b,c,d){var e=b.g-2>>>c&31;if(5<c){b=rf(b,c-5,d.e[e]);if(null==b&&0===e)return null;d=gf(d);d.e[e]=b;return d}if(0===e)return null;d=gf(d);d.e[e]=null;return d};function tf(a,b,c,d,e,f){this.m=a;this.zb=b;this.e=c;this.oa=d;this.start=e;this.end=f}tf.prototype.ga=function(){return this.m<this.end}; -tf.prototype.next=function(){32===this.m-this.zb&&(this.e=nf(this.oa,this.m),this.zb+=32);var a=this.e[this.m&31];this.m+=1;return a};function W(a,b,c,d,e,f){this.k=a;this.g=b;this.shift=c;this.root=d;this.W=e;this.p=f;this.j=167668511;this.q=8196}k=W.prototype;k.toString=function(){return ec(this)};k.t=function(a,b){return $a.c(this,b,null)};k.s=function(a,b,c){return"number"===typeof b?C.c(this,b,c):c}; -k.gb=function(a,b,c){a=0;for(var d=c;;)if(a<this.g){var e=nf(this,a);c=e.length;a:{for(var f=0;;)if(f<c){var g=f+a,h=e[f],d=b.c?b.c(d,g,h):b.call(null,d,g,h);if(Ac(d)){e=d;break a}f+=1}else{e=d;break a}e=void 0}if(Ac(e))return b=e,L.b?L.b(b):L.call(null,b);a+=c;d=e}else return d};k.Q=function(a,b){return of(this,b)[b&31]};k.$=function(a,b,c){return 0<=b&&b<this.g?nf(this,b)[b&31]:c}; -k.Ua=function(a,b,c){if(0<=b&&b<this.g)return hf(this)<=b?(a=Fa(this.W),a[b&31]=c,new W(this.k,this.g,this.shift,this.root,a,null)):new W(this.k,this.g,this.shift,qf(this,this.shift,this.root,b,c),this.W,null);if(b===this.g)return Ra(this,c);throw Error([z("Index "),z(b),z(" out of bounds [0,"),z(this.g),z("]")].join(""));};k.vb=!0;k.fb=function(){var a=this.g;return new tf(0,0,0<Q(this)?nf(this,0):null,this,0,a)};k.H=function(){return this.k};k.L=function(){return this.g}; -k.hb=function(){return C.a(this,0)};k.ib=function(){return C.a(this,1)};k.La=function(){return 0<this.g?C.a(this,this.g-1):null}; -k.Ma=function(){if(0===this.g)throw Error("Can't pop empty vector");if(1===this.g)return ub(Mc,this.k);if(1<this.g-hf(this))return new W(this.k,this.g-1,this.shift,this.root,this.W.slice(0,-1),null);var a=nf(this,this.g-2),b=sf(this,this.shift,this.root),b=null==b?uf:b,c=this.g-1;return 5<this.shift&&null==b.e[1]?new W(this.k,c,this.shift-5,b.e[0],a,null):new W(this.k,c,this.shift,b,a,null)};k.ab=function(){return 0<this.g?new Hc(this,this.g-1,null):null}; -k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){if(b instanceof W)if(this.g===Q(b))for(var c=cc(this),d=cc(b);;)if(t(c.ga())){var e=c.next(),f=d.next();if(!sc.a(e,f))return!1}else return!0;else return!1;else return Ic(this,b)};k.$a=function(){var a=this;return new vf(a.g,a.shift,function(){var b=a.root;return wf.b?wf.b(b):wf.call(null,b)}(),function(){var b=a.W;return xf.b?xf.b(b):xf.call(null,b)}())};k.J=function(){return O(Mc,this.k)}; -k.R=function(a,b){return Cc.a(this,b)};k.O=function(a,b,c){a=0;for(var d=c;;)if(a<this.g){var e=nf(this,a);c=e.length;a:{for(var f=0;;)if(f<c){var g=e[f],d=b.a?b.a(d,g):b.call(null,d,g);if(Ac(d)){e=d;break a}f+=1}else{e=d;break a}e=void 0}if(Ac(e))return b=e,L.b?L.b(b):L.call(null,b);a+=c;d=e}else return d};k.Ka=function(a,b,c){if("number"===typeof b)return pb(this,b,c);throw Error("Vector's key for assoc must be a number.");}; -k.D=function(){if(0===this.g)return null;if(32>=this.g)return new F(this.W,0);var a;a:{a=this.root;for(var b=this.shift;;)if(0<b)b-=5,a=a.e[0];else{a=a.e;break a}a=void 0}return yf.n?yf.n(this,a,0,0):yf.call(null,this,a,0,0)};k.F=function(a,b){return new W(b,this.g,this.shift,this.root,this.W,this.p)}; -k.G=function(a,b){if(32>this.g-hf(this)){for(var c=this.W.length,d=Array(c+1),e=0;;)if(e<c)d[e]=this.W[e],e+=1;else break;d[c]=b;return new W(this.k,this.g+1,this.shift,this.root,d,null)}c=(d=this.g>>>5>1<<this.shift)?this.shift+5:this.shift;d?(d=ff(null),d.e[0]=this.root,e=jf(null,this.shift,new ef(null,this.W)),d.e[1]=e):d=lf(this,this.shift,this.root,new ef(null,this.W));return new W(this.k,this.g+1,c,d,[b],null)}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.Q(null,c);case 3:return this.$(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.Q(null,c)};a.c=function(a,c,d){return this.$(null,c,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.Q(null,a)};k.a=function(a,b){return this.$(null,a,b)}; -var uf=new ef(null,[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null]),Mc=new W(null,0,5,uf,[],0);W.prototype[Ea]=function(){return uc(this)};function zf(a){return Qb(A.c(Pb,Ob(Mc),a))} -var Af=function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){if(a instanceof F&&0===a.m)a:{a=a.e;var b=a.length;if(32>b)a=new W(null,b,5,uf,a,null);else{for(var e=32,f=(new W(null,32,5,uf,a.slice(0,32),null)).$a(null);;)if(e<b)var g=e+1,f=de.a(f,a[e]),e=g;else{a=Qb(f);break a}a=void 0}}else a=zf(a);return a}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}(); -function Bf(a,b,c,d,e,f){this.ha=a;this.Ja=b;this.m=c;this.V=d;this.k=e;this.p=f;this.j=32375020;this.q=1536}k=Bf.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.k};k.T=function(){if(this.V+1<this.Ja.length){var a;a=this.ha;var b=this.Ja,c=this.m,d=this.V+1;a=yf.n?yf.n(a,b,c,d):yf.call(null,a,b,c,d);return null==a?null:a}return $b(this)};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(Mc,this.k)}; -k.R=function(a,b){var c=this;return Cc.a(function(){var a=c.ha,b=c.m+c.V,f=Q(c.ha);return Cf.c?Cf.c(a,b,f):Cf.call(null,a,b,f)}(),b)};k.O=function(a,b,c){var d=this;return Cc.c(function(){var a=d.ha,b=d.m+d.V,c=Q(d.ha);return Cf.c?Cf.c(a,b,c):Cf.call(null,a,b,c)}(),b,c)};k.N=function(){return this.Ja[this.V]};k.S=function(){if(this.V+1<this.Ja.length){var a;a=this.ha;var b=this.Ja,c=this.m,d=this.V+1;a=yf.n?yf.n(a,b,c,d):yf.call(null,a,b,c,d);return null==a?J:a}return Zb(this)};k.D=function(){return this}; -k.Cb=function(){return Ud.a(this.Ja,this.V)};k.Db=function(){var a=this.m+this.Ja.length;if(a<Ma(this.ha)){var b=this.ha,c=nf(this.ha,a);return yf.n?yf.n(b,c,a,0):yf.call(null,b,c,a,0)}return J};k.F=function(a,b){var c=this.ha,d=this.Ja,e=this.m,f=this.V;return yf.r?yf.r(c,d,e,f,b):yf.call(null,c,d,e,f,b)};k.G=function(a,b){return M(b,this)};k.Bb=function(){var a=this.m+this.Ja.length;if(a<Ma(this.ha)){var b=this.ha,c=nf(this.ha,a);return yf.n?yf.n(b,c,a,0):yf.call(null,b,c,a,0)}return null}; -Bf.prototype[Ea]=function(){return uc(this)};var yf=function(){function a(a,b,c,d,l){return new Bf(a,b,c,d,l,null)}function b(a,b,c,d){return new Bf(a,b,c,d,null,null)}function c(a,b,c){return new Bf(a,of(a,b),b,c,null,null)}var d=null,d=function(d,f,g,h,l){switch(arguments.length){case 3:return c.call(this,d,f,g);case 4:return b.call(this,d,f,g,h);case 5:return a.call(this,d,f,g,h,l)}throw Error("Invalid arity: "+arguments.length);};d.c=c;d.n=b;d.r=a;return d}(); -function Df(a,b,c,d,e){this.k=a;this.oa=b;this.start=c;this.end=d;this.p=e;this.j=166617887;this.q=8192}k=Df.prototype;k.toString=function(){return ec(this)};k.t=function(a,b){return $a.c(this,b,null)};k.s=function(a,b,c){return"number"===typeof b?C.c(this,b,c):c};k.Q=function(a,b){return 0>b||this.end<=this.start+b?mf(b,this.end-this.start):C.a(this.oa,this.start+b)};k.$=function(a,b,c){return 0>b||this.end<=this.start+b?c:C.c(this.oa,this.start+b,c)}; -k.Ua=function(a,b,c){var d=this.start+b;a=this.k;c=Rc.c(this.oa,d,c);b=this.start;var e=this.end,d=d+1,d=e>d?e:d;return Ef.r?Ef.r(a,c,b,d,null):Ef.call(null,a,c,b,d,null)};k.H=function(){return this.k};k.L=function(){return this.end-this.start};k.La=function(){return C.a(this.oa,this.end-1)};k.Ma=function(){if(this.start===this.end)throw Error("Can't pop empty vector");var a=this.k,b=this.oa,c=this.start,d=this.end-1;return Ef.r?Ef.r(a,b,c,d,null):Ef.call(null,a,b,c,d,null)}; -k.ab=function(){return this.start!==this.end?new Hc(this,this.end-this.start-1,null):null};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(Mc,this.k)};k.R=function(a,b){return Cc.a(this,b)};k.O=function(a,b,c){return Cc.c(this,b,c)};k.Ka=function(a,b,c){if("number"===typeof b)return pb(this,b,c);throw Error("Subvec's key for assoc must be a number.");}; -k.D=function(){var a=this;return function(b){return function d(e){return e===a.end?null:M(C.a(a.oa,e),new V(null,function(){return function(){return d(e+1)}}(b),null,null))}}(this)(a.start)};k.F=function(a,b){var c=this.oa,d=this.start,e=this.end,f=this.p;return Ef.r?Ef.r(b,c,d,e,f):Ef.call(null,b,c,d,e,f)};k.G=function(a,b){var c=this.k,d=pb(this.oa,this.end,b),e=this.start,f=this.end+1;return Ef.r?Ef.r(c,d,e,f,null):Ef.call(null,c,d,e,f,null)}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.Q(null,c);case 3:return this.$(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.Q(null,c)};a.c=function(a,c,d){return this.$(null,c,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.Q(null,a)};k.a=function(a,b){return this.$(null,a,b)};Df.prototype[Ea]=function(){return uc(this)}; -function Ef(a,b,c,d,e){for(;;)if(b instanceof Df)c=b.start+c,d=b.start+d,b=b.oa;else{var f=Q(b);if(0>c||0>d||c>f||d>f)throw Error("Index out of bounds");return new Df(a,b,c,d,e)}}var Cf=function(){function a(a,b,c){return Ef(null,a,b,c,null)}function b(a,b){return c.c(a,b,Q(a))}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}(); -function Ff(a,b){return a===b.u?b:new ef(a,Fa(b.e))}function wf(a){return new ef({},Fa(a.e))}function xf(a){var b=[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null];hd(a,0,b,0,a.length);return b} -var Hf=function Gf(b,c,d,e){d=Ff(b.root.u,d);var f=b.g-1>>>c&31;if(5===c)b=e;else{var g=d.e[f];b=null!=g?Gf(b,c-5,g,e):jf(b.root.u,c-5,e)}d.e[f]=b;return d},Jf=function If(b,c,d){d=Ff(b.root.u,d);var e=b.g-2>>>c&31;if(5<c){b=If(b,c-5,d.e[e]);if(null==b&&0===e)return null;d.e[e]=b;return d}if(0===e)return null;d.e[e]=null;return d};function vf(a,b,c,d){this.g=a;this.shift=b;this.root=c;this.W=d;this.j=275;this.q=88}k=vf.prototype; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.t(null,c);case 3:return this.s(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.t(null,c)};a.c=function(a,c,d){return this.s(null,c,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.t(null,a)};k.a=function(a,b){return this.s(null,a,b)};k.t=function(a,b){return $a.c(this,b,null)}; -k.s=function(a,b,c){return"number"===typeof b?C.c(this,b,c):c};k.Q=function(a,b){if(this.root.u)return of(this,b)[b&31];throw Error("nth after persistent!");};k.$=function(a,b,c){return 0<=b&&b<this.g?C.a(this,b):c};k.L=function(){if(this.root.u)return this.g;throw Error("count after persistent!");}; -k.Ub=function(a,b,c){var d=this;if(d.root.u){if(0<=b&&b<d.g)return hf(this)<=b?d.W[b&31]=c:(a=function(){return function f(a,h){var l=Ff(d.root.u,h);if(0===a)l.e[b&31]=c;else{var m=b>>>a&31,p=f(a-5,l.e[m]);l.e[m]=p}return l}}(this).call(null,d.shift,d.root),d.root=a),this;if(b===d.g)return Pb(this,c);throw Error([z("Index "),z(b),z(" out of bounds for TransientVector of length"),z(d.g)].join(""));}throw Error("assoc! after persistent!");}; -k.Vb=function(){if(this.root.u){if(0===this.g)throw Error("Can't pop empty vector");if(1===this.g)this.g=0;else if(0<(this.g-1&31))this.g-=1;else{var a;a:if(a=this.g-2,a>=hf(this))a=this.W;else{for(var b=this.root,c=b,d=this.shift;;)if(0<d)c=Ff(b.u,c.e[a>>>d&31]),d-=5;else{a=c.e;break a}a=void 0}b=Jf(this,this.shift,this.root);b=null!=b?b:new ef(this.root.u,[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null, -null,null,null,null]);5<this.shift&&null==b.e[1]?(this.root=Ff(this.root.u,b.e[0]),this.shift-=5):this.root=b;this.g-=1;this.W=a}return this}throw Error("pop! after persistent!");};k.kb=function(a,b,c){if("number"===typeof b)return Tb(this,b,c);throw Error("TransientVector's key for assoc! must be a number.");}; -k.Sa=function(a,b){if(this.root.u){if(32>this.g-hf(this))this.W[this.g&31]=b;else{var c=new ef(this.root.u,this.W),d=[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null];d[0]=b;this.W=d;if(this.g>>>5>1<<this.shift){var d=[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],e=this.shift+ -5;d[0]=this.root;d[1]=jf(this.root.u,this.shift,c);this.root=new ef(this.root.u,d);this.shift=e}else this.root=Hf(this,this.shift,this.root,c)}this.g+=1;return this}throw Error("conj! after persistent!");};k.Ta=function(){if(this.root.u){this.root.u=null;var a=this.g-hf(this),b=Array(a);hd(this.W,0,b,0,a);return new W(null,this.g,this.shift,this.root,b,null)}throw Error("persistent! called twice");};function Kf(a,b,c,d){this.k=a;this.ea=b;this.sa=c;this.p=d;this.q=0;this.j=31850572}k=Kf.prototype; -k.toString=function(){return ec(this)};k.H=function(){return this.k};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.k)};k.N=function(){return G(this.ea)};k.S=function(){var a=K(this.ea);return a?new Kf(this.k,a,this.sa,null):null==this.sa?Na(this):new Kf(this.k,this.sa,null,null)};k.D=function(){return this};k.F=function(a,b){return new Kf(b,this.ea,this.sa,this.p)};k.G=function(a,b){return M(b,this)}; -Kf.prototype[Ea]=function(){return uc(this)};function Lf(a,b,c,d,e){this.k=a;this.count=b;this.ea=c;this.sa=d;this.p=e;this.j=31858766;this.q=8192}k=Lf.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.k};k.L=function(){return this.count};k.La=function(){return G(this.ea)};k.Ma=function(){if(t(this.ea)){var a=K(this.ea);return a?new Lf(this.k,this.count-1,a,this.sa,null):new Lf(this.k,this.count-1,D(this.sa),Mc,null)}return this}; -k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(Mf,this.k)};k.N=function(){return G(this.ea)};k.S=function(){return H(D(this))};k.D=function(){var a=D(this.sa),b=this.ea;return t(t(b)?b:a)?new Kf(null,this.ea,D(a),null):null};k.F=function(a,b){return new Lf(b,this.count,this.ea,this.sa,this.p)}; -k.G=function(a,b){var c;t(this.ea)?(c=this.sa,c=new Lf(this.k,this.count+1,this.ea,Nc.a(t(c)?c:Mc,b),null)):c=new Lf(this.k,this.count+1,Nc.a(this.ea,b),Mc,null);return c};var Mf=new Lf(null,0,null,Mc,0);Lf.prototype[Ea]=function(){return uc(this)};function Nf(){this.q=0;this.j=2097152}Nf.prototype.A=function(){return!1};var Of=new Nf;function Pf(a,b){return md(dd(b)?Q(a)===Q(b)?Ee(ud,Oe.a(function(a){return sc.a(S.c(b,G(a),Of),Lc(a))},a)):null:null)} -function Qf(a,b){var c=a.e;if(b instanceof U)a:{for(var d=c.length,e=b.pa,f=0;;){if(d<=f){c=-1;break a}var g=c[f];if(g instanceof U&&e===g.pa){c=f;break a}f+=2}c=void 0}else if(d="string"==typeof b,t(t(d)?d:"number"===typeof b))a:{d=c.length;for(e=0;;){if(d<=e){c=-1;break a}if(b===c[e]){c=e;break a}e+=2}c=void 0}else if(b instanceof qc)a:{d=c.length;e=b.ta;for(f=0;;){if(d<=f){c=-1;break a}g=c[f];if(g instanceof qc&&e===g.ta){c=f;break a}f+=2}c=void 0}else if(null==b)a:{d=c.length;for(e=0;;){if(d<= -e){c=-1;break a}if(null==c[e]){c=e;break a}e+=2}c=void 0}else a:{d=c.length;for(e=0;;){if(d<=e){c=-1;break a}if(sc.a(b,c[e])){c=e;break a}e+=2}c=void 0}return c}function Rf(a,b,c){this.e=a;this.m=b;this.Z=c;this.q=0;this.j=32374990}k=Rf.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.Z};k.T=function(){return this.m<this.e.length-2?new Rf(this.e,this.m+2,this.Z):null};k.L=function(){return(this.e.length-this.m)/2};k.B=function(){return wc(this)}; -k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.Z)};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){return new W(null,2,5,uf,[this.e[this.m],this.e[this.m+1]],null)};k.S=function(){return this.m<this.e.length-2?new Rf(this.e,this.m+2,this.Z):J};k.D=function(){return this};k.F=function(a,b){return new Rf(this.e,this.m,b)};k.G=function(a,b){return M(b,this)};Rf.prototype[Ea]=function(){return uc(this)}; -function Sf(a,b,c){this.e=a;this.m=b;this.g=c}Sf.prototype.ga=function(){return this.m<this.g};Sf.prototype.next=function(){var a=new W(null,2,5,uf,[this.e[this.m],this.e[this.m+1]],null);this.m+=2;return a};function pa(a,b,c,d){this.k=a;this.g=b;this.e=c;this.p=d;this.j=16647951;this.q=8196}k=pa.prototype;k.toString=function(){return ec(this)};k.t=function(a,b){return $a.c(this,b,null)};k.s=function(a,b,c){a=Qf(this,b);return-1===a?c:this.e[a+1]}; -k.gb=function(a,b,c){a=this.e.length;for(var d=0;;)if(d<a){var e=this.e[d],f=this.e[d+1];c=b.c?b.c(c,e,f):b.call(null,c,e,f);if(Ac(c))return b=c,L.b?L.b(b):L.call(null,b);d+=2}else return c};k.vb=!0;k.fb=function(){return new Sf(this.e,0,2*this.g)};k.H=function(){return this.k};k.L=function(){return this.g};k.B=function(){var a=this.p;return null!=a?a:this.p=a=xc(this)}; -k.A=function(a,b){if(b&&(b.j&1024||b.ic)){var c=this.e.length;if(this.g===b.L(null))for(var d=0;;)if(d<c){var e=b.s(null,this.e[d],jd);if(e!==jd)if(sc.a(this.e[d+1],e))d+=2;else return!1;else return!1}else return!0;else return!1}else return Pf(this,b)};k.$a=function(){return new Tf({},this.e.length,Fa(this.e))};k.J=function(){return ub(Uf,this.k)};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)}; -k.wb=function(a,b){if(0<=Qf(this,b)){var c=this.e.length,d=c-2;if(0===d)return Na(this);for(var d=Array(d),e=0,f=0;;){if(e>=c)return new pa(this.k,this.g-1,d,null);sc.a(b,this.e[e])||(d[f]=this.e[e],d[f+1]=this.e[e+1],f+=2);e+=2}}else return this}; -k.Ka=function(a,b,c){a=Qf(this,b);if(-1===a){if(this.g<Vf){a=this.e;for(var d=a.length,e=Array(d+2),f=0;;)if(f<d)e[f]=a[f],f+=1;else break;e[d]=b;e[d+1]=c;return new pa(this.k,this.g+1,e,null)}return ub(cb(af.a(Qc,this),b,c),this.k)}if(c===this.e[a+1])return this;b=Fa(this.e);b[a+1]=c;return new pa(this.k,this.g,b,null)};k.rb=function(a,b){return-1!==Qf(this,b)};k.D=function(){var a=this.e;return 0<=a.length-2?new Rf(a,0,null):null};k.F=function(a,b){return new pa(b,this.g,this.e,this.p)}; -k.G=function(a,b){if(ed(b))return cb(this,C.a(b,0),C.a(b,1));for(var c=this,d=D(b);;){if(null==d)return c;var e=G(d);if(ed(e))c=cb(c,C.a(e,0),C.a(e,1)),d=K(d);else throw Error("conj on a map takes map entries or seqables of map entries");}}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.t(null,c);case 3:return this.s(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.t(null,c)};a.c=function(a,c,d){return this.s(null,c,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.t(null,a)};k.a=function(a,b){return this.s(null,a,b)};var Uf=new pa(null,0,[],null),Vf=8;pa.prototype[Ea]=function(){return uc(this)}; -function Tf(a,b,c){this.Va=a;this.qa=b;this.e=c;this.q=56;this.j=258}k=Tf.prototype;k.Jb=function(a,b){if(t(this.Va)){var c=Qf(this,b);0<=c&&(this.e[c]=this.e[this.qa-2],this.e[c+1]=this.e[this.qa-1],c=this.e,c.pop(),c.pop(),this.qa-=2);return this}throw Error("dissoc! after persistent!");}; -k.kb=function(a,b,c){var d=this;if(t(d.Va)){a=Qf(this,b);if(-1===a)return d.qa+2<=2*Vf?(d.qa+=2,d.e.push(b),d.e.push(c),this):ee.c(function(){var a=d.qa,b=d.e;return Xf.a?Xf.a(a,b):Xf.call(null,a,b)}(),b,c);c!==d.e[a+1]&&(d.e[a+1]=c);return this}throw Error("assoc! after persistent!");}; -k.Sa=function(a,b){if(t(this.Va)){if(b?b.j&2048||b.jc||(b.j?0:w(fb,b)):w(fb,b))return Rb(this,Yf.b?Yf.b(b):Yf.call(null,b),Zf.b?Zf.b(b):Zf.call(null,b));for(var c=D(b),d=this;;){var e=G(c);if(t(e))var f=e,c=K(c),d=Rb(d,function(){var a=f;return Yf.b?Yf.b(a):Yf.call(null,a)}(),function(){var a=f;return Zf.b?Zf.b(a):Zf.call(null,a)}());else return d}}else throw Error("conj! after persistent!");}; -k.Ta=function(){if(t(this.Va))return this.Va=!1,new pa(null,Cd(this.qa,2),this.e,null);throw Error("persistent! called twice");};k.t=function(a,b){return $a.c(this,b,null)};k.s=function(a,b,c){if(t(this.Va))return a=Qf(this,b),-1===a?c:this.e[a+1];throw Error("lookup after persistent!");};k.L=function(){if(t(this.Va))return Cd(this.qa,2);throw Error("count after persistent!");};function Xf(a,b){for(var c=Ob(Qc),d=0;;)if(d<a)c=ee.c(c,b[d],b[d+1]),d+=2;else return c}function $f(){this.o=!1} -function ag(a,b){return a===b?!0:Nd(a,b)?!0:sc.a(a,b)}var bg=function(){function a(a,b,c,g,h){a=Fa(a);a[b]=c;a[g]=h;return a}function b(a,b,c){a=Fa(a);a[b]=c;return a}var c=null,c=function(c,e,f,g,h){switch(arguments.length){case 3:return b.call(this,c,e,f);case 5:return a.call(this,c,e,f,g,h)}throw Error("Invalid arity: "+arguments.length);};c.c=b;c.r=a;return c}();function cg(a,b){var c=Array(a.length-2);hd(a,0,c,0,2*b);hd(a,2*(b+1),c,2*b,c.length-2*b);return c} -var dg=function(){function a(a,b,c,g,h,l){a=a.Na(b);a.e[c]=g;a.e[h]=l;return a}function b(a,b,c,g){a=a.Na(b);a.e[c]=g;return a}var c=null,c=function(c,e,f,g,h,l){switch(arguments.length){case 4:return b.call(this,c,e,f,g);case 6:return a.call(this,c,e,f,g,h,l)}throw Error("Invalid arity: "+arguments.length);};c.n=b;c.P=a;return c}(); -function eg(a,b,c){for(var d=a.length,e=0,f=c;;)if(e<d){c=a[e];if(null!=c){var g=a[e+1];c=b.c?b.c(f,c,g):b.call(null,f,c,g)}else c=a[e+1],c=null!=c?c.Xa(b,f):f;if(Ac(c))return a=c,L.b?L.b(a):L.call(null,a);e+=2;f=c}else return f}function fg(a,b,c){this.u=a;this.w=b;this.e=c}k=fg.prototype;k.Na=function(a){if(a===this.u)return this;var b=Dd(this.w),c=Array(0>b?4:2*(b+1));hd(this.e,0,c,0,2*b);return new fg(a,this.w,c)}; -k.nb=function(a,b,c,d,e){var f=1<<(c>>>b&31);if(0===(this.w&f))return this;var g=Dd(this.w&f-1),h=this.e[2*g],l=this.e[2*g+1];return null==h?(b=l.nb(a,b+5,c,d,e),b===l?this:null!=b?dg.n(this,a,2*g+1,b):this.w===f?null:gg(this,a,f,g)):ag(d,h)?(e[0]=!0,gg(this,a,f,g)):this};function gg(a,b,c,d){if(a.w===c)return null;a=a.Na(b);b=a.e;var e=b.length;a.w^=c;hd(b,2*(d+1),b,2*d,e-2*(d+1));b[e-2]=null;b[e-1]=null;return a}k.lb=function(){var a=this.e;return hg.b?hg.b(a):hg.call(null,a)}; -k.Xa=function(a,b){return eg(this.e,a,b)};k.Oa=function(a,b,c,d){var e=1<<(b>>>a&31);if(0===(this.w&e))return d;var f=Dd(this.w&e-1),e=this.e[2*f],f=this.e[2*f+1];return null==e?f.Oa(a+5,b,c,d):ag(c,e)?f:d}; -k.la=function(a,b,c,d,e,f){var g=1<<(c>>>b&31),h=Dd(this.w&g-1);if(0===(this.w&g)){var l=Dd(this.w);if(2*l<this.e.length){var m=this.Na(a),p=m.e;f.o=!0;id(p,2*h,p,2*(h+1),2*(l-h));p[2*h]=d;p[2*h+1]=e;m.w|=g;return m}if(16<=l){g=[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null];g[c>>>b&31]=ig.la(a,b+5,c,d,e,f);for(m=h=0;;)if(32>h)0!==(this.w>>>h&1)&&(g[h]=null!=this.e[m]?ig.la(a,b+5,nc(this.e[m]), -this.e[m],this.e[m+1],f):this.e[m+1],m+=2),h+=1;else break;return new jg(a,l+1,g)}p=Array(2*(l+4));hd(this.e,0,p,0,2*h);p[2*h]=d;p[2*h+1]=e;hd(this.e,2*h,p,2*(h+1),2*(l-h));f.o=!0;m=this.Na(a);m.e=p;m.w|=g;return m}var q=this.e[2*h],s=this.e[2*h+1];if(null==q)return l=s.la(a,b+5,c,d,e,f),l===s?this:dg.n(this,a,2*h+1,l);if(ag(d,q))return e===s?this:dg.n(this,a,2*h+1,e);f.o=!0;return dg.P(this,a,2*h,null,2*h+1,function(){var f=b+5;return kg.ia?kg.ia(a,f,q,s,c,d,e):kg.call(null,a,f,q,s,c,d,e)}())}; -k.ka=function(a,b,c,d,e){var f=1<<(b>>>a&31),g=Dd(this.w&f-1);if(0===(this.w&f)){var h=Dd(this.w);if(16<=h){f=[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null];f[b>>>a&31]=ig.ka(a+5,b,c,d,e);for(var l=g=0;;)if(32>g)0!==(this.w>>>g&1)&&(f[g]=null!=this.e[l]?ig.ka(a+5,nc(this.e[l]),this.e[l],this.e[l+1],e):this.e[l+1],l+=2),g+=1;else break;return new jg(null,h+1,f)}l=Array(2*(h+1));hd(this.e, -0,l,0,2*g);l[2*g]=c;l[2*g+1]=d;hd(this.e,2*g,l,2*(g+1),2*(h-g));e.o=!0;return new fg(null,this.w|f,l)}var m=this.e[2*g],p=this.e[2*g+1];if(null==m)return h=p.ka(a+5,b,c,d,e),h===p?this:new fg(null,this.w,bg.c(this.e,2*g+1,h));if(ag(c,m))return d===p?this:new fg(null,this.w,bg.c(this.e,2*g+1,d));e.o=!0;return new fg(null,this.w,bg.r(this.e,2*g,null,2*g+1,function(){var e=a+5;return kg.P?kg.P(e,m,p,b,c,d):kg.call(null,e,m,p,b,c,d)}()))}; -k.mb=function(a,b,c){var d=1<<(b>>>a&31);if(0===(this.w&d))return this;var e=Dd(this.w&d-1),f=this.e[2*e],g=this.e[2*e+1];return null==f?(a=g.mb(a+5,b,c),a===g?this:null!=a?new fg(null,this.w,bg.c(this.e,2*e+1,a)):this.w===d?null:new fg(null,this.w^d,cg(this.e,e))):ag(c,f)?new fg(null,this.w^d,cg(this.e,e)):this};var ig=new fg(null,0,[]); -function lg(a,b,c){var d=a.e,e=d.length;a=Array(2*(a.g-1));for(var f=0,g=1,h=0;;)if(f<e)f!==c&&null!=d[f]&&(a[g]=d[f],g+=2,h|=1<<f),f+=1;else return new fg(b,h,a)}function jg(a,b,c){this.u=a;this.g=b;this.e=c}k=jg.prototype;k.Na=function(a){return a===this.u?this:new jg(a,this.g,Fa(this.e))}; -k.nb=function(a,b,c,d,e){var f=c>>>b&31,g=this.e[f];if(null==g)return this;b=g.nb(a,b+5,c,d,e);if(b===g)return this;if(null==b){if(8>=this.g)return lg(this,a,f);a=dg.n(this,a,f,b);a.g-=1;return a}return dg.n(this,a,f,b)};k.lb=function(){var a=this.e;return mg.b?mg.b(a):mg.call(null,a)};k.Xa=function(a,b){for(var c=this.e.length,d=0,e=b;;)if(d<c){var f=this.e[d];if(null!=f&&(e=f.Xa(a,e),Ac(e)))return c=e,L.b?L.b(c):L.call(null,c);d+=1}else return e}; -k.Oa=function(a,b,c,d){var e=this.e[b>>>a&31];return null!=e?e.Oa(a+5,b,c,d):d};k.la=function(a,b,c,d,e,f){var g=c>>>b&31,h=this.e[g];if(null==h)return a=dg.n(this,a,g,ig.la(a,b+5,c,d,e,f)),a.g+=1,a;b=h.la(a,b+5,c,d,e,f);return b===h?this:dg.n(this,a,g,b)};k.ka=function(a,b,c,d,e){var f=b>>>a&31,g=this.e[f];if(null==g)return new jg(null,this.g+1,bg.c(this.e,f,ig.ka(a+5,b,c,d,e)));a=g.ka(a+5,b,c,d,e);return a===g?this:new jg(null,this.g,bg.c(this.e,f,a))}; -k.mb=function(a,b,c){var d=b>>>a&31,e=this.e[d];return null!=e?(a=e.mb(a+5,b,c),a===e?this:null==a?8>=this.g?lg(this,null,d):new jg(null,this.g-1,bg.c(this.e,d,a)):new jg(null,this.g,bg.c(this.e,d,a))):this};function ng(a,b,c){b*=2;for(var d=0;;)if(d<b){if(ag(c,a[d]))return d;d+=2}else return-1}function og(a,b,c,d){this.u=a;this.Ia=b;this.g=c;this.e=d}k=og.prototype;k.Na=function(a){if(a===this.u)return this;var b=Array(2*(this.g+1));hd(this.e,0,b,0,2*this.g);return new og(a,this.Ia,this.g,b)}; -k.nb=function(a,b,c,d,e){b=ng(this.e,this.g,d);if(-1===b)return this;e[0]=!0;if(1===this.g)return null;a=this.Na(a);e=a.e;e[b]=e[2*this.g-2];e[b+1]=e[2*this.g-1];e[2*this.g-1]=null;e[2*this.g-2]=null;a.g-=1;return a};k.lb=function(){var a=this.e;return hg.b?hg.b(a):hg.call(null,a)};k.Xa=function(a,b){return eg(this.e,a,b)};k.Oa=function(a,b,c,d){a=ng(this.e,this.g,c);return 0>a?d:ag(c,this.e[a])?this.e[a+1]:d}; -k.la=function(a,b,c,d,e,f){if(c===this.Ia){b=ng(this.e,this.g,d);if(-1===b){if(this.e.length>2*this.g)return a=dg.P(this,a,2*this.g,d,2*this.g+1,e),f.o=!0,a.g+=1,a;c=this.e.length;b=Array(c+2);hd(this.e,0,b,0,c);b[c]=d;b[c+1]=e;f.o=!0;f=this.g+1;a===this.u?(this.e=b,this.g=f,a=this):a=new og(this.u,this.Ia,f,b);return a}return this.e[b+1]===e?this:dg.n(this,a,b+1,e)}return(new fg(a,1<<(this.Ia>>>b&31),[null,this,null,null])).la(a,b,c,d,e,f)}; -k.ka=function(a,b,c,d,e){return b===this.Ia?(a=ng(this.e,this.g,c),-1===a?(a=2*this.g,b=Array(a+2),hd(this.e,0,b,0,a),b[a]=c,b[a+1]=d,e.o=!0,new og(null,this.Ia,this.g+1,b)):sc.a(this.e[a],d)?this:new og(null,this.Ia,this.g,bg.c(this.e,a+1,d))):(new fg(null,1<<(this.Ia>>>a&31),[null,this])).ka(a,b,c,d,e)};k.mb=function(a,b,c){a=ng(this.e,this.g,c);return-1===a?this:1===this.g?null:new og(null,this.Ia,this.g-1,cg(this.e,Cd(a,2)))}; -var kg=function(){function a(a,b,c,g,h,l,m){var p=nc(c);if(p===h)return new og(null,p,2,[c,g,l,m]);var q=new $f;return ig.la(a,b,p,c,g,q).la(a,b,h,l,m,q)}function b(a,b,c,g,h,l){var m=nc(b);if(m===g)return new og(null,m,2,[b,c,h,l]);var p=new $f;return ig.ka(a,m,b,c,p).ka(a,g,h,l,p)}var c=null,c=function(c,e,f,g,h,l,m){switch(arguments.length){case 6:return b.call(this,c,e,f,g,h,l);case 7:return a.call(this,c,e,f,g,h,l,m)}throw Error("Invalid arity: "+arguments.length);};c.P=b;c.ia=a;return c}(); -function pg(a,b,c,d,e){this.k=a;this.Pa=b;this.m=c;this.C=d;this.p=e;this.q=0;this.j=32374860}k=pg.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.k};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.k)};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){return null==this.C?new W(null,2,5,uf,[this.Pa[this.m],this.Pa[this.m+1]],null):G(this.C)}; -k.S=function(){if(null==this.C){var a=this.Pa,b=this.m+2;return hg.c?hg.c(a,b,null):hg.call(null,a,b,null)}var a=this.Pa,b=this.m,c=K(this.C);return hg.c?hg.c(a,b,c):hg.call(null,a,b,c)};k.D=function(){return this};k.F=function(a,b){return new pg(b,this.Pa,this.m,this.C,this.p)};k.G=function(a,b){return M(b,this)};pg.prototype[Ea]=function(){return uc(this)}; -var hg=function(){function a(a,b,c){if(null==c)for(c=a.length;;)if(b<c){if(null!=a[b])return new pg(null,a,b,null,null);var g=a[b+1];if(t(g)&&(g=g.lb(),t(g)))return new pg(null,a,b+2,g,null);b+=2}else return null;else return new pg(null,a,b,c,null)}function b(a){return c.c(a,0,null)}var c=null,c=function(c,e,f){switch(arguments.length){case 1:return b.call(this,c);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.c=a;return c}(); -function qg(a,b,c,d,e){this.k=a;this.Pa=b;this.m=c;this.C=d;this.p=e;this.q=0;this.j=32374860}k=qg.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.k};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.k)};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){return G(this.C)}; -k.S=function(){var a=this.Pa,b=this.m,c=K(this.C);return mg.n?mg.n(null,a,b,c):mg.call(null,null,a,b,c)};k.D=function(){return this};k.F=function(a,b){return new qg(b,this.Pa,this.m,this.C,this.p)};k.G=function(a,b){return M(b,this)};qg.prototype[Ea]=function(){return uc(this)}; -var mg=function(){function a(a,b,c,g){if(null==g)for(g=b.length;;)if(c<g){var h=b[c];if(t(h)&&(h=h.lb(),t(h)))return new qg(a,b,c+1,h,null);c+=1}else return null;else return new qg(a,b,c,g,null)}function b(a){return c.n(null,a,0,null)}var c=null,c=function(c,e,f,g){switch(arguments.length){case 1:return b.call(this,c);case 4:return a.call(this,c,e,f,g)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.n=a;return c}(); -function rg(a,b,c,d,e,f){this.k=a;this.g=b;this.root=c;this.U=d;this.da=e;this.p=f;this.j=16123663;this.q=8196}k=rg.prototype;k.toString=function(){return ec(this)};k.t=function(a,b){return $a.c(this,b,null)};k.s=function(a,b,c){return null==b?this.U?this.da:c:null==this.root?c:this.root.Oa(0,nc(b),b,c)};k.gb=function(a,b,c){this.U&&(a=this.da,c=b.c?b.c(c,null,a):b.call(null,c,null,a));return Ac(c)?L.b?L.b(c):L.call(null,c):null!=this.root?this.root.Xa(b,c):c};k.H=function(){return this.k};k.L=function(){return this.g}; -k.B=function(){var a=this.p;return null!=a?a:this.p=a=xc(this)};k.A=function(a,b){return Pf(this,b)};k.$a=function(){return new sg({},this.root,this.g,this.U,this.da)};k.J=function(){return ub(Qc,this.k)};k.wb=function(a,b){if(null==b)return this.U?new rg(this.k,this.g-1,this.root,!1,null,null):this;if(null==this.root)return this;var c=this.root.mb(0,nc(b),b);return c===this.root?this:new rg(this.k,this.g-1,c,this.U,this.da,null)}; -k.Ka=function(a,b,c){if(null==b)return this.U&&c===this.da?this:new rg(this.k,this.U?this.g:this.g+1,this.root,!0,c,null);a=new $f;b=(null==this.root?ig:this.root).ka(0,nc(b),b,c,a);return b===this.root?this:new rg(this.k,a.o?this.g+1:this.g,b,this.U,this.da,null)};k.rb=function(a,b){return null==b?this.U:null==this.root?!1:this.root.Oa(0,nc(b),b,jd)!==jd};k.D=function(){if(0<this.g){var a=null!=this.root?this.root.lb():null;return this.U?M(new W(null,2,5,uf,[null,this.da],null),a):a}return null}; -k.F=function(a,b){return new rg(b,this.g,this.root,this.U,this.da,this.p)};k.G=function(a,b){if(ed(b))return cb(this,C.a(b,0),C.a(b,1));for(var c=this,d=D(b);;){if(null==d)return c;var e=G(d);if(ed(e))c=cb(c,C.a(e,0),C.a(e,1)),d=K(d);else throw Error("conj on a map takes map entries or seqables of map entries");}}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.t(null,c);case 3:return this.s(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.t(null,c)};a.c=function(a,c,d){return this.s(null,c,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.t(null,a)};k.a=function(a,b){return this.s(null,a,b)};var Qc=new rg(null,0,null,!1,null,0);rg.prototype[Ea]=function(){return uc(this)}; -function sg(a,b,c,d,e){this.u=a;this.root=b;this.count=c;this.U=d;this.da=e;this.q=56;this.j=258}k=sg.prototype;k.Jb=function(a,b){if(this.u)if(null==b)this.U&&(this.U=!1,this.da=null,this.count-=1);else{if(null!=this.root){var c=new $f,d=this.root.nb(this.u,0,nc(b),b,c);d!==this.root&&(this.root=d);t(c[0])&&(this.count-=1)}}else throw Error("dissoc! after persistent!");return this};k.kb=function(a,b,c){return tg(this,b,c)};k.Sa=function(a,b){return ug(this,b)}; -k.Ta=function(){var a;if(this.u)this.u=null,a=new rg(null,this.count,this.root,this.U,this.da,null);else throw Error("persistent! called twice");return a};k.t=function(a,b){return null==b?this.U?this.da:null:null==this.root?null:this.root.Oa(0,nc(b),b)};k.s=function(a,b,c){return null==b?this.U?this.da:c:null==this.root?c:this.root.Oa(0,nc(b),b,c)};k.L=function(){if(this.u)return this.count;throw Error("count after persistent!");}; -function ug(a,b){if(a.u){if(b?b.j&2048||b.jc||(b.j?0:w(fb,b)):w(fb,b))return tg(a,Yf.b?Yf.b(b):Yf.call(null,b),Zf.b?Zf.b(b):Zf.call(null,b));for(var c=D(b),d=a;;){var e=G(c);if(t(e))var f=e,c=K(c),d=tg(d,function(){var a=f;return Yf.b?Yf.b(a):Yf.call(null,a)}(),function(){var a=f;return Zf.b?Zf.b(a):Zf.call(null,a)}());else return d}}else throw Error("conj! after persistent");} -function tg(a,b,c){if(a.u){if(null==b)a.da!==c&&(a.da=c),a.U||(a.count+=1,a.U=!0);else{var d=new $f;b=(null==a.root?ig:a.root).la(a.u,0,nc(b),b,c,d);b!==a.root&&(a.root=b);d.o&&(a.count+=1)}return a}throw Error("assoc! after persistent!");}function vg(a,b,c){for(var d=b;;)if(null!=a)b=c?a.left:a.right,d=Nc.a(d,a),a=b;else return d}function wg(a,b,c,d,e){this.k=a;this.stack=b;this.pb=c;this.g=d;this.p=e;this.q=0;this.j=32374862}k=wg.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.k}; -k.L=function(){return 0>this.g?Q(K(this))+1:this.g};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.k)};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){return Wc(this.stack)};k.S=function(){var a=G(this.stack),a=vg(this.pb?a.right:a.left,K(this.stack),this.pb);return null!=a?new wg(null,a,this.pb,this.g-1,null):J};k.D=function(){return this}; -k.F=function(a,b){return new wg(b,this.stack,this.pb,this.g,this.p)};k.G=function(a,b){return M(b,this)};wg.prototype[Ea]=function(){return uc(this)};function xg(a,b,c){return new wg(null,vg(a,null,b),b,c,null)} -function yg(a,b,c,d){return c instanceof X?c.left instanceof X?new X(c.key,c.o,c.left.ua(),new Z(a,b,c.right,d,null),null):c.right instanceof X?new X(c.right.key,c.right.o,new Z(c.key,c.o,c.left,c.right.left,null),new Z(a,b,c.right.right,d,null),null):new Z(a,b,c,d,null):new Z(a,b,c,d,null)} -function zg(a,b,c,d){return d instanceof X?d.right instanceof X?new X(d.key,d.o,new Z(a,b,c,d.left,null),d.right.ua(),null):d.left instanceof X?new X(d.left.key,d.left.o,new Z(a,b,c,d.left.left,null),new Z(d.key,d.o,d.left.right,d.right,null),null):new Z(a,b,c,d,null):new Z(a,b,c,d,null)} -function Ag(a,b,c,d){if(c instanceof X)return new X(a,b,c.ua(),d,null);if(d instanceof Z)return zg(a,b,c,d.ob());if(d instanceof X&&d.left instanceof Z)return new X(d.left.key,d.left.o,new Z(a,b,c,d.left.left,null),zg(d.key,d.o,d.left.right,d.right.ob()),null);throw Error("red-black tree invariant violation");} -var Cg=function Bg(b,c,d){d=null!=b.left?Bg(b.left,c,d):d;if(Ac(d))return L.b?L.b(d):L.call(null,d);var e=b.key,f=b.o;d=c.c?c.c(d,e,f):c.call(null,d,e,f);if(Ac(d))return L.b?L.b(d):L.call(null,d);b=null!=b.right?Bg(b.right,c,d):d;return Ac(b)?L.b?L.b(b):L.call(null,b):b};function Z(a,b,c,d,e){this.key=a;this.o=b;this.left=c;this.right=d;this.p=e;this.q=0;this.j=32402207}k=Z.prototype;k.Mb=function(a){return a.Ob(this)};k.ob=function(){return new X(this.key,this.o,this.left,this.right,null)}; -k.ua=function(){return this};k.Lb=function(a){return a.Nb(this)};k.replace=function(a,b,c,d){return new Z(a,b,c,d,null)};k.Nb=function(a){return new Z(a.key,a.o,this,a.right,null)};k.Ob=function(a){return new Z(a.key,a.o,a.left,this,null)};k.Xa=function(a,b){return Cg(this,a,b)};k.t=function(a,b){return C.c(this,b,null)};k.s=function(a,b,c){return C.c(this,b,c)};k.Q=function(a,b){return 0===b?this.key:1===b?this.o:null};k.$=function(a,b,c){return 0===b?this.key:1===b?this.o:c}; -k.Ua=function(a,b,c){return(new W(null,2,5,uf,[this.key,this.o],null)).Ua(null,b,c)};k.H=function(){return null};k.L=function(){return 2};k.hb=function(){return this.key};k.ib=function(){return this.o};k.La=function(){return this.o};k.Ma=function(){return new W(null,1,5,uf,[this.key],null)};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return Mc};k.R=function(a,b){return Cc.a(this,b)};k.O=function(a,b,c){return Cc.c(this,b,c)}; -k.Ka=function(a,b,c){return Rc.c(new W(null,2,5,uf,[this.key,this.o],null),b,c)};k.D=function(){return Ra(Ra(J,this.o),this.key)};k.F=function(a,b){return O(new W(null,2,5,uf,[this.key,this.o],null),b)};k.G=function(a,b){return new W(null,3,5,uf,[this.key,this.o,b],null)}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.t(null,c);case 3:return this.s(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.t(null,c)};a.c=function(a,c,d){return this.s(null,c,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.t(null,a)};k.a=function(a,b){return this.s(null,a,b)};Z.prototype[Ea]=function(){return uc(this)}; -function X(a,b,c,d,e){this.key=a;this.o=b;this.left=c;this.right=d;this.p=e;this.q=0;this.j=32402207}k=X.prototype;k.Mb=function(a){return new X(this.key,this.o,this.left,a,null)};k.ob=function(){throw Error("red-black tree invariant violation");};k.ua=function(){return new Z(this.key,this.o,this.left,this.right,null)};k.Lb=function(a){return new X(this.key,this.o,a,this.right,null)};k.replace=function(a,b,c,d){return new X(a,b,c,d,null)}; -k.Nb=function(a){return this.left instanceof X?new X(this.key,this.o,this.left.ua(),new Z(a.key,a.o,this.right,a.right,null),null):this.right instanceof X?new X(this.right.key,this.right.o,new Z(this.key,this.o,this.left,this.right.left,null),new Z(a.key,a.o,this.right.right,a.right,null),null):new Z(a.key,a.o,this,a.right,null)}; -k.Ob=function(a){return this.right instanceof X?new X(this.key,this.o,new Z(a.key,a.o,a.left,this.left,null),this.right.ua(),null):this.left instanceof X?new X(this.left.key,this.left.o,new Z(a.key,a.o,a.left,this.left.left,null),new Z(this.key,this.o,this.left.right,this.right,null),null):new Z(a.key,a.o,a.left,this,null)};k.Xa=function(a,b){return Cg(this,a,b)};k.t=function(a,b){return C.c(this,b,null)};k.s=function(a,b,c){return C.c(this,b,c)}; -k.Q=function(a,b){return 0===b?this.key:1===b?this.o:null};k.$=function(a,b,c){return 0===b?this.key:1===b?this.o:c};k.Ua=function(a,b,c){return(new W(null,2,5,uf,[this.key,this.o],null)).Ua(null,b,c)};k.H=function(){return null};k.L=function(){return 2};k.hb=function(){return this.key};k.ib=function(){return this.o};k.La=function(){return this.o};k.Ma=function(){return new W(null,1,5,uf,[this.key],null)};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)}; -k.A=function(a,b){return Ic(this,b)};k.J=function(){return Mc};k.R=function(a,b){return Cc.a(this,b)};k.O=function(a,b,c){return Cc.c(this,b,c)};k.Ka=function(a,b,c){return Rc.c(new W(null,2,5,uf,[this.key,this.o],null),b,c)};k.D=function(){return Ra(Ra(J,this.o),this.key)};k.F=function(a,b){return O(new W(null,2,5,uf,[this.key,this.o],null),b)};k.G=function(a,b){return new W(null,3,5,uf,[this.key,this.o,b],null)}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.t(null,c);case 3:return this.s(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.t(null,c)};a.c=function(a,c,d){return this.s(null,c,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.t(null,a)};k.a=function(a,b){return this.s(null,a,b)};X.prototype[Ea]=function(){return uc(this)}; -var Eg=function Dg(b,c,d,e,f){if(null==c)return new X(d,e,null,null,null);var g;g=c.key;g=b.a?b.a(d,g):b.call(null,d,g);if(0===g)return f[0]=c,null;if(0>g)return b=Dg(b,c.left,d,e,f),null!=b?c.Lb(b):null;b=Dg(b,c.right,d,e,f);return null!=b?c.Mb(b):null},Gg=function Fg(b,c){if(null==b)return c;if(null==c)return b;if(b instanceof X){if(c instanceof X){var d=Fg(b.right,c.left);return d instanceof X?new X(d.key,d.o,new X(b.key,b.o,b.left,d.left,null),new X(c.key,c.o,d.right,c.right,null),null):new X(b.key, -b.o,b.left,new X(c.key,c.o,d,c.right,null),null)}return new X(b.key,b.o,b.left,Fg(b.right,c),null)}if(c instanceof X)return new X(c.key,c.o,Fg(b,c.left),c.right,null);d=Fg(b.right,c.left);return d instanceof X?new X(d.key,d.o,new Z(b.key,b.o,b.left,d.left,null),new Z(c.key,c.o,d.right,c.right,null),null):Ag(b.key,b.o,b.left,new Z(c.key,c.o,d,c.right,null))},Ig=function Hg(b,c,d,e){if(null!=c){var f;f=c.key;f=b.a?b.a(d,f):b.call(null,d,f);if(0===f)return e[0]=c,Gg(c.left,c.right);if(0>f)return b=Hg(b, -c.left,d,e),null!=b||null!=e[0]?c.left instanceof Z?Ag(c.key,c.o,b,c.right):new X(c.key,c.o,b,c.right,null):null;b=Hg(b,c.right,d,e);if(null!=b||null!=e[0])if(c.right instanceof Z)if(e=c.key,d=c.o,c=c.left,b instanceof X)c=new X(e,d,c,b.ua(),null);else if(c instanceof Z)c=yg(e,d,c.ob(),b);else if(c instanceof X&&c.right instanceof Z)c=new X(c.right.key,c.right.o,yg(c.key,c.o,c.left.ob(),c.right.left),new Z(e,d,c.right.right,b,null),null);else throw Error("red-black tree invariant violation");else c= -new X(c.key,c.o,c.left,b,null);else c=null;return c}return null},Kg=function Jg(b,c,d,e){var f=c.key,g=b.a?b.a(d,f):b.call(null,d,f);return 0===g?c.replace(f,e,c.left,c.right):0>g?c.replace(f,c.o,Jg(b,c.left,d,e),c.right):c.replace(f,c.o,c.left,Jg(b,c.right,d,e))};function Lg(a,b,c,d,e){this.aa=a;this.na=b;this.g=c;this.k=d;this.p=e;this.j=418776847;this.q=8192}k=Lg.prototype;k.toString=function(){return ec(this)}; -function Mg(a,b){for(var c=a.na;;)if(null!=c){var d;d=c.key;d=a.aa.a?a.aa.a(b,d):a.aa.call(null,b,d);if(0===d)return c;c=0>d?c.left:c.right}else return null}k.t=function(a,b){return $a.c(this,b,null)};k.s=function(a,b,c){a=Mg(this,b);return null!=a?a.o:c};k.gb=function(a,b,c){return null!=this.na?Cg(this.na,b,c):c};k.H=function(){return this.k};k.L=function(){return this.g};k.ab=function(){return 0<this.g?xg(this.na,!1,this.g):null};k.B=function(){var a=this.p;return null!=a?a:this.p=a=xc(this)}; -k.A=function(a,b){return Pf(this,b)};k.J=function(){return new Lg(this.aa,null,0,this.k,0)};k.wb=function(a,b){var c=[null],d=Ig(this.aa,this.na,b,c);return null==d?null==R.a(c,0)?this:new Lg(this.aa,null,0,this.k,null):new Lg(this.aa,d.ua(),this.g-1,this.k,null)};k.Ka=function(a,b,c){a=[null];var d=Eg(this.aa,this.na,b,c,a);return null==d?(a=R.a(a,0),sc.a(c,a.o)?this:new Lg(this.aa,Kg(this.aa,this.na,b,c),this.g,this.k,null)):new Lg(this.aa,d.ua(),this.g+1,this.k,null)}; -k.rb=function(a,b){return null!=Mg(this,b)};k.D=function(){return 0<this.g?xg(this.na,!0,this.g):null};k.F=function(a,b){return new Lg(this.aa,this.na,this.g,b,this.p)};k.G=function(a,b){if(ed(b))return cb(this,C.a(b,0),C.a(b,1));for(var c=this,d=D(b);;){if(null==d)return c;var e=G(d);if(ed(e))c=cb(c,C.a(e,0),C.a(e,1)),d=K(d);else throw Error("conj on a map takes map entries or seqables of map entries");}}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.t(null,c);case 3:return this.s(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.t(null,c)};a.c=function(a,c,d){return this.s(null,c,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.t(null,a)};k.a=function(a,b){return this.s(null,a,b)};k.Hb=function(a,b){return 0<this.g?xg(this.na,b,this.g):null}; -k.Ib=function(a,b,c){if(0<this.g){a=null;for(var d=this.na;;)if(null!=d){var e;e=d.key;e=this.aa.a?this.aa.a(b,e):this.aa.call(null,b,e);if(0===e)return new wg(null,Nc.a(a,d),c,-1,null);t(c)?0>e?(a=Nc.a(a,d),d=d.left):d=d.right:0<e?(a=Nc.a(a,d),d=d.right):d=d.left}else return null==a?null:new wg(null,a,c,-1,null)}else return null};k.Gb=function(a,b){return Yf.b?Yf.b(b):Yf.call(null,b)};k.Fb=function(){return this.aa};var Ng=new Lg(od,null,0,null,0);Lg.prototype[Ea]=function(){return uc(this)}; -var Og=function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){a=D(a);for(var b=Ob(Qc);;)if(a){var e=K(K(a)),b=ee.c(b,G(a),Lc(a));a=e}else return Qb(b)}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}(),Pg=function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this, -d)}function b(a){a:{a=T.a(Ha,a);for(var b=a.length,e=0,f=Ob(Uf);;)if(e<b)var g=e+2,f=Rb(f,a[e],a[e+1]),e=g;else{a=Qb(f);break a}a=void 0}return a}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}(),Qg=function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){a=D(a);for(var b=Ng;;)if(a){var e=K(K(a)),b=Rc.c(b,G(a),Lc(a));a=e}else return b}a.i=0;a.f=function(a){a=D(a); -return b(a)};a.d=b;return a}(),Rg=function(){function a(a,d){var e=null;if(1<arguments.length){for(var e=0,f=Array(arguments.length-1);e<f.length;)f[e]=arguments[e+1],++e;e=new F(f,0)}return b.call(this,a,e)}function b(a,b){for(var e=D(b),f=new Lg(qd(a),null,0,null,0);;)if(e)var g=K(K(e)),f=Rc.c(f,G(e),Lc(e)),e=g;else return f}a.i=1;a.f=function(a){var d=G(a);a=H(a);return b(d,a)};a.d=b;return a}();function Sg(a,b){this.Y=a;this.Z=b;this.q=0;this.j=32374988}k=Sg.prototype;k.toString=function(){return ec(this)}; -k.H=function(){return this.Z};k.T=function(){var a=this.Y,a=(a?a.j&128||a.xb||(a.j?0:w(Xa,a)):w(Xa,a))?this.Y.T(null):K(this.Y);return null==a?null:new Sg(a,this.Z)};k.B=function(){return wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.Z)};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){return this.Y.N(null).hb(null)}; -k.S=function(){var a=this.Y,a=(a?a.j&128||a.xb||(a.j?0:w(Xa,a)):w(Xa,a))?this.Y.T(null):K(this.Y);return null!=a?new Sg(a,this.Z):J};k.D=function(){return this};k.F=function(a,b){return new Sg(this.Y,b)};k.G=function(a,b){return M(b,this)};Sg.prototype[Ea]=function(){return uc(this)};function Tg(a){return(a=D(a))?new Sg(a,null):null}function Yf(a){return hb(a)}function Ug(a,b){this.Y=a;this.Z=b;this.q=0;this.j=32374988}k=Ug.prototype;k.toString=function(){return ec(this)};k.H=function(){return this.Z}; -k.T=function(){var a=this.Y,a=(a?a.j&128||a.xb||(a.j?0:w(Xa,a)):w(Xa,a))?this.Y.T(null):K(this.Y);return null==a?null:new Ug(a,this.Z)};k.B=function(){return wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.Z)};k.R=function(a,b){return P.a(b,this)};k.O=function(a,b,c){return P.c(b,c,this)};k.N=function(){return this.Y.N(null).ib(null)};k.S=function(){var a=this.Y,a=(a?a.j&128||a.xb||(a.j?0:w(Xa,a)):w(Xa,a))?this.Y.T(null):K(this.Y);return null!=a?new Ug(a,this.Z):J}; -k.D=function(){return this};k.F=function(a,b){return new Ug(this.Y,b)};k.G=function(a,b){return M(b,this)};Ug.prototype[Ea]=function(){return uc(this)};function Vg(a){return(a=D(a))?new Ug(a,null):null}function Zf(a){return ib(a)} -var Wg=function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){return t(Fe(ud,a))?A.a(function(a,b){return Nc.a(t(a)?a:Uf,b)},a):null}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}(),Xg=function(){function a(a,d){var e=null;if(1<arguments.length){for(var e=0,f=Array(arguments.length-1);e<f.length;)f[e]=arguments[e+1],++e;e=new F(f,0)}return b.call(this,a,e)}function b(a, -b){return t(Fe(ud,b))?A.a(function(a){return function(b,c){return A.c(a,t(b)?b:Uf,D(c))}}(function(b,d){var g=G(d),h=Lc(d);return nd(b,g)?Rc.c(b,g,function(){var d=S.a(b,g);return a.a?a.a(d,h):a.call(null,d,h)}()):Rc.c(b,g,h)}),b):null}a.i=1;a.f=function(a){var d=G(a);a=H(a);return b(d,a)};a.d=b;return a}();function Yg(a,b){for(var c=Uf,d=D(b);;)if(d)var e=G(d),f=S.c(a,e,Zg),c=je.a(f,Zg)?Rc.c(c,e,f):c,d=K(d);else return O(c,Vc(a))} -function $g(a,b,c){this.k=a;this.Wa=b;this.p=c;this.j=15077647;this.q=8196}k=$g.prototype;k.toString=function(){return ec(this)};k.t=function(a,b){return $a.c(this,b,null)};k.s=function(a,b,c){return bb(this.Wa,b)?b:c};k.H=function(){return this.k};k.L=function(){return Ma(this.Wa)};k.B=function(){var a=this.p;return null!=a?a:this.p=a=xc(this)};k.A=function(a,b){return ad(b)&&Q(this)===Q(b)&&Ee(function(a){return function(b){return nd(a,b)}}(this),b)};k.$a=function(){return new ah(Ob(this.Wa))}; -k.J=function(){return O(bh,this.k)};k.Eb=function(a,b){return new $g(this.k,eb(this.Wa,b),null)};k.D=function(){return Tg(this.Wa)};k.F=function(a,b){return new $g(b,this.Wa,this.p)};k.G=function(a,b){return new $g(this.k,Rc.c(this.Wa,b,null),null)}; -k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.t(null,c);case 3:return this.s(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.t(null,c)};a.c=function(a,c,d){return this.s(null,c,d)};return a}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.t(null,a)};k.a=function(a,b){return this.s(null,a,b)};var bh=new $g(null,Uf,0);$g.prototype[Ea]=function(){return uc(this)}; -function ah(a){this.ma=a;this.j=259;this.q=136}k=ah.prototype;k.call=function(){function a(a,b,c){return $a.c(this.ma,b,jd)===jd?c:b}function b(a,b){return $a.c(this.ma,b,jd)===jd?null:b}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+arguments.length);};c.a=b;c.c=a;return c}();k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))}; -k.b=function(a){return $a.c(this.ma,a,jd)===jd?null:a};k.a=function(a,b){return $a.c(this.ma,a,jd)===jd?b:a};k.t=function(a,b){return $a.c(this,b,null)};k.s=function(a,b,c){return $a.c(this.ma,b,jd)===jd?c:b};k.L=function(){return Q(this.ma)};k.Tb=function(a,b){this.ma=fe.a(this.ma,b);return this};k.Sa=function(a,b){this.ma=ee.c(this.ma,b,null);return this};k.Ta=function(){return new $g(null,Qb(this.ma),null)};function ch(a,b,c){this.k=a;this.ja=b;this.p=c;this.j=417730831;this.q=8192}k=ch.prototype; -k.toString=function(){return ec(this)};k.t=function(a,b){return $a.c(this,b,null)};k.s=function(a,b,c){a=Mg(this.ja,b);return null!=a?a.key:c};k.H=function(){return this.k};k.L=function(){return Q(this.ja)};k.ab=function(){return 0<Q(this.ja)?Oe.a(Yf,Gb(this.ja)):null};k.B=function(){var a=this.p;return null!=a?a:this.p=a=xc(this)};k.A=function(a,b){return ad(b)&&Q(this)===Q(b)&&Ee(function(a){return function(b){return nd(a,b)}}(this),b)};k.J=function(){return new ch(this.k,Na(this.ja),0)}; -k.Eb=function(a,b){return new ch(this.k,Sc.a(this.ja,b),null)};k.D=function(){return Tg(this.ja)};k.F=function(a,b){return new ch(b,this.ja,this.p)};k.G=function(a,b){return new ch(this.k,Rc.c(this.ja,b,null),null)};k.call=function(){var a=null,a=function(a,c,d){switch(arguments.length){case 2:return this.t(null,c);case 3:return this.s(null,c,d)}throw Error("Invalid arity: "+arguments.length);};a.a=function(a,c){return this.t(null,c)};a.c=function(a,c,d){return this.s(null,c,d)};return a}(); -k.apply=function(a,b){return this.call.apply(this,[this].concat(Fa(b)))};k.b=function(a){return this.t(null,a)};k.a=function(a,b){return this.s(null,a,b)};k.Hb=function(a,b){return Oe.a(Yf,Hb(this.ja,b))};k.Ib=function(a,b,c){return Oe.a(Yf,Ib(this.ja,b,c))};k.Gb=function(a,b){return b};k.Fb=function(){return Kb(this.ja)};var eh=new ch(null,Ng,0);ch.prototype[Ea]=function(){return uc(this)}; -function fh(a){a=D(a);if(null==a)return bh;if(a instanceof F&&0===a.m){a=a.e;a:{for(var b=0,c=Ob(bh);;)if(b<a.length)var d=b+1,c=c.Sa(null,a[b]),b=d;else{a=c;break a}a=void 0}return a.Ta(null)}for(d=Ob(bh);;)if(null!=a)b=a.T(null),d=d.Sa(null,a.N(null)),a=b;else return d.Ta(null)} -var gh=function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){return A.c(Ra,eh,a)}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}(),hh=function(){function a(a,d){var e=null;if(1<arguments.length){for(var e=0,f=Array(arguments.length-1);e<f.length;)f[e]=arguments[e+1],++e;e=new F(f,0)}return b.call(this,a,e)}function b(a,b){return A.c(Ra,new ch(null,Rg(a),0),b)} -a.i=1;a.f=function(a){var d=G(a);a=H(a);return b(d,a)};a.d=b;return a}();function Od(a){if(a&&(a.q&4096||a.lc))return a.name;if("string"===typeof a)return a;throw Error([z("Doesn't support name: "),z(a)].join(""));} -var ih=function(){function a(a,b,c){return(a.b?a.b(b):a.call(null,b))>(a.b?a.b(c):a.call(null,c))?b:c}var b=null,c=function(){function a(b,d,h,l){var m=null;if(3<arguments.length){for(var m=0,p=Array(arguments.length-3);m<p.length;)p[m]=arguments[m+3],++m;m=new F(p,0)}return c.call(this,b,d,h,m)}function c(a,d,e,l){return A.c(function(c,d){return b.c(a,c,d)},b.c(a,d,e),l)}a.i=3;a.f=function(a){var b=G(a);a=K(a);var d=G(a);a=K(a);var l=G(a);a=H(a);return c(b,d,l,a)};a.d=c;return a}(),b=function(b, -e,f,g){switch(arguments.length){case 2:return e;case 3:return a.call(this,b,e,f);default:var h=null;if(3<arguments.length){for(var h=0,l=Array(arguments.length-3);h<l.length;)l[h]=arguments[h+3],++h;h=new F(l,0)}return c.d(b,e,f,h)}throw Error("Invalid arity: "+arguments.length);};b.i=3;b.f=c.f;b.a=function(a,b){return b};b.c=a;b.d=c.d;return b}();function jh(a){this.e=a}jh.prototype.add=function(a){return this.e.push(a)};jh.prototype.size=function(){return this.e.length}; -jh.prototype.clear=function(){return this.e=[]}; -var kh=function(){function a(a,b,c){return new V(null,function(){var h=D(c);return h?M(Pe.a(a,h),d.c(a,b,Qe.a(b,h))):null},null,null)}function b(a,b){return d.c(a,a,b)}function c(a){return function(b){return function(c){return function(){function d(h,l){c.add(l);if(a===c.size()){var m=zf(c.e);c.clear();return b.a?b.a(h,m):b.call(null,h,m)}return h}function l(a){if(!t(0===c.e.length)){var d=zf(c.e);c.clear();a=Bc(b.a?b.a(a,d):b.call(null,a,d))}return b.b?b.b(a):b.call(null,a)}function m(){return b.l? -b.l():b.call(null)}var p=null,p=function(a,b){switch(arguments.length){case 0:return m.call(this);case 1:return l.call(this,a);case 2:return d.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};p.l=m;p.b=l;p.a=d;return p}()}(new jh([]))}}var d=null,d=function(d,f,g){switch(arguments.length){case 1:return c.call(this,d);case 2:return b.call(this,d,f);case 3:return a.call(this,d,f,g)}throw Error("Invalid arity: "+arguments.length);};d.b=c;d.a=b;d.c=a;return d}(),lh=function(){function a(a, -b){return new V(null,function(){var f=D(b);if(f){var g;g=G(f);g=a.b?a.b(g):a.call(null,g);f=t(g)?M(G(f),c.a(a,H(f))):null}else f=null;return f},null,null)}function b(a){return function(b){return function(){function c(f,g){return t(a.b?a.b(g):a.call(null,g))?b.a?b.a(f,g):b.call(null,f,g):new yc(f)}function g(a){return b.b?b.b(a):b.call(null,a)}function h(){return b.l?b.l():b.call(null)}var l=null,l=function(a,b){switch(arguments.length){case 0:return h.call(this);case 1:return g.call(this,a);case 2:return c.call(this, -a,b)}throw Error("Invalid arity: "+arguments.length);};l.l=h;l.b=g;l.a=c;return l}()}}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}();function mh(a,b,c){return function(d){var e=Kb(a);d=Jb(a,d);e=e.a?e.a(d,c):e.call(null,d,c);return b.a?b.a(e,0):b.call(null,e,0)}} -var nh=function(){function a(a,b,c,g,h){var l=Ib(a,c,!0);if(t(l)){var m=R.c(l,0,null);return lh.a(mh(a,g,h),t(mh(a,b,c).call(null,m))?l:K(l))}return null}function b(a,b,c){var g=mh(a,b,c),h;a:{h=[Ad,Bd];var l=h.length;if(l<=Vf)for(var m=0,p=Ob(Uf);;)if(m<l)var q=m+1,p=Rb(p,h[m],null),m=q;else{h=new $g(null,Qb(p),null);break a}else for(m=0,p=Ob(bh);;)if(m<l)q=m+1,p=Pb(p,h[m]),m=q;else{h=Qb(p);break a}h=void 0}return t(h.call(null,b))?(a=Ib(a,c,!0),t(a)?(b=R.c(a,0,null),t(g.b?g.b(b):g.call(null,b))? -a:K(a)):null):lh.a(g,Hb(a,!0))}var c=null,c=function(c,e,f,g,h){switch(arguments.length){case 3:return b.call(this,c,e,f);case 5:return a.call(this,c,e,f,g,h)}throw Error("Invalid arity: "+arguments.length);};c.c=b;c.r=a;return c}();function oh(a,b,c){this.m=a;this.end=b;this.step=c}oh.prototype.ga=function(){return 0<this.step?this.m<this.end:this.m>this.end};oh.prototype.next=function(){var a=this.m;this.m+=this.step;return a}; -function ph(a,b,c,d,e){this.k=a;this.start=b;this.end=c;this.step=d;this.p=e;this.j=32375006;this.q=8192}k=ph.prototype;k.toString=function(){return ec(this)};k.Q=function(a,b){if(b<Ma(this))return this.start+b*this.step;if(this.start>this.end&&0===this.step)return this.start;throw Error("Index out of bounds");};k.$=function(a,b,c){return b<Ma(this)?this.start+b*this.step:this.start>this.end&&0===this.step?this.start:c};k.vb=!0;k.fb=function(){return new oh(this.start,this.end,this.step)};k.H=function(){return this.k}; -k.T=function(){return 0<this.step?this.start+this.step<this.end?new ph(this.k,this.start+this.step,this.end,this.step,null):null:this.start+this.step>this.end?new ph(this.k,this.start+this.step,this.end,this.step,null):null};k.L=function(){if(Aa(Cb(this)))return 0;var a=(this.end-this.start)/this.step;return Math.ceil.b?Math.ceil.b(a):Math.ceil.call(null,a)};k.B=function(){var a=this.p;return null!=a?a:this.p=a=wc(this)};k.A=function(a,b){return Ic(this,b)};k.J=function(){return O(J,this.k)}; -k.R=function(a,b){return Cc.a(this,b)};k.O=function(a,b,c){for(a=this.start;;)if(0<this.step?a<this.end:a>this.end){var d=a;c=b.a?b.a(c,d):b.call(null,c,d);if(Ac(c))return b=c,L.b?L.b(b):L.call(null,b);a+=this.step}else return c};k.N=function(){return null==Cb(this)?null:this.start};k.S=function(){return null!=Cb(this)?new ph(this.k,this.start+this.step,this.end,this.step,null):J};k.D=function(){return 0<this.step?this.start<this.end?this:null:this.start>this.end?this:null}; -k.F=function(a,b){return new ph(b,this.start,this.end,this.step,this.p)};k.G=function(a,b){return M(b,this)};ph.prototype[Ea]=function(){return uc(this)}; -var qh=function(){function a(a,b,c){return new ph(null,a,b,c,null)}function b(a,b){return e.c(a,b,1)}function c(a){return e.c(0,a,1)}function d(){return e.c(0,Number.MAX_VALUE,1)}var e=null,e=function(e,g,h){switch(arguments.length){case 0:return d.call(this);case 1:return c.call(this,e);case 2:return b.call(this,e,g);case 3:return a.call(this,e,g,h)}throw Error("Invalid arity: "+arguments.length);};e.l=d;e.b=c;e.a=b;e.c=a;return e}(),rh=function(){function a(a,b){return new V(null,function(){var f= -D(b);return f?M(G(f),c.a(a,Qe.a(a,f))):null},null,null)}function b(a){return function(b){return function(c){return function(){function g(g,h){var l=c.bb(0,c.Ra(null)+1),m=Cd(l,a);return 0===l-a*m?b.a?b.a(g,h):b.call(null,g,h):g}function h(a){return b.b?b.b(a):b.call(null,a)}function l(){return b.l?b.l():b.call(null)}var m=null,m=function(a,b){switch(arguments.length){case 0:return l.call(this);case 1:return h.call(this,a);case 2:return g.call(this,a,b)}throw Error("Invalid arity: "+arguments.length); -};m.l=l;m.b=h;m.a=g;return m}()}(new Me(-1))}}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),th=function(){function a(a,b){return new V(null,function(){var f=D(b);if(f){var g=G(f),h=a.b?a.b(g):a.call(null,g),g=M(g,lh.a(function(b,c){return function(b){return sc.a(c,a.b?a.b(b):a.call(null,b))}}(g,h,f,f),K(f)));return M(g,c.a(a,D(Qe.a(Q(g),f))))}return null},null, -null)}function b(a){return function(b){return function(c,g){return function(){function h(h,l){var m=L.b?L.b(g):L.call(null,g),p=a.b?a.b(l):a.call(null,l);ac(g,p);if(Nd(m,sh)||sc.a(p,m))return c.add(l),h;m=zf(c.e);c.clear();m=b.a?b.a(h,m):b.call(null,h,m);Ac(m)||c.add(l);return m}function l(a){if(!t(0===c.e.length)){var d=zf(c.e);c.clear();a=Bc(b.a?b.a(a,d):b.call(null,a,d))}return b.b?b.b(a):b.call(null,a)}function m(){return b.l?b.l():b.call(null)}var p=null,p=function(a,b){switch(arguments.length){case 0:return m.call(this); -case 1:return l.call(this,a);case 2:return h.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};p.l=m;p.b=l;p.a=h;return p}()}(new jh([]),new Me(sh))}}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),uh=function(){function a(a,b){for(;;)if(D(b)&&0<a){var c=a-1,g=K(b);a=c;b=g}else return null}function b(a){for(;;)if(D(a))a=K(a);else return null}var c= -null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(),vh=function(){function a(a,b){uh.a(a,b);return b}function b(a){uh.b(a);return a}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}(); -function wh(a,b,c,d,e,f,g){var h=ma;try{ma=null==ma?null:ma-1;if(null!=ma&&0>ma)return Lb(a,"#");Lb(a,c);if(D(g)){var l=G(g);b.c?b.c(l,a,f):b.call(null,l,a,f)}for(var m=K(g),p=za.b(f)-1;;)if(!m||null!=p&&0===p){D(m)&&0===p&&(Lb(a,d),Lb(a,"..."));break}else{Lb(a,d);var q=G(m);c=a;g=f;b.c?b.c(q,c,g):b.call(null,q,c,g);var s=K(m);c=p-1;m=s;p=c}return Lb(a,e)}finally{ma=h}} -var xh=function(){function a(a,d){var e=null;if(1<arguments.length){for(var e=0,f=Array(arguments.length-1);e<f.length;)f[e]=arguments[e+1],++e;e=new F(f,0)}return b.call(this,a,e)}function b(a,b){for(var e=D(b),f=null,g=0,h=0;;)if(h<g){var l=f.Q(null,h);Lb(a,l);h+=1}else if(e=D(e))f=e,fd(f)?(e=Yb(f),g=Zb(f),f=e,l=Q(e),e=g,g=l):(l=G(f),Lb(a,l),e=K(f),f=null,g=0),h=0;else return null}a.i=1;a.f=function(a){var d=G(a);a=H(a);return b(d,a)};a.d=b;return a}(),yh={'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f", -"\n":"\\n","\r":"\\r","\t":"\\t"};function zh(a){return[z('"'),z(a.replace(RegExp('[\\\\"\b\f\n\r\t]',"g"),function(a){return yh[a]})),z('"')].join("")} -var $=function Ah(b,c,d){if(null==b)return Lb(c,"nil");if(void 0===b)return Lb(c,"#\x3cundefined\x3e");t(function(){var c=S.a(d,wa);return t(c)?(c=b?b.j&131072||b.kc?!0:b.j?!1:w(rb,b):w(rb,b))?Vc(b):c:c}())&&(Lb(c,"^"),Ah(Vc(b),c,d),Lb(c," "));if(null==b)return Lb(c,"nil");if(b.Yb)return b.nc(c);if(b&&(b.j&2147483648||b.I))return b.v(null,c,d);if(Ba(b)===Boolean||"number"===typeof b)return Lb(c,""+z(b));if(null!=b&&b.constructor===Object){Lb(c,"#js ");var e=Oe.a(function(c){return new W(null,2,5, -uf,[Pd.b(c),b[c]],null)},gd(b));return Bh.n?Bh.n(e,Ah,c,d):Bh.call(null,e,Ah,c,d)}return b instanceof Array?wh(c,Ah,"#js ["," ","]",d,b):t("string"==typeof b)?t(ua.b(d))?Lb(c,zh(b)):Lb(c,b):Tc(b)?xh.d(c,Kc(["#\x3c",""+z(b),"\x3e"],0)):b instanceof Date?(e=function(b,c){for(var d=""+z(b);;)if(Q(d)<c)d=[z("0"),z(d)].join("");else return d},xh.d(c,Kc(['#inst "',""+z(b.getUTCFullYear()),"-",e(b.getUTCMonth()+1,2),"-",e(b.getUTCDate(),2),"T",e(b.getUTCHours(),2),":",e(b.getUTCMinutes(),2),":",e(b.getUTCSeconds(), -2),".",e(b.getUTCMilliseconds(),3),"-",'00:00"'],0))):b instanceof RegExp?xh.d(c,Kc(['#"',b.source,'"'],0)):(b?b.j&2147483648||b.I||(b.j?0:w(Mb,b)):w(Mb,b))?Nb(b,c,d):xh.d(c,Kc(["#\x3c",""+z(b),"\x3e"],0))},Ch=function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){var b=oa();if(Yc(a))b="";else{var e=z,f=new fa;a:{var g=new dc(f);$(G(a),g,b);a=D(K(a));for(var h=null,l=0, -m=0;;)if(m<l){var p=h.Q(null,m);Lb(g," ");$(p,g,b);m+=1}else if(a=D(a))h=a,fd(h)?(a=Yb(h),l=Zb(h),h=a,p=Q(a),a=l,l=p):(p=G(h),Lb(g," "),$(p,g,b),a=K(h),h=null,l=0),m=0;else break a}b=""+e(f)}return b}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}();function Bh(a,b,c,d){return wh(c,function(a,c,d){var h=hb(a);b.c?b.c(h,c,d):b.call(null,h,c,d);Lb(c," ");a=ib(a);return b.c?b.c(a,c,d):b.call(null,a,c,d)},"{",", ","}",d,D(a))}Me.prototype.I=!0; -Me.prototype.v=function(a,b,c){Lb(b,"#\x3cVolatile: ");$(this.state,b,c);return Lb(b,"\x3e")};F.prototype.I=!0;F.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};V.prototype.I=!0;V.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};wg.prototype.I=!0;wg.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};pg.prototype.I=!0;pg.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Z.prototype.I=!0; -Z.prototype.v=function(a,b,c){return wh(b,$,"["," ","]",c,this)};Rf.prototype.I=!0;Rf.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};ch.prototype.I=!0;ch.prototype.v=function(a,b,c){return wh(b,$,"#{"," ","}",c,this)};Bf.prototype.I=!0;Bf.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Ld.prototype.I=!0;Ld.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Hc.prototype.I=!0;Hc.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)}; -rg.prototype.I=!0;rg.prototype.v=function(a,b,c){return Bh(this,$,b,c)};qg.prototype.I=!0;qg.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Df.prototype.I=!0;Df.prototype.v=function(a,b,c){return wh(b,$,"["," ","]",c,this)};Lg.prototype.I=!0;Lg.prototype.v=function(a,b,c){return Bh(this,$,b,c)};$g.prototype.I=!0;$g.prototype.v=function(a,b,c){return wh(b,$,"#{"," ","}",c,this)};Vd.prototype.I=!0;Vd.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Ug.prototype.I=!0; -Ug.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};X.prototype.I=!0;X.prototype.v=function(a,b,c){return wh(b,$,"["," ","]",c,this)};W.prototype.I=!0;W.prototype.v=function(a,b,c){return wh(b,$,"["," ","]",c,this)};Kf.prototype.I=!0;Kf.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Hd.prototype.I=!0;Hd.prototype.v=function(a,b){return Lb(b,"()")};ze.prototype.I=!0;ze.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Lf.prototype.I=!0; -Lf.prototype.v=function(a,b,c){return wh(b,$,"#queue ["," ","]",c,D(this))};pa.prototype.I=!0;pa.prototype.v=function(a,b,c){return Bh(this,$,b,c)};ph.prototype.I=!0;ph.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Sg.prototype.I=!0;Sg.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Fd.prototype.I=!0;Fd.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};W.prototype.sb=!0;W.prototype.tb=function(a,b){return pd.a(this,b)};Df.prototype.sb=!0; -Df.prototype.tb=function(a,b){return pd.a(this,b)};U.prototype.sb=!0;U.prototype.tb=function(a,b){return Md(this,b)};qc.prototype.sb=!0;qc.prototype.tb=function(a,b){return pc(this,b)};var Dh=function(){function a(a,d,e){var f=null;if(2<arguments.length){for(var f=0,g=Array(arguments.length-2);f<g.length;)g[f]=arguments[f+2],++f;f=new F(g,0)}return b.call(this,a,d,f)}function b(a,b,e){return a.k=T.c(b,a.k,e)}a.i=2;a.f=function(a){var d=G(a);a=K(a);var e=G(a);a=H(a);return b(d,e,a)};a.d=b;return a}(); -function Eh(a){return function(b,c){var d=a.a?a.a(b,c):a.call(null,b,c);return Ac(d)?new yc(d):d}} -function Ve(a){return function(b){return function(){function c(a,c){return A.c(b,a,c)}function d(b){return a.b?a.b(b):a.call(null,b)}function e(){return a.l?a.l():a.call(null)}var f=null,f=function(a,b){switch(arguments.length){case 0:return e.call(this);case 1:return d.call(this,a);case 2:return c.call(this,a,b)}throw Error("Invalid arity: "+arguments.length);};f.l=e;f.b=d;f.a=c;return f}()}(Eh(a))} -var Fh=function(){function a(a){return Ce.a(c.l(),a)}function b(){return function(a){return function(b){return function(){function c(f,g){var h=L.b?L.b(b):L.call(null,b);ac(b,g);return sc.a(h,g)?f:a.a?a.a(f,g):a.call(null,f,g)}function g(b){return a.b?a.b(b):a.call(null,b)}function h(){return a.l?a.l():a.call(null)}var l=null,l=function(a,b){switch(arguments.length){case 0:return h.call(this);case 1:return g.call(this,a);case 2:return c.call(this,a,b)}throw Error("Invalid arity: "+arguments.length); -};l.l=h;l.b=g;l.a=c;return l}()}(new Me(sh))}}var c=null,c=function(c){switch(arguments.length){case 0:return b.call(this);case 1:return a.call(this,c)}throw Error("Invalid arity: "+arguments.length);};c.l=b;c.b=a;return c}();function Gh(a,b){this.fa=a;this.Zb=b;this.q=0;this.j=2173173760}Gh.prototype.v=function(a,b,c){return wh(b,$,"("," ",")",c,this)};Gh.prototype.O=function(a,b,c){return wd.n(this.fa,b,c,this.Zb)};Gh.prototype.D=function(){return D(Ce.a(this.fa,this.Zb))};Gh.prototype[Ea]=function(){return uc(this)}; -var Hh={};function Ih(a){if(a?a.gc:a)return a.gc(a);var b;b=Ih[n(null==a?null:a)];if(!b&&(b=Ih._,!b))throw x("IEncodeJS.-clj-\x3ejs",a);return b.call(null,a)}function Jh(a){return(a?t(t(null)?null:a.fc)||(a.yb?0:w(Hh,a)):w(Hh,a))?Ih(a):"string"===typeof a||"number"===typeof a||a instanceof U||a instanceof qc?Kh.b?Kh.b(a):Kh.call(null,a):Ch.d(Kc([a],0))} -var Kh=function Lh(b){if(null==b)return null;if(b?t(t(null)?null:b.fc)||(b.yb?0:w(Hh,b)):w(Hh,b))return Ih(b);if(b instanceof U)return Od(b);if(b instanceof qc)return""+z(b);if(dd(b)){var c={};b=D(b);for(var d=null,e=0,f=0;;)if(f<e){var g=d.Q(null,f),h=R.c(g,0,null),g=R.c(g,1,null);c[Jh(h)]=Lh(g);f+=1}else if(b=D(b))fd(b)?(e=Yb(b),b=Zb(b),d=e,e=Q(e)):(e=G(b),d=R.c(e,0,null),e=R.c(e,1,null),c[Jh(d)]=Lh(e),b=K(b),d=null,e=0),f=0;else break;return c}if($c(b)){c=[];b=D(Oe.a(Lh,b));d=null;for(f=e=0;;)if(f< -e)h=d.Q(null,f),c.push(h),f+=1;else if(b=D(b))d=b,fd(d)?(b=Yb(d),f=Zb(d),d=b,e=Q(b),b=f):(b=G(d),c.push(b),b=K(d),d=null,e=0),f=0;else break;return c}return b},Mh={};function Nh(a,b){if(a?a.ec:a)return a.ec(a,b);var c;c=Nh[n(null==a?null:a)];if(!c&&(c=Nh._,!c))throw x("IEncodeClojure.-js-\x3eclj",a);return c.call(null,a,b)} -var Ph=function(){function a(a){return b.d(a,Kc([new pa(null,1,[Oh,!1],null)],0))}var b=null,c=function(){function a(c,d){var h=null;if(1<arguments.length){for(var h=0,l=Array(arguments.length-1);h<l.length;)l[h]=arguments[h+1],++h;h=new F(l,0)}return b.call(this,c,h)}function b(a,c){var d=kd(c)?T.a(Og,c):c,e=S.a(d,Oh);return function(a,b,d,e){return function v(f){return(f?t(t(null)?null:f.uc)||(f.yb?0:w(Mh,f)):w(Mh,f))?Nh(f,T.a(Pg,c)):kd(f)?vh.b(Oe.a(v,f)):$c(f)?af.a(Oc(f),Oe.a(v,f)):f instanceof -Array?zf(Oe.a(v,f)):Ba(f)===Object?af.a(Uf,function(){return function(a,b,c,d){return function Pa(e){return new V(null,function(a,b,c,d){return function(){for(;;){var a=D(e);if(a){if(fd(a)){var b=Yb(a),c=Q(b),g=Td(c);return function(){for(var a=0;;)if(a<c){var e=C.a(b,a),h=g,l=uf,m;m=e;m=d.b?d.b(m):d.call(null,m);e=new W(null,2,5,l,[m,v(f[e])],null);h.add(e);a+=1}else return!0}()?Wd(g.ca(),Pa(Zb(a))):Wd(g.ca(),null)}var h=G(a);return M(new W(null,2,5,uf,[function(){var a=h;return d.b?d.b(a):d.call(null, -a)}(),v(f[h])],null),Pa(H(a)))}return null}}}(a,b,c,d),null,null)}}(a,b,d,e)(gd(f))}()):f}}(c,d,e,t(e)?Pd:z)(a)}a.i=1;a.f=function(a){var c=G(a);a=H(a);return b(c,a)};a.d=b;return a}(),b=function(b,e){switch(arguments.length){case 1:return a.call(this,b);default:var f=null;if(1<arguments.length){for(var f=0,g=Array(arguments.length-1);f<g.length;)g[f]=arguments[f+1],++f;f=new F(g,0)}return c.d(b,f)}throw Error("Invalid arity: "+arguments.length);};b.i=1;b.f=c.f;b.b=a;b.d=c.d;return b}();var wa=new U(null,"meta","meta",1499536964),ya=new U(null,"dup","dup",556298533),sh=new U("cljs.core","none","cljs.core/none",926646439),pe=new U(null,"file","file",-1269645878),le=new U(null,"end-column","end-column",1425389514),sa=new U(null,"flush-on-newline","flush-on-newline",-151457939),ne=new U(null,"column","column",2078222095),ua=new U(null,"readably","readably",1129599760),oe=new U(null,"line","line",212345235),za=new U(null,"print-length","print-length",1931866356),me=new U(null,"end-line", -"end-line",1837326455),Oh=new U(null,"keywordize-keys","keywordize-keys",1310784252),Zg=new U("cljs.core","not-found","cljs.core/not-found",-1572889185);function Qh(a,b){var c=T.c(ih,a,b);return M(c,Ye.a(function(a){return function(b){return a===b}}(c),b))} -var Rh=function(){function a(a,b){return Q(a)<Q(b)?A.c(Nc,b,a):A.c(Nc,a,b)}var b=null,c=function(){function a(c,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return b.call(this,c,d,l)}function b(a,c,d){a=Qh(Q,Nc.d(d,c,Kc([a],0)));return A.c(af,G(a),H(a))}a.i=2;a.f=function(a){var c=G(a);a=K(a);var d=G(a);a=H(a);return b(c,d,a)};a.d=b;return a}(),b=function(b,e,f){switch(arguments.length){case 0:return bh;case 1:return b; -case 2:return a.call(this,b,e);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.l=function(){return bh};b.b=function(a){return a};b.a=a;b.d=c.d;return b}(),Sh=function(){function a(a,b){for(;;)if(Q(b)<Q(a)){var c=a;a=b;b=c}else return A.c(function(a,b){return function(a,c){return nd(b,c)?a:Xc.a(a,c)}}(a,b),a,a)}var b=null,c=function(){function a(b, -d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return c.call(this,b,d,l)}function c(a,d,e){a=Qh(function(a){return-Q(a)},Nc.d(e,d,Kc([a],0)));return A.c(b,G(a),H(a))}a.i=2;a.f=function(a){var b=G(a);a=K(a);var d=G(a);a=H(a);return c(b,d,a)};a.d=c;return a}(),b=function(b,e,f){switch(arguments.length){case 1:return b;case 2:return a.call(this,b,e);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length- -2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.b=function(a){return a};b.a=a;b.d=c.d;return b}(),Th=function(){function a(a,b){return Q(a)<Q(b)?A.c(function(a,c){return nd(b,c)?Xc.a(a,c):a},a,a):A.c(Xc,a,b)}var b=null,c=function(){function a(b,d,h){var l=null;if(2<arguments.length){for(var l=0,m=Array(arguments.length-2);l<m.length;)m[l]=arguments[l+2],++l;l=new F(m,0)}return c.call(this,b,d,l)}function c(a,d, -e){return A.c(b,a,Nc.a(e,d))}a.i=2;a.f=function(a){var b=G(a);a=K(a);var d=G(a);a=H(a);return c(b,d,a)};a.d=c;return a}(),b=function(b,e,f){switch(arguments.length){case 1:return b;case 2:return a.call(this,b,e);default:var g=null;if(2<arguments.length){for(var g=0,h=Array(arguments.length-2);g<h.length;)h[g]=arguments[g+2],++g;g=new F(h,0)}return c.d(b,e,g)}throw Error("Invalid arity: "+arguments.length);};b.i=2;b.f=c.f;b.b=function(a){return a};b.a=a;b.d=c.d;return b}(); -function Uh(a,b){return A.c(function(b,d){var e=R.c(d,0,null),f=R.c(d,1,null);return nd(a,e)?Rc.c(b,f,S.a(a,e)):b},T.c(Sc,a,Tg(b)),b)}function Vh(a,b){return A.c(function(a,d){var e=Yg(d,b);return Rc.c(a,e,Nc.a(S.c(a,e,bh),d))},Uf,a)}function Wh(a){return A.c(function(a,c){var d=R.c(c,0,null),e=R.c(c,1,null);return Rc.c(a,e,d)},Uf,a)} -var Xh=function(){function a(a,b,c){a=Q(a)<=Q(b)?new W(null,3,5,uf,[a,b,Wh(c)],null):new W(null,3,5,uf,[b,a,c],null);b=R.c(a,0,null);c=R.c(a,1,null);var g=R.c(a,2,null),h=Vh(b,Vg(g));return A.c(function(a,b,c,d,e){return function(f,g){var h=function(){var a=Uh(Yg(g,Tg(d)),d);return e.b?e.b(a):e.call(null,a)}();return t(h)?A.c(function(){return function(a,b){return Nc.a(a,Wg.d(Kc([b,g],0)))}}(h,a,b,c,d,e),f,h):f}}(a,b,c,g,h),bh,c)}function b(a,b){if(D(a)&&D(b)){var c=Sh.a(fh(Tg(G(a))),fh(Tg(G(b)))), -g=Q(a)<=Q(b)?new W(null,2,5,uf,[a,b],null):new W(null,2,5,uf,[b,a],null),h=R.c(g,0,null),l=R.c(g,1,null),m=Vh(h,c);return A.c(function(a,b,c,d,e){return function(f,g){var h=function(){var b=Yg(g,a);return e.b?e.b(b):e.call(null,b)}();return t(h)?A.c(function(){return function(a,b){return Nc.a(a,Wg.d(Kc([b,g],0)))}}(h,a,b,c,d,e),f,h):f}}(c,g,h,l,m),bh,l)}return bh}var c=null,c=function(c,e,f){switch(arguments.length){case 2:return b.call(this,c,e);case 3:return a.call(this,c,e,f)}throw Error("Invalid arity: "+ -arguments.length);};c.a=b;c.c=a;return c}();r("mori.apply",T);r("mori.apply.f2",T.a);r("mori.apply.f3",T.c);r("mori.apply.f4",T.n);r("mori.apply.f5",T.r);r("mori.apply.fn",T.K);r("mori.count",Q);r("mori.distinct",function(a){return function c(a,e){return new V(null,function(){return function(a,d){for(;;){var e=a,l=R.c(e,0,null);if(e=D(e))if(nd(d,l))l=H(e),e=d,a=l,d=e;else return M(l,c(H(e),Nc.a(d,l)));else return null}}.call(null,a,e)},null,null)}(a,bh)});r("mori.empty",Oc);r("mori.first",G);r("mori.second",Lc);r("mori.next",K); -r("mori.rest",H);r("mori.seq",D);r("mori.conj",Nc);r("mori.conj.f0",Nc.l);r("mori.conj.f1",Nc.b);r("mori.conj.f2",Nc.a);r("mori.conj.fn",Nc.K);r("mori.cons",M);r("mori.find",function(a,b){return null!=a&&bd(a)&&nd(a,b)?new W(null,2,5,uf,[b,S.a(a,b)],null):null});r("mori.nth",R);r("mori.nth.f2",R.a);r("mori.nth.f3",R.c);r("mori.last",function(a){for(;;){var b=K(a);if(null!=b)a=b;else return G(a)}});r("mori.assoc",Rc);r("mori.assoc.f3",Rc.c);r("mori.assoc.fn",Rc.K);r("mori.dissoc",Sc); -r("mori.dissoc.f1",Sc.b);r("mori.dissoc.f2",Sc.a);r("mori.dissoc.fn",Sc.K);r("mori.getIn",cf);r("mori.getIn.f2",cf.a);r("mori.getIn.f3",cf.c);r("mori.updateIn",df);r("mori.updateIn.f3",df.c);r("mori.updateIn.f4",df.n);r("mori.updateIn.f5",df.r);r("mori.updateIn.f6",df.P);r("mori.updateIn.fn",df.K);r("mori.assocIn",function Yh(b,c,d){var e=R.c(c,0,null);return(c=Ed(c))?Rc.c(b,e,Yh(S.a(b,e),c,d)):Rc.c(b,e,d)});r("mori.fnil",Ke);r("mori.fnil.f2",Ke.a);r("mori.fnil.f3",Ke.c);r("mori.fnil.f4",Ke.n); -r("mori.disj",Xc);r("mori.disj.f1",Xc.b);r("mori.disj.f2",Xc.a);r("mori.disj.fn",Xc.K);r("mori.pop",function(a){return null==a?null:mb(a)});r("mori.peek",Wc);r("mori.hash",nc);r("mori.get",S);r("mori.get.f2",S.a);r("mori.get.f3",S.c);r("mori.hasKey",nd);r("mori.isEmpty",Yc);r("mori.reverse",Jd);r("mori.take",Pe);r("mori.take.f1",Pe.b);r("mori.take.f2",Pe.a);r("mori.drop",Qe);r("mori.drop.f1",Qe.b);r("mori.drop.f2",Qe.a);r("mori.takeNth",rh);r("mori.takeNth.f1",rh.b);r("mori.takeNth.f2",rh.a); -r("mori.partition",bf);r("mori.partition.f2",bf.a);r("mori.partition.f3",bf.c);r("mori.partition.f4",bf.n);r("mori.partitionAll",kh);r("mori.partitionAll.f1",kh.b);r("mori.partitionAll.f2",kh.a);r("mori.partitionAll.f3",kh.c);r("mori.partitionBy",th);r("mori.partitionBy.f1",th.b);r("mori.partitionBy.f2",th.a);r("mori.iterate",function Zh(b,c){return M(c,new V(null,function(){return Zh(b,b.b?b.b(c):b.call(null,c))},null,null))});r("mori.into",af);r("mori.into.f2",af.a);r("mori.into.f3",af.c); -r("mori.merge",Wg);r("mori.mergeWith",Xg);r("mori.subvec",Cf);r("mori.subvec.f2",Cf.a);r("mori.subvec.f3",Cf.c);r("mori.takeWhile",lh);r("mori.takeWhile.f1",lh.b);r("mori.takeWhile.f2",lh.a);r("mori.dropWhile",Re);r("mori.dropWhile.f1",Re.b);r("mori.dropWhile.f2",Re.a);r("mori.groupBy",function(a,b){return ce(A.c(function(b,d){var e=a.b?a.b(d):a.call(null,d);return ee.c(b,e,Nc.a(S.c(b,e,Mc),d))},Ob(Uf),b))});r("mori.interpose",function(a,b){return Qe.a(1,Ue.a(Se.b(a),b))});r("mori.interleave",Ue); -r("mori.interleave.f2",Ue.a);r("mori.interleave.fn",Ue.K);r("mori.concat",ae);r("mori.concat.f0",ae.l);r("mori.concat.f1",ae.b);r("mori.concat.f2",ae.a);r("mori.concat.fn",ae.K);function $e(a){return a instanceof Array||cd(a)}r("mori.flatten",function(a){return Xe.a(function(a){return!$e(a)},H(Ze(a)))});r("mori.lazySeq",function(a){return new V(null,a,null,null)});r("mori.keys",Tg);r("mori.selectKeys",Yg);r("mori.vals",Vg);r("mori.primSeq",Jc);r("mori.primSeq.f1",Jc.b);r("mori.primSeq.f2",Jc.a); -r("mori.map",Oe);r("mori.map.f1",Oe.b);r("mori.map.f2",Oe.a);r("mori.map.f3",Oe.c);r("mori.map.f4",Oe.n);r("mori.map.fn",Oe.K); -r("mori.mapIndexed",function(a,b){return function d(b,f){return new V(null,function(){var g=D(f);if(g){if(fd(g)){for(var h=Yb(g),l=Q(h),m=Td(l),p=0;;)if(p<l)Xd(m,function(){var d=b+p,f=C.a(h,p);return a.a?a.a(d,f):a.call(null,d,f)}()),p+=1;else break;return Wd(m.ca(),d(b+l,Zb(g)))}return M(function(){var d=G(g);return a.a?a.a(b,d):a.call(null,b,d)}(),d(b+1,H(g)))}return null},null,null)}(0,b)});r("mori.mapcat",We);r("mori.mapcat.f1",We.b);r("mori.mapcat.fn",We.K);r("mori.reduce",A); -r("mori.reduce.f2",A.a);r("mori.reduce.f3",A.c);r("mori.reduceKV",function(a,b,c){return null!=c?xb(c,a,b):b});r("mori.keep",Le);r("mori.keep.f1",Le.b);r("mori.keep.f2",Le.a);r("mori.keepIndexed",Ne);r("mori.keepIndexed.f1",Ne.b);r("mori.keepIndexed.f2",Ne.a);r("mori.filter",Xe);r("mori.filter.f1",Xe.b);r("mori.filter.f2",Xe.a);r("mori.remove",Ye);r("mori.remove.f1",Ye.b);r("mori.remove.f2",Ye.a);r("mori.some",Fe);r("mori.every",Ee);r("mori.equals",sc);r("mori.equals.f1",sc.b); -r("mori.equals.f2",sc.a);r("mori.equals.fn",sc.K);r("mori.range",qh);r("mori.range.f0",qh.l);r("mori.range.f1",qh.b);r("mori.range.f2",qh.a);r("mori.range.f3",qh.c);r("mori.repeat",Se);r("mori.repeat.f1",Se.b);r("mori.repeat.f2",Se.a);r("mori.repeatedly",Te);r("mori.repeatedly.f1",Te.b);r("mori.repeatedly.f2",Te.a);r("mori.sort",sd);r("mori.sort.f1",sd.b);r("mori.sort.f2",sd.a);r("mori.sortBy",td);r("mori.sortBy.f2",td.a);r("mori.sortBy.f3",td.c);r("mori.intoArray",Ia);r("mori.intoArray.f1",Ia.b); -r("mori.intoArray.f2",Ia.a);r("mori.subseq",nh);r("mori.subseq.f3",nh.c);r("mori.subseq.f5",nh.r);r("mori.dedupe",Fh);r("mori.dedupe.f0",Fh.l);r("mori.dedupe.f1",Fh.b);r("mori.transduce",wd);r("mori.transduce.f3",wd.c);r("mori.transduce.f4",wd.n);r("mori.eduction",function(a,b){return new Gh(a,b)});r("mori.sequence",Ce);r("mori.sequence.f1",Ce.b);r("mori.sequence.f2",Ce.a);r("mori.sequence.fn",Ce.K);r("mori.completing",vd);r("mori.completing.f1",vd.b);r("mori.completing.f2",vd.a);r("mori.list",Kd); -r("mori.vector",Af);r("mori.hashMap",Pg);r("mori.set",fh);r("mori.sortedSet",gh);r("mori.sortedSetBy",hh);r("mori.sortedMap",Qg);r("mori.sortedMapBy",Rg);r("mori.queue",function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){return af.a?af.a(Mf,a):af.call(null,Mf,a)}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}());r("mori.keyword",Pd);r("mori.keyword.f1",Pd.b); -r("mori.keyword.f2",Pd.a);r("mori.symbol",rc);r("mori.symbol.f1",rc.b);r("mori.symbol.f2",rc.a);r("mori.zipmap",function(a,b){for(var c=Ob(Uf),d=D(a),e=D(b);;)if(d&&e)c=ee.c(c,G(d),G(e)),d=K(d),e=K(e);else return Qb(c)});r("mori.isList",function(a){return a?a.j&33554432||a.wc?!0:a.j?!1:w(Eb,a):w(Eb,a)});r("mori.isSeq",kd);r("mori.isVector",ed);r("mori.isMap",dd);r("mori.isSet",ad);r("mori.isKeyword",function(a){return a instanceof U});r("mori.isSymbol",function(a){return a instanceof qc}); -r("mori.isCollection",$c);r("mori.isSequential",cd);r("mori.isAssociative",bd);r("mori.isCounted",Ec);r("mori.isIndexed",Fc);r("mori.isReduceable",function(a){return a?a.j&524288||a.Sb?!0:a.j?!1:w(vb,a):w(vb,a)});r("mori.isSeqable",ld);r("mori.isReversible",Id);r("mori.union",Rh);r("mori.union.f0",Rh.l);r("mori.union.f1",Rh.b);r("mori.union.f2",Rh.a);r("mori.union.fn",Rh.K);r("mori.intersection",Sh);r("mori.intersection.f1",Sh.b);r("mori.intersection.f2",Sh.a);r("mori.intersection.fn",Sh.K); -r("mori.difference",Th);r("mori.difference.f1",Th.b);r("mori.difference.f2",Th.a);r("mori.difference.fn",Th.K);r("mori.join",Xh);r("mori.join.f2",Xh.a);r("mori.join.f3",Xh.c);r("mori.index",Vh);r("mori.project",function(a,b){return fh(Oe.a(function(a){return Yg(a,b)},a))});r("mori.mapInvert",Wh);r("mori.rename",function(a,b){return fh(Oe.a(function(a){return Uh(a,b)},a))});r("mori.renameKeys",Uh);r("mori.isSubset",function(a,b){return Q(a)<=Q(b)&&Ee(function(a){return nd(b,a)},a)}); -r("mori.isSuperset",function(a,b){return Q(a)>=Q(b)&&Ee(function(b){return nd(a,b)},b)});r("mori.notEquals",je);r("mori.notEquals.f1",je.b);r("mori.notEquals.f2",je.a);r("mori.notEquals.fn",je.K);r("mori.gt",Ad);r("mori.gt.f1",Ad.b);r("mori.gt.f2",Ad.a);r("mori.gt.fn",Ad.K);r("mori.gte",Bd);r("mori.gte.f1",Bd.b);r("mori.gte.f2",Bd.a);r("mori.gte.fn",Bd.K);r("mori.lt",yd);r("mori.lt.f1",yd.b);r("mori.lt.f2",yd.a);r("mori.lt.fn",yd.K);r("mori.lte",zd);r("mori.lte.f1",zd.b);r("mori.lte.f2",zd.a); -r("mori.lte.fn",zd.K);r("mori.compare",od);r("mori.partial",Je);r("mori.partial.f1",Je.b);r("mori.partial.f2",Je.a);r("mori.partial.f3",Je.c);r("mori.partial.f4",Je.n);r("mori.partial.fn",Je.K);r("mori.comp",Ie);r("mori.comp.f0",Ie.l);r("mori.comp.f1",Ie.b);r("mori.comp.f2",Ie.a);r("mori.comp.f3",Ie.c);r("mori.comp.fn",Ie.K); -r("mori.pipeline",function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){function b(a,c){return c.b?c.b(a):c.call(null,a)}return A.a?A.a(b,a):A.call(null,b,a)}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}()); -r("mori.curry",function(){function a(a,d){var e=null;if(1<arguments.length){for(var e=0,f=Array(arguments.length-1);e<f.length;)f[e]=arguments[e+1],++e;e=new F(f,0)}return b.call(this,a,e)}function b(a,b){return function(e){return T.a(a,M.a?M.a(e,b):M.call(null,e,b))}}a.i=1;a.f=function(a){var d=G(a);a=H(a);return b(d,a)};a.d=b;return a}()); -r("mori.juxt",function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){return function(){function b(a){var c=null;if(0<arguments.length){for(var c=0,d=Array(arguments.length-0);c<d.length;)d[c]=arguments[c+0],++c;c=new F(d,0)}return e.call(this,c)}function e(b){var d=function(){function d(a){return T.a(a,b)}return Oe.a?Oe.a(d,a):Oe.call(null,d,a)}();return Ia.b?Ia.b(d):Ia.call(null, -d)}b.i=0;b.f=function(a){a=D(a);return e(a)};b.d=e;return b}()}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}()); -r("mori.knit",function(){function a(a){var d=null;if(0<arguments.length){for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;d=new F(e,0)}return b.call(this,d)}function b(a){return function(b){var e=function(){function e(a,b){return a.b?a.b(b):a.call(null,b)}return Oe.c?Oe.c(e,a,b):Oe.call(null,e,a,b)}();return Ia.b?Ia.b(e):Ia.call(null,e)}}a.i=0;a.f=function(a){a=D(a);return b(a)};a.d=b;return a}());r("mori.sum",xd);r("mori.sum.f0",xd.l);r("mori.sum.f1",xd.b); -r("mori.sum.f2",xd.a);r("mori.sum.fn",xd.K);r("mori.inc",function(a){return a+1});r("mori.dec",function(a){return a-1});r("mori.isEven",Ge);r("mori.isOdd",function(a){return!Ge(a)});r("mori.each",function(a,b){for(var c=D(a),d=null,e=0,f=0;;)if(f<e){var g=d.Q(null,f);b.b?b.b(g):b.call(null,g);f+=1}else if(c=D(c))fd(c)?(e=Yb(c),c=Zb(c),d=e,e=Q(e)):(d=g=G(c),b.b?b.b(d):b.call(null,d),c=K(c),d=null,e=0),f=0;else return null});r("mori.identity",ud); -r("mori.constantly",function(a){return function(){function b(b){if(0<arguments.length)for(var d=0,e=Array(arguments.length-0);d<e.length;)e[d]=arguments[d+0],++d;return a}b.i=0;b.f=function(b){D(b);return a};b.d=function(){return a};return b}()});r("mori.toJs",Kh); -r("mori.toClj",function(){function a(a,b){return Ph.d(a,Kc([Oh,b],0))}function b(a){return Ph.b(a)}var c=null,c=function(c,e){switch(arguments.length){case 1:return b.call(this,c);case 2:return a.call(this,c,e)}throw Error("Invalid arity: "+arguments.length);};c.b=b;c.a=a;return c}());r("mori.configure",function(a,b){switch(a){case "print-length":return la=b;case "print-level":return ma=b;default:throw Error([z("No matching clause: "),z(a)].join(""));}});r("mori.meta",Vc);r("mori.withMeta",O); -r("mori.varyMeta",ie);r("mori.varyMeta.f2",ie.a);r("mori.varyMeta.f3",ie.c);r("mori.varyMeta.f4",ie.n);r("mori.varyMeta.f5",ie.r);r("mori.varyMeta.f6",ie.P);r("mori.varyMeta.fn",ie.K);r("mori.alterMeta",Dh);r("mori.resetMeta",function(a,b){return a.k=b});V.prototype.inspect=function(){return this.toString()};F.prototype.inspect=function(){return this.toString()};Hc.prototype.inspect=function(){return this.toString()};wg.prototype.inspect=function(){return this.toString()};pg.prototype.inspect=function(){return this.toString()}; -qg.prototype.inspect=function(){return this.toString()};Fd.prototype.inspect=function(){return this.toString()};Ld.prototype.inspect=function(){return this.toString()};Hd.prototype.inspect=function(){return this.toString()};W.prototype.inspect=function(){return this.toString()};Vd.prototype.inspect=function(){return this.toString()};Bf.prototype.inspect=function(){return this.toString()};Df.prototype.inspect=function(){return this.toString()};Z.prototype.inspect=function(){return this.toString()}; -X.prototype.inspect=function(){return this.toString()};pa.prototype.inspect=function(){return this.toString()};rg.prototype.inspect=function(){return this.toString()};Lg.prototype.inspect=function(){return this.toString()};$g.prototype.inspect=function(){return this.toString()};ch.prototype.inspect=function(){return this.toString()};ph.prototype.inspect=function(){return this.toString()};U.prototype.inspect=function(){return this.toString()};qc.prototype.inspect=function(){return this.toString()}; -Lf.prototype.inspect=function(){return this.toString()};Kf.prototype.inspect=function(){return this.toString()};r("mori.mutable.thaw",function(a){return Ob(a)});r("mori.mutable.freeze",ce);r("mori.mutable.conj",de);r("mori.mutable.conj.f0",de.l);r("mori.mutable.conj.f1",de.b);r("mori.mutable.conj.f2",de.a);r("mori.mutable.conj.fn",de.K);r("mori.mutable.assoc",ee);r("mori.mutable.assoc.f3",ee.c);r("mori.mutable.assoc.fn",ee.K);r("mori.mutable.dissoc",fe);r("mori.mutable.dissoc.f2",fe.a);r("mori.mutable.dissoc.fn",fe.K);r("mori.mutable.pop",function(a){return Ub(a)});r("mori.mutable.disj",ge); -r("mori.mutable.disj.f2",ge.a);r("mori.mutable.disj.fn",ge.K);;return this.mori;}.call({});}); diff --git a/third_party/immer/extra/js/lib/platform.js b/third_party/immer/extra/js/lib/platform.js deleted file mode 100644 index a998e9953749..000000000000 --- a/third_party/immer/extra/js/lib/platform.js +++ /dev/null @@ -1,1135 +0,0 @@ -/*! - * Platform.js v1.3.1 <http://mths.be/platform> - * Copyright 2014-2016 Benjamin Tan <https://d10.github.io/> - * Copyright 2011-2013 John-David Dalton <http://allyoucanleet.com/> - * Available under MIT license <http://mths.be/mit> - */ -;(function() { - 'use strict'; - - /** Used to determine if values are of the language type `Object` */ - var objectTypes = { - 'function': true, - 'object': true - }; - - /** Used as a reference to the global object */ - var root = (objectTypes[typeof window] && window) || this; - - /** Backup possible global object */ - var oldRoot = root; - - /** Detect free variable `exports` */ - var freeExports = objectTypes[typeof exports] && exports; - - /** Detect free variable `module` */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; - - /** Detect free variable `global` from Node.js or Browserified code and use it as `root` */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global; - if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal || freeGlobal.self === freeGlobal)) { - root = freeGlobal; - } - - /** - * Used as the maximum length of an array-like object. - * See the [ES6 spec](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength) - * for more details. - */ - var maxSafeInteger = Math.pow(2, 53) - 1; - - /** Opera regexp */ - var reOpera = /\bOpera/; - - /** Possible global object */ - var thisBinding = this; - - /** Used for native method references */ - var objectProto = Object.prototype; - - /** Used to check for own properties of an object */ - var hasOwnProperty = objectProto.hasOwnProperty; - - /** Used to resolve the internal `[[Class]]` of values */ - var toString = objectProto.toString; - - /*--------------------------------------------------------------------------*/ - - /** - * Capitalizes a string value. - * - * @private - * @param {string} string The string to capitalize. - * @returns {string} The capitalized string. - */ - function capitalize(string) { - string = String(string); - return string.charAt(0).toUpperCase() + string.slice(1); - } - - /** - * A utility function to clean up the OS name. - * - * @private - * @param {string} os The OS name to clean up. - * @param {string} [pattern] A `RegExp` pattern matching the OS name. - * @param {string} [label] A label for the OS. - */ - function cleanupOS(os, pattern, label) { - // platform tokens defined at - // http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - // http://web.archive.org/web/20081122053950/http://msdn.microsoft.com/en-us/library/ms537503(VS.85).aspx - var data = { - '6.4': '10', - '6.3': '8.1', - '6.2': '8', - '6.1': 'Server 2008 R2 / 7', - '6.0': 'Server 2008 / Vista', - '5.2': 'Server 2003 / XP 64-bit', - '5.1': 'XP', - '5.01': '2000 SP1', - '5.0': '2000', - '4.0': 'NT', - '4.90': 'ME' - }; - // detect Windows version from platform tokens - if (pattern && label && /^Win/i.test(os) && - (data = data[0/*Opera 9.25 fix*/, /[\d.]+$/.exec(os)])) { - os = 'Windows ' + data; - } - // correct character case and cleanup - os = String(os); - - if (pattern && label) { - os = os.replace(RegExp(pattern, 'i'), label); - } - - os = format( - os.replace(/ ce$/i, ' CE') - .replace(/\bhpw/i, 'web') - .replace(/\bMacintosh\b/, 'Mac OS') - .replace(/_PowerPC\b/i, ' OS') - .replace(/\b(OS X) [^ \d]+/i, '$1') - .replace(/\bMac (OS X)\b/, '$1') - .replace(/\/(\d)/, ' $1') - .replace(/_/g, '.') - .replace(/(?: BePC|[ .]*fc[ \d.]+)$/i, '') - .replace(/\bx86\.64\b/gi, 'x86_64') - .replace(/\b(Windows Phone) OS\b/, '$1') - .split(' on ')[0] - ); - - return os; - } - - /** - * An iteration utility for arrays and objects. - * - * @private - * @param {Array|Object} object The object to iterate over. - * @param {Function} callback The function called per iteration. - */ - function each(object, callback) { - var index = -1, - length = object ? object.length : 0; - - if (typeof length == 'number' && length > -1 && length <= maxSafeInteger) { - while (++index < length) { - callback(object[index], index, object); - } - } else { - forOwn(object, callback); - } - } - - /** - * Trim and conditionally capitalize string values. - * - * @private - * @param {string} string The string to format. - * @returns {string} The formatted string. - */ - function format(string) { - string = trim(string); - return /^(?:webOS|i(?:OS|P))/.test(string) - ? string - : capitalize(string); - } - - /** - * Iterates over an object's own properties, executing the `callback` for each. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} callback The function executed per own property. - */ - function forOwn(object, callback) { - for (var key in object) { - if (hasOwnProperty.call(object, key)) { - callback(object[key], key, object); - } - } - } - - /** - * Gets the internal `[[Class]]` of a value. - * - * @private - * @param {*} value The value. - * @returns {string} The `[[Class]]`. - */ - function getClassOf(value) { - return value == null - ? capitalize(value) - : toString.call(value).slice(8, -1); - } - - /** - * Host objects can return type values that are different from their actual - * data type. The objects we are concerned with usually return non-primitive - * types of "object", "function", or "unknown". - * - * @private - * @param {*} object The owner of the property. - * @param {string} property The property to check. - * @returns {boolean} Returns `true` if the property value is a non-primitive, else `false`. - */ - function isHostType(object, property) { - var type = object != null ? typeof object[property] : 'number'; - return !/^(?:boolean|number|string|undefined)$/.test(type) && - (type == 'object' ? !!object[property] : true); - } - - /** - * Prepares a string for use in a `RegExp` by making hyphens and spaces optional. - * - * @private - * @param {string} string The string to qualify. - * @returns {string} The qualified string. - */ - function qualify(string) { - return String(string).replace(/([ -])(?!$)/g, '$1?'); - } - - /** - * A bare-bones `Array#reduce` like utility function. - * - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function called per iteration. - * @returns {*} The accumulated result. - */ - function reduce(array, callback) { - var accumulator = null; - each(array, function(value, index) { - accumulator = callback(accumulator, value, index, array); - }); - return accumulator; - } - - /** - * Removes leading and trailing whitespace from a string. - * - * @private - * @param {string} string The string to trim. - * @returns {string} The trimmed string. - */ - function trim(string) { - return String(string).replace(/^ +| +$/g, ''); - } - - /*--------------------------------------------------------------------------*/ - - /** - * Creates a new platform object. - * - * @memberOf platform - * @param {Object|string} [ua=navigator.userAgent] The user agent string or - * context object. - * @returns {Object} A platform object. - */ - function parse(ua) { - - /** The environment context object */ - var context = root; - - /** Used to flag when a custom context is provided */ - var isCustomContext = ua && typeof ua == 'object' && getClassOf(ua) != 'String'; - - // juggle arguments - if (isCustomContext) { - context = ua; - ua = null; - } - - /** Browser navigator object */ - var nav = context.navigator || {}; - - /** Browser user agent string */ - var userAgent = nav.userAgent || ''; - - ua || (ua = userAgent); - - /** Used to flag when `thisBinding` is the [ModuleScope] */ - var isModuleScope = isCustomContext || thisBinding == oldRoot; - - /** Used to detect if browser is like Chrome */ - var likeChrome = isCustomContext - ? !!nav.likeChrome - : /\bChrome\b/.test(ua) && !/internal|\n/i.test(toString.toString()); - - /** Internal `[[Class]]` value shortcuts */ - var objectClass = 'Object', - airRuntimeClass = isCustomContext ? objectClass : 'ScriptBridgingProxyObject', - enviroClass = isCustomContext ? objectClass : 'Environment', - javaClass = (isCustomContext && context.java) ? 'JavaPackage' : getClassOf(context.java), - phantomClass = isCustomContext ? objectClass : 'RuntimeObject'; - - /** Detect Java environment */ - var java = /\bJava/.test(javaClass) && context.java; - - /** Detect Rhino */ - var rhino = java && getClassOf(context.environment) == enviroClass; - - /** A character to represent alpha */ - var alpha = java ? 'a' : '\u03b1'; - - /** A character to represent beta */ - var beta = java ? 'b' : '\u03b2'; - - /** Browser document object */ - var doc = context.document || {}; - - /** - * Detect Opera browser (Presto-based) - * http://www.howtocreate.co.uk/operaStuff/operaObject.html - * http://dev.opera.com/articles/view/opera-mini-web-content-authoring-guidelines/#operamini - */ - var opera = context.operamini || context.opera; - - /** Opera `[[Class]]` */ - var operaClass = reOpera.test(operaClass = (isCustomContext && opera) ? opera['[[Class]]'] : getClassOf(opera)) - ? operaClass - : (opera = null); - - /*------------------------------------------------------------------------*/ - - /** Temporary variable used over the script's lifetime */ - var data; - - /** The CPU architecture */ - var arch = ua; - - /** Platform description array */ - var description = []; - - /** Platform alpha/beta indicator */ - var prerelease = null; - - /** A flag to indicate that environment features should be used to resolve the platform */ - var useFeatures = ua == userAgent; - - /** The browser/environment version */ - var version = useFeatures && opera && typeof opera.version == 'function' && opera.version(); - - /** A flag to indicate if the OS ends with "/ Version" */ - var isSpecialCasedOS; - - /* Detectable layout engines (order is important) */ - var layout = getLayout([ - 'Trident', - { 'label': 'WebKit', 'pattern': 'AppleWebKit' }, - 'iCab', - 'Presto', - 'NetFront', - 'Tasman', - 'KHTML', - 'Gecko' - ]); - - /* Detectable browser names (order is important) */ - var name = getName([ - 'Adobe AIR', - 'Arora', - 'Avant Browser', - 'Breach', - 'Camino', - 'Epiphany', - 'Fennec', - 'Flock', - 'Galeon', - 'GreenBrowser', - 'iCab', - 'Iceweasel', - { 'label': 'SRWare Iron', 'pattern': 'Iron' }, - 'K-Meleon', - 'Konqueror', - 'Lunascape', - 'Maxthon', - 'Midori', - 'Nook Browser', - 'PhantomJS', - 'Raven', - 'Rekonq', - 'RockMelt', - 'SeaMonkey', - { 'label': 'Silk', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Sleipnir', - 'SlimBrowser', - 'Sunrise', - 'Swiftfox', - 'WebPositive', - 'Opera Mini', - { 'label': 'Opera Mini', 'pattern': 'OPiOS' }, - 'Opera', - { 'label': 'Opera', 'pattern': 'OPR' }, - 'Chrome', - { 'label': 'Chrome Mobile', 'pattern': '(?:CriOS|CrMo)' }, - { 'label': 'Firefox', 'pattern': '(?:Firefox|Minefield)' }, - { 'label': 'IE', 'pattern': 'IEMobile' }, - { 'label': 'IE', 'pattern': 'MSIE' }, - 'Safari' - ]); - - /* Detectable products (order is important) */ - var product = getProduct([ - { 'label': 'BlackBerry', 'pattern': 'BB10' }, - 'BlackBerry', - { 'label': 'Galaxy S', 'pattern': 'GT-I9000' }, - { 'label': 'Galaxy S2', 'pattern': 'GT-I9100' }, - { 'label': 'Galaxy S3', 'pattern': 'GT-I9300' }, - { 'label': 'Galaxy S4', 'pattern': 'GT-I9500' }, - 'Google TV', - 'Lumia', - 'iPad', - 'iPod', - 'iPhone', - 'Kindle', - { 'label': 'Kindle Fire', 'pattern': '(?:Cloud9|Silk-Accelerated)' }, - 'Nook', - 'PlayBook', - 'PlayStation 4', - 'PlayStation 3', - 'PlayStation Vita', - 'TouchPad', - 'Transformer', - { 'label': 'Wii U', 'pattern': 'WiiU' }, - 'Wii', - 'Xbox One', - { 'label': 'Xbox 360', 'pattern': 'Xbox' }, - 'Xoom' - ]); - - /* Detectable manufacturers */ - var manufacturer = getManufacturer({ - 'Apple': { 'iPad': 1, 'iPhone': 1, 'iPod': 1 }, - 'Amazon': { 'Kindle': 1, 'Kindle Fire': 1 }, - 'Asus': { 'Transformer': 1 }, - 'Barnes & Noble': { 'Nook': 1 }, - 'BlackBerry': { 'PlayBook': 1 }, - 'Google': { 'Google TV': 1 }, - 'HP': { 'TouchPad': 1 }, - 'HTC': {}, - 'LG': {}, - 'Microsoft': { 'Xbox': 1, 'Xbox One': 1 }, - 'Motorola': { 'Xoom': 1 }, - 'Nintendo': { 'Wii U': 1, 'Wii': 1 }, - 'Nokia': { 'Lumia': 1 }, - 'Samsung': { 'Galaxy S': 1, 'Galaxy S2': 1, 'Galaxy S3': 1, 'Galaxy S4': 1 }, - 'Sony': { 'PlayStation 4': 1, 'PlayStation 3': 1, 'PlayStation Vita': 1 } - }); - - /* Detectable OSes (order is important) */ - var os = getOS([ - 'Windows Phone ', - 'Android', - 'CentOS', - 'Debian', - 'Fedora', - 'FreeBSD', - 'Gentoo', - 'Haiku', - 'Kubuntu', - 'Linux Mint', - 'Red Hat', - 'SuSE', - 'Ubuntu', - 'Xubuntu', - 'Cygwin', - 'Symbian OS', - 'hpwOS', - 'webOS ', - 'webOS', - 'Tablet OS', - 'Linux', - 'Mac OS X', - 'Macintosh', - 'Mac', - 'Windows 98;', - 'Windows ' - ]); - - /*------------------------------------------------------------------------*/ - - /** - * Picks the layout engine from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected layout engine. - */ - function getLayout(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the manufacturer from an array of guesses. - * - * @private - * @param {Array} guesses An object of guesses. - * @returns {null|string} The detected manufacturer. - */ - function getManufacturer(guesses) { - return reduce(guesses, function(result, value, key) { - // lookup the manufacturer by product or scan the UA for the manufacturer - return result || ( - value[product] || - value[0/*Opera 9.25 fix*/, /^[a-z]+(?: +[a-z]+\b)*/i.exec(product)] || - RegExp('\\b' + qualify(key) + '(?:\\b|\\w*\\d)', 'i').exec(ua) - ) && key; - }); - } - - /** - * Picks the browser name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected browser name. - */ - function getName(guesses) { - return reduce(guesses, function(result, guess) { - return result || RegExp('\\b' + ( - guess.pattern || qualify(guess) - ) + '\\b', 'i').exec(ua) && (guess.label || guess); - }); - } - - /** - * Picks the OS name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected OS name. - */ - function getOS(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + '(?:/[\\d.]+|[ \\w.]*)', 'i').exec(ua) - )) { - result = cleanupOS(result, pattern, guess.label || guess); - } - return result; - }); - } - - /** - * Picks the product name from an array of guesses. - * - * @private - * @param {Array} guesses An array of guesses. - * @returns {null|string} The detected product name. - */ - function getProduct(guesses) { - return reduce(guesses, function(result, guess) { - var pattern = guess.pattern || qualify(guess); - if (!result && (result = - RegExp('\\b' + pattern + ' *\\d+[.\\w_]*', 'i').exec(ua) || - RegExp('\\b' + pattern + '(?:; *(?:[a-z]+[_-])?[a-z]+\\d+|[^ ();-]*)', 'i').exec(ua) - )) { - // split by forward slash and append product version if needed - if ((result = String((guess.label && !RegExp(pattern, 'i').test(guess.label)) ? guess.label : result).split('/'))[1] && !/[\d.]+/.test(result[0])) { - result[0] += ' ' + result[1]; - } - // correct character case and cleanup - guess = guess.label || guess; - result = format(result[0] - .replace(RegExp(pattern, 'i'), guess) - .replace(RegExp('; *(?:' + guess + '[_-])?', 'i'), ' ') - .replace(RegExp('(' + guess + ')[-_.]?(\\w)', 'i'), '$1 $2')); - } - return result; - }); - } - - /** - * Resolves the version using an array of UA patterns. - * - * @private - * @param {Array} patterns An array of UA patterns. - * @returns {null|string} The detected version. - */ - function getVersion(patterns) { - return reduce(patterns, function(result, pattern) { - return result || (RegExp(pattern + - '(?:-[\\d.]+/|(?: for [\\w-]+)?[ /-])([\\d.]+[^ ();/_-]*)', 'i').exec(ua) || 0)[1] || null; - }); - } - - /** - * Returns `platform.description` when the platform object is coerced to a string. - * - * @name toString - * @memberOf platform - * @returns {string} Returns `platform.description` if available, else an empty string. - */ - function toStringPlatform() { - return this.description || ''; - } - - /*------------------------------------------------------------------------*/ - - // convert layout to an array so we can add extra details - layout && (layout = [layout]); - - // detect product names that contain their manufacturer's name - if (manufacturer && !product) { - product = getProduct([manufacturer]); - } - // clean up Google TV - if ((data = /\bGoogle TV\b/.exec(product))) { - product = data[0]; - } - // detect simulators - if (/\bSimulator\b/i.test(ua)) { - product = (product ? product + ' ' : '') + 'Simulator'; - } - // detect Opera Mini 8+ running in Turbo/Uncompressed mode on iOS - if (name == 'Opera Mini' && /\bOPiOS\b/.test(ua)) { - description.push('running in Turbo/Uncompressed mode'); - } - // detect iOS - if (/^iP/.test(product)) { - name || (name = 'Safari'); - os = 'iOS' + ((data = / OS ([\d_]+)/i.exec(ua)) - ? ' ' + data[1].replace(/_/g, '.') - : ''); - } - // detect Kubuntu - else if (name == 'Konqueror' && !/buntu/i.test(os)) { - os = 'Kubuntu'; - } - // detect Android browsers - else if (manufacturer && manufacturer != 'Google' && - ((/Chrome/.test(name) && !/\bMobile Safari\b/i.test(ua)) || /\bVita\b/.test(product))) { - name = 'Android Browser'; - os = /\bAndroid\b/.test(os) ? os : 'Android'; - } - // detect false positives for Firefox/Safari - else if (!name || (data = !/\bMinefield\b|\(Android;/i.test(ua) && /\b(?:Firefox|Safari)\b/.exec(name))) { - // escape the `/` for Firefox 1 - if (name && !product && /[\/,]|^[^(]+?\)/.test(ua.slice(ua.indexOf(data + '/') + 8))) { - // clear name of false positives - name = null; - } - // reassign a generic name - if ((data = product || manufacturer || os) && - (product || manufacturer || /\b(?:Android|Symbian OS|Tablet OS|webOS)\b/.test(os))) { - name = /[a-z]+(?: Hat)?/i.exec(/\bAndroid\b/.test(os) ? os : data) + ' Browser'; - } - } - // detect Firefox OS - if ((data = /\((Mobile|Tablet).*?Firefox\b/i.exec(ua)) && data[1]) { - os = 'Firefox OS'; - if (!product) { - product = data[1]; - } - } - // detect non-Opera versions (order is important) - if (!version) { - version = getVersion([ - '(?:Cloud9|CriOS|CrMo|IEMobile|Iron|Opera ?Mini|OPiOS|OPR|Raven|Silk(?!/[\\d.]+$))', - 'Version', - qualify(name), - '(?:Firefox|Minefield|NetFront)' - ]); - } - // detect stubborn layout engines - if (layout == 'iCab' && parseFloat(version) > 3) { - layout = ['WebKit']; - } else if ( - layout != 'Trident' && - (data = - /\bOpera\b/.test(name) && (/\bOPR\b/.test(ua) ? 'Blink' : 'Presto') || - /\b(?:Midori|Nook|Safari)\b/i.test(ua) && 'WebKit' || - !layout && /\bMSIE\b/i.test(ua) && (os == 'Mac OS' ? 'Tasman' : 'Trident') - ) - ) { - layout = [data]; - } - // detect NetFront on PlayStation - else if (/\bPlayStation\b(?! Vita\b)/i.test(name) && layout == 'WebKit') { - layout = ['NetFront']; - } - // detect Windows Phone 7 desktop mode - if (name == 'IE' && (data = (/; *(?:XBLWP|ZuneWP)(\d+)/i.exec(ua) || 0)[1])) { - name += ' Mobile'; - os = 'Windows Phone ' + (/\+$/.test(data) ? data : data + '.x'); - description.unshift('desktop mode'); - } - // detect Windows Phone 8+ desktop mode - else if (/\bWPDesktop\b/i.test(ua)) { - name = 'IE Mobile'; - os = 'Windows Phone 8+'; - description.unshift('desktop mode'); - version || (version = (/\brv:([\d.]+)/.exec(ua) || 0)[1]); - } - // detect IE 11 and above - else if (name != 'IE' && layout == 'Trident' && (data = /\brv:([\d.]+)/.exec(ua))) { - if (!/\bWPDesktop\b/i.test(ua)) { - if (name) { - description.push('identifying as ' + name + (version ? ' ' + version : '')); - } - name = 'IE'; - } - version = data[1]; - } - // detect Microsoft Edge - else if ((name == 'Chrome' || name != 'IE') && (data = /\bEdge\/([\d.]+)/.exec(ua))) { - name = 'Microsoft Edge'; - version = data[1]; - layout = ['Trident']; - } - // leverage environment features - if (useFeatures) { - // detect server-side environments - // Rhino has a global function while others have a global object - if (isHostType(context, 'global')) { - if (java) { - data = java.lang.System; - arch = data.getProperty('os.arch'); - os = os || data.getProperty('os.name') + ' ' + data.getProperty('os.version'); - } - if (isModuleScope && isHostType(context, 'system') && (data = [context.system])[0]) { - os || (os = data[0].os || null); - try { - data[1] = context.require('ringo/engine').version; - version = data[1].join('.'); - name = 'RingoJS'; - } catch(e) { - if (data[0].global.system == context.system) { - name = 'Narwhal'; - } - } - } - else if (typeof context.process == 'object' && (data = context.process)) { - name = 'Node.js'; - arch = data.arch; - os = data.platform; - version = /[\d.]+/.exec(data.version)[0]; - } - else if (rhino) { - name = 'Rhino'; - } - } - // detect Adobe AIR - else if (getClassOf((data = context.runtime)) == airRuntimeClass) { - name = 'Adobe AIR'; - os = data.flash.system.Capabilities.os; - } - // detect PhantomJS - else if (getClassOf((data = context.phantom)) == phantomClass) { - name = 'PhantomJS'; - version = (data = data.version || null) && (data.major + '.' + data.minor + '.' + data.patch); - } - // detect IE compatibility modes - else if (typeof doc.documentMode == 'number' && (data = /\bTrident\/(\d+)/i.exec(ua))) { - // we're in compatibility mode when the Trident version + 4 doesn't - // equal the document mode - version = [version, doc.documentMode]; - if ((data = +data[1] + 4) != version[1]) { - description.push('IE ' + version[1] + ' mode'); - layout && (layout[1] = ''); - version[1] = data; - } - version = name == 'IE' ? String(version[1].toFixed(1)) : version[0]; - } - os = os && format(os); - } - // detect prerelease phases - if (version && (data = - /(?:[ab]|dp|pre|[ab]\d+pre)(?:\d+\+?)?$/i.exec(version) || - /(?:alpha|beta)(?: ?\d)?/i.exec(ua + ';' + (useFeatures && nav.appMinorVersion)) || - /\bMinefield\b/i.test(ua) && 'a' - )) { - prerelease = /b/i.test(data) ? 'beta' : 'alpha'; - version = version.replace(RegExp(data + '\\+?$'), '') + - (prerelease == 'beta' ? beta : alpha) + (/\d+\+?/.exec(data) || ''); - } - // detect Firefox Mobile - if (name == 'Fennec' || name == 'Firefox' && /\b(?:Android|Firefox OS)\b/.test(os)) { - name = 'Firefox Mobile'; - } - // obscure Maxthon's unreliable version - else if (name == 'Maxthon' && version) { - version = version.replace(/\.[\d.]+/, '.x'); - } - // detect Silk desktop/accelerated modes - else if (name == 'Silk') { - if (!/\bMobi/i.test(ua)) { - os = 'Android'; - description.unshift('desktop mode'); - } - if (/Accelerated *= *true/i.test(ua)) { - description.unshift('accelerated'); - } - } - // detect Xbox 360 and Xbox One - else if (/\bXbox\b/i.test(product)) { - os = null; - if (product == 'Xbox 360' && /\bIEMobile\b/.test(ua)) { - description.unshift('mobile mode'); - } - } - // add mobile postfix - else if ((/^(?:Chrome|IE|Opera)$/.test(name) || name && !product && !/Browser|Mobi/.test(name)) && - (os == 'Windows CE' || /Mobi/i.test(ua))) { - name += ' Mobile'; - } - // detect IE platform preview - else if (name == 'IE' && useFeatures && context.external === null) { - description.unshift('platform preview'); - } - // detect BlackBerry OS version - // http://docs.blackberry.com/en/developers/deliverables/18169/HTTP_headers_sent_by_BB_Browser_1234911_11.jsp - else if ((/\bBlackBerry\b/.test(product) || /\bBB10\b/.test(ua)) && (data = - (RegExp(product.replace(/ +/g, ' *') + '/([.\\d]+)', 'i').exec(ua) || 0)[1] || - version - )) { - data = [data, /BB10/.test(ua)]; - os = (data[1] ? (product = null, manufacturer = 'BlackBerry') : 'Device Software') + ' ' + data[0]; - version = null; - } - // detect Opera identifying/masking itself as another browser - // http://www.opera.com/support/kb/view/843/ - else if (this != forOwn && ( - product != 'Wii' && ( - (useFeatures && opera) || - (/Opera/.test(name) && /\b(?:MSIE|Firefox)\b/i.test(ua)) || - (name == 'Firefox' && /\bOS X (?:\d+\.){2,}/.test(os)) || - (name == 'IE' && ( - (os && !/^Win/.test(os) && version > 5.5) || - /\bWindows XP\b/.test(os) && version > 8 || - version == 8 && !/\bTrident\b/.test(ua) - )) - ) - ) && !reOpera.test((data = parse.call(forOwn, ua.replace(reOpera, '') + ';'))) && data.name) { - - // when "indentifying", the UA contains both Opera and the other browser's name - data = 'ing as ' + data.name + ((data = data.version) ? ' ' + data : ''); - if (reOpera.test(name)) { - if (/\bIE\b/.test(data) && os == 'Mac OS') { - os = null; - } - data = 'identify' + data; - } - // when "masking", the UA contains only the other browser's name - else { - data = 'mask' + data; - if (operaClass) { - name = format(operaClass.replace(/([a-z])([A-Z])/g, '$1 $2')); - } else { - name = 'Opera'; - } - if (/\bIE\b/.test(data)) { - os = null; - } - if (!useFeatures) { - version = null; - } - } - layout = ['Presto']; - description.push(data); - } - // detect WebKit Nightly and approximate Chrome/Safari versions - if ((data = (/\bAppleWebKit\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - // correct build for numeric comparison - // (e.g. "532.5" becomes "532.05") - data = [parseFloat(data.replace(/\.(\d)$/, '.0$1')), data]; - // nightly builds are postfixed with a `+` - if (name == 'Safari' && data[1].slice(-1) == '+') { - name = 'WebKit Nightly'; - prerelease = 'alpha'; - version = data[1].slice(0, -1); - } - // clear incorrect browser versions - else if (version == data[1] || - version == (data[2] = (/\bSafari\/([\d.]+\+?)/i.exec(ua) || 0)[1])) { - version = null; - } - // use the full Chrome version when available - data[1] = (/\bChrome\/([\d.]+)/i.exec(ua) || 0)[1]; - // detect Blink layout engine - if (data[0] == 537.36 && data[2] == 537.36 && parseFloat(data[1]) >= 28 && name != 'IE' && name != 'Microsoft Edge') { - layout = ['Blink']; - } - // detect JavaScriptCore - // http://stackoverflow.com/questions/6768474/how-can-i-detect-which-javascript-engine-v8-or-jsc-is-used-at-runtime-in-androi - if (!useFeatures || (!likeChrome && !data[1])) { - layout && (layout[1] = 'like Safari'); - data = (data = data[0], data < 400 ? 1 : data < 500 ? 2 : data < 526 ? 3 : data < 533 ? 4 : data < 534 ? '4+' : data < 535 ? 5 : data < 537 ? 6 : data < 538 ? 7 : data < 601 ? 8 : '8'); - } else { - layout && (layout[1] = 'like Chrome'); - data = data[1] || (data = data[0], data < 530 ? 1 : data < 532 ? 2 : data < 532.05 ? 3 : data < 533 ? 4 : data < 534.03 ? 5 : data < 534.07 ? 6 : data < 534.10 ? 7 : data < 534.13 ? 8 : data < 534.16 ? 9 : data < 534.24 ? 10 : data < 534.30 ? 11 : data < 535.01 ? 12 : data < 535.02 ? '13+' : data < 535.07 ? 15 : data < 535.11 ? 16 : data < 535.19 ? 17 : data < 536.05 ? 18 : data < 536.10 ? 19 : data < 537.01 ? 20 : data < 537.11 ? '21+' : data < 537.13 ? 23 : data < 537.18 ? 24 : data < 537.24 ? 25 : data < 537.36 ? 26 : layout != 'Blink' ? '27' : '28'); - } - // add the postfix of ".x" or "+" for approximate versions - layout && (layout[1] += ' ' + (data += typeof data == 'number' ? '.x' : /[.+]/.test(data) ? '' : '+')); - // obscure version for some Safari 1-2 releases - if (name == 'Safari' && (!version || parseInt(version) > 45)) { - version = data; - } - } - // detect Opera desktop modes - if (name == 'Opera' && (data = /\bzbov|zvav$/.exec(os))) { - name += ' '; - description.unshift('desktop mode'); - if (data == 'zvav') { - name += 'Mini'; - version = null; - } else { - name += 'Mobile'; - } - os = os.replace(RegExp(' *' + data + '$'), ''); - } - // detect Chrome desktop mode - else if (name == 'Safari' && /\bChrome\b/.exec(layout && layout[1])) { - description.unshift('desktop mode'); - name = 'Chrome Mobile'; - version = null; - - if (/\bOS X\b/.test(os)) { - manufacturer = 'Apple'; - os = 'iOS 4.3+'; - } else { - os = null; - } - } - // strip incorrect OS versions - if (version && version.indexOf((data = /[\d.]+$/.exec(os))) == 0 && - ua.indexOf('/' + data + '-') > -1) { - os = trim(os.replace(data, '')); - } - // add layout engine - if (layout && !/\b(?:Avant|Nook)\b/.test(name) && ( - /Browser|Lunascape|Maxthon/.test(name) || - /^(?:Adobe|Arora|Breach|Midori|Opera|Phantom|Rekonq|Rock|Sleipnir|Web)/.test(name) && layout[1])) { - // don't add layout details to description if they are falsey - (data = layout[layout.length - 1]) && description.push(data); - } - // combine contextual information - if (description.length) { - description = ['(' + description.join('; ') + ')']; - } - // append manufacturer - if (manufacturer && product && product.indexOf(manufacturer) < 0) { - description.push('on ' + manufacturer); - } - // append product - if (product) { - description.push((/^on /.test(description[description.length -1]) ? '' : 'on ') + product); - } - // parse OS into an object - if (os) { - data = / ([\d.+]+)$/.exec(os); - isSpecialCasedOS = data && os.charAt(os.length - data[0].length - 1) == '/'; - os = { - 'architecture': 32, - 'family': (data && !isSpecialCasedOS) ? os.replace(data[0], '') : os, - 'version': data ? data[1] : null, - 'toString': function() { - var version = this.version; - return this.family + ((version && !isSpecialCasedOS) ? ' ' + version : '') + (this.architecture == 64 ? ' 64-bit' : ''); - } - }; - } - // add browser/OS architecture - if ((data = /\b(?:AMD|IA|Win|WOW|x86_|x)64\b/i.exec(arch)) && !/\bi686\b/i.test(arch)) { - if (os) { - os.architecture = 64; - os.family = os.family.replace(RegExp(' *' + data), ''); - } - if ( - name && (/\bWOW64\b/i.test(ua) || - (useFeatures && /\w(?:86|32)$/.test(nav.cpuClass || nav.platform) && !/\bWin64; x64\b/i.test(ua))) - ) { - description.unshift('32-bit'); - } - } - - ua || (ua = null); - - /*------------------------------------------------------------------------*/ - - /** - * The platform object. - * - * @name platform - * @type Object - */ - var platform = {}; - - /** - * The platform description. - * - * @memberOf platform - * @type string|null - */ - platform.description = ua; - - /** - * The name of the browser's layout engine. - * - * @memberOf platform - * @type string|null - */ - platform.layout = layout && layout[0]; - - /** - * The name of the product's manufacturer. - * - * @memberOf platform - * @type string|null - */ - platform.manufacturer = manufacturer; - - /** - * The name of the browser/environment. - * - * @memberOf platform - * @type string|null - */ - platform.name = name; - - /** - * The alpha/beta release indicator. - * - * @memberOf platform - * @type string|null - */ - platform.prerelease = prerelease; - - /** - * The name of the product hosting the browser. - * - * @memberOf platform - * @type string|null - */ - platform.product = product; - - /** - * The browser's user agent string. - * - * @memberOf platform - * @type string|null - */ - platform.ua = ua; - - /** - * The browser/environment version. - * - * @memberOf platform - * @type string|null - */ - platform.version = name && version; - - /** - * The name of the operating system. - * - * @memberOf platform - * @type Object - */ - platform.os = os || { - - /** - * The CPU architecture the OS is built for. - * - * @memberOf platform.os - * @type number|null - */ - 'architecture': null, - - /** - * The family of the OS. - * - * Common values include: - * "Windows", "Windows Server 2008 R2 / 7", "Windows Server 2008 / Vista", - * "Windows XP", "OS X", "Ubuntu", "Debian", "Fedora", "Red Hat", "SuSE", - * "Android", "iOS" and "Windows Phone" - * - * @memberOf platform.os - * @type string|null - */ - 'family': null, - - /** - * The version of the OS. - * - * @memberOf platform.os - * @type string|null - */ - 'version': null, - - /** - * Returns the OS string. - * - * @memberOf platform.os - * @returns {string} The OS string. - */ - 'toString': function() { return 'null'; } - }; - - platform.parse = parse; - platform.toString = toStringPlatform; - - if (platform.version) { - description.unshift(version); - } - if (platform.name) { - description.unshift(name); - } - if (os && name && !(os == String(os).split(' ')[0] && (os == name.split(' ')[0] || product))) { - description.push(product ? '(' + os + ')' : 'on ' + os); - } - if (description.length) { - platform.description = description.join(' '); - } - return platform; - } - - /*--------------------------------------------------------------------------*/ - - // export platform - // some AMD build optimizers, like r.js, check for condition patterns like the following: - if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { - // define as an anonymous module so, through path mapping, it can be aliased - define(function() { - return parse(); - }); - } - // check for `exports` after `define` in case a build optimizer adds an `exports` object - else if (freeExports && freeModule) { - // in Narwhal, Node.js, Rhino -require, or RingoJS - forOwn(parse(), function(value, key) { - freeExports[key] = value; - }); - } - // in a browser or Rhino - else { - root.platform = parse(); - } -}.call(this)); diff --git a/third_party/immer/extra/js/makefile b/third_party/immer/extra/js/makefile deleted file mode 100644 index fc6075bfe8fa..000000000000 --- a/third_party/immer/extra/js/makefile +++ /dev/null @@ -1,29 +0,0 @@ - -BOOST=. -EMCXX=em++ -EMCXXFLAGS=-O3 -std=c++14 --bind \ - -I ../.. \ - -I $(BOOST) -WASM_BACKEND=0 - -ALL= \ - out/immer.asmjs.js \ - out/immer.asmjs.html \ - out/immer.wasm.js \ - out/immer.wasm.html - -all: $(ALL) - -out/immer.asmjs.js: immer.cpp - @mkdir -p $(@D) - $(EMCXX) $(EMCXXFLAGS) $< -o $@ - -out/immer.wasm.js: immer.cpp - @mkdir -p $(@D) - EMCC_WASM_BACKEND=$(WASM_BACKEND) $(EMCXX) -s WASM=1 $(EMCXXFLAGS) $< -o $@ - -%.html: %.js index.tpl.html - sed s/%IMMER_JS%/`basename $<`/ < index.tpl.html > $@ - -clean: - rm -f $(ALL) diff --git a/third_party/immer/extra/python/CMakeLists.txt b/third_party/immer/extra/python/CMakeLists.txt deleted file mode 100644 index 11d5fff209ad..000000000000 --- a/third_party/immer/extra/python/CMakeLists.txt +++ /dev/null @@ -1,46 +0,0 @@ - -option(USE_PYBIND "bind with pybind1" off) -option(USE_BOOST_PYTHON "bind with boost::python" off) - -if (USE_PYBIND) - set(PYBIND11_CPP_STANDARD -std=c++14) - find_package(Boost 1.56 REQUIRED) - add_subdirectory(lib/pybind11) - pybind11_add_module(immer_python_module src/immer-pybind.cpp) - target_link_libraries(immer_python_module PUBLIC - immer) - -elseif(USE_BOOST_PYTHON) - find_package(PythonInterp) - find_package(PythonLibs) - find_package(Boost 1.56 COMPONENTS python) - python_add_module(immer_python_module src/immer-boost.cpp) - include_directories(immer_python_module PUBLIC - ${immer_include_dir} - ${Boost_INCLUDE_DIRS} - ${PYTHON_INCLUDE_DIRS}) - target_link_libraries(immer_python_module PUBLIC - immer - ${Boost_LIBRARIES} - ${PYTHON_LIBRARIES}) - -else() - find_package(PythonInterp) - find_package(PythonLibs) - - if (NOT PYTHONLIBS_FOUND) - message(STATUS "Disabling Python modules") - return() - endif() - - python_add_module(immer_python_module EXCLUDE_FROM_ALL - src/immer-raw.cpp) - target_include_directories(immer_python_module PUBLIC - ${PYTHON_INCLUDE_DIRS}) - target_link_libraries(immer_python_module PUBLIC - immer - ${PYTHON_LIBRARIES}) - -endif() - -add_custom_target(python DEPENDS immer_python_module) diff --git a/third_party/immer/extra/python/README.rst b/third_party/immer/extra/python/README.rst deleted file mode 100644 index 7447e99e6281..000000000000 --- a/third_party/immer/extra/python/README.rst +++ /dev/null @@ -1,42 +0,0 @@ - -Python bindings -=============== - -This library includes experimental bindings bring efficient immutable -vectors for the Python language. They were developed as part of the -research for the `ICFP'17 paper`_. The interface is quite -**incomplete**, yet you can already do some things like: - -.. literalinclude:: ../extra/python/example.py - :language: python - :start-after: intro/start - :end-before: intro/end -.. - - **Do you want to help** making these bindings complete and production - ready? Drop a line at `immer@sinusoid.al - <mailto:immer@sinusoid.al>`_ or `open an issue on Github - <https://github.com/arximboldi/immer>`_ - -Installation ------------- -:: - - pip install --user git+https://github.com/arximboldi/immer.git - -Benchmarks ----------- - -The library includes a set of benchmarks that compare it to -`pyrsistent <https://github.com/tobgu/pyrsistent>`_. You can see the -results in the `ICFP'17 paper`_. If you want to run them yourself, -you need to install some dependencies:: - - pip install --user pytest-benchmark pyrsistent - -Then you need to clone the `project repository -<https://github.com/arximboldi/immer>`_ and from its root, run:: - - pytest extra/python/benchmark - -.. _ICFP'17 paper: https://public.sinusoid.es/misc/immer/immer-icfp17.pdf diff --git a/third_party/immer/extra/python/benchmark/test_benchmarks.py b/third_party/immer/extra/python/benchmark/test_benchmarks.py deleted file mode 100644 index 11e4817c3256..000000000000 --- a/third_party/immer/extra/python/benchmark/test_benchmarks.py +++ /dev/null @@ -1,45 +0,0 @@ - -# immer: immutable data structures for C++ -# Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -# -# This software is distributed under the Boost Software License, Version 1.0. -# See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt - -## - -import immer -import pyrsistent - -BENCHMARK_SIZE = 1000 - -def push(v, n=BENCHMARK_SIZE): - for x in xrange(n): - v = v.append(x) - return v - -def assoc(v): - for i in xrange(len(v)): - v = v.set(i, i+1) - return v - -def index(v): - for i in xrange(len(v)): - v[i] - -def test_push_immer(benchmark): - benchmark(push, immer.Vector()) - -def test_push_pyrsistent(benchmark): - benchmark(push, pyrsistent.pvector()) - -def test_assoc_immer(benchmark): - benchmark(assoc, push(immer.Vector())) - -def test_assoc_pyrsistent(benchmark): - benchmark(assoc, push(pyrsistent.pvector())) - -def test_index_immer(benchmark): - benchmark(index, push(immer.Vector())) - -def test_index_pyrsistent(benchmark): - benchmark(index, push(pyrsistent.pvector())) diff --git a/third_party/immer/extra/python/example.py b/third_party/immer/extra/python/example.py deleted file mode 100755 index 36f7333c4f0f..000000000000 --- a/third_party/immer/extra/python/example.py +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env python## - -# immer: immutable data structures for C++ -# Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -# -# This software is distributed under the Boost Software License, Version 1.0. -# See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt - - -# include:intro/start -import immer - -v0 = immer.Vector().append(13).append(42) -assert v0[0] == 13 -assert v0[1] == 42 -assert len(v0) == 2 - -v1 = v0.set(0, 12) -assert v0.tolist() == [13, 42] -assert v1.tolist() == [12, 42] -# include:intro/end diff --git a/third_party/immer/extra/python/immer/__init__.py b/third_party/immer/extra/python/immer/__init__.py deleted file mode 100644 index e4702b40e4a1..000000000000 --- a/third_party/immer/extra/python/immer/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ - -from immer_python_module import * diff --git a/third_party/immer/extra/python/lib/pybind11 b/third_party/immer/extra/python/lib/pybind11 deleted file mode 160000 -Subproject 1eaacd19f6de9a053570c21de6d173efc2304bc diff --git a/third_party/immer/extra/python/src/immer-boost.cpp b/third_party/immer/extra/python/src/immer-boost.cpp deleted file mode 100644 index 0ea42354b6b1..000000000000 --- a/third_party/immer/extra/python/src/immer-boost.cpp +++ /dev/null @@ -1,80 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <boost/python.hpp> -#include <boost/python/suite/indexing/vector_indexing_suite.hpp> - -#include <immer/vector.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> - -namespace { - -struct heap_t -{ - template <typename ...Tags> - static void* allocate(std::size_t size, Tags...) - { - return PyMem_Malloc(size); - } - - template <typename ...Tags> - static void deallocate(std::size_t, void* obj, Tags...) - { - PyMem_Free(obj); - } -}; - -using memory_t = immer::memory_policy< - immer::unsafe_free_list_heap_policy<heap_t>, - immer::unsafe_refcount_policy>; - -template <typename Vector> -struct immer_vector_indexing_suite : boost::python::vector_indexing_suite< - Vector, true, immer_vector_indexing_suite<Vector>> -{ - using value_t = typename Vector::value_type; - using index_t = typename Vector::size_type; - using object_t = boost::python::object; - - static void forbidden() { throw std::runtime_error{"immutable!"}; } - static void todo() { throw std::runtime_error{"TODO!"}; } - - static const value_t& get_item(const Vector& v, index_t i) { return v[i]; } - static object_t get_slice(const Vector&, index_t, index_t) { todo(); } - - static void set_item(const Vector&, index_t, const value_t&) { forbidden(); } - static void delete_item(const Vector&, index_t) { forbidden(); } - static void set_slice(const Vector&, index_t, index_t, const value_t&) { forbidden(); } - static void delete_slice(const Vector&, index_t, index_t) { forbidden(); } - template <typename Iter> - static void set_slice(const Vector&, index_t, index_t, Iter, Iter) { forbidden(); } - template <class Iter> - static void extend(const Vector& container, Iter, Iter) { forbidden(); } -}; - -} // anonymous namespace - - -BOOST_PYTHON_MODULE(immer_python_module) -{ - using namespace boost::python; - - using vector_t = immer::vector<object, memory_t>; - - class_<vector_t>("Vector") - .def(immer_vector_indexing_suite<vector_t>()) - .def("append", - +[] (const vector_t& v, object x) { - return v.push_back(std::move(x)); - }) - .def("set", - +[] (const vector_t& v, std::size_t i, object x) { - return v.set(i, std::move(x)); - }) - ; -} diff --git a/third_party/immer/extra/python/src/immer-pybind.cpp b/third_party/immer/extra/python/src/immer-pybind.cpp deleted file mode 100644 index 8f8aab1231f8..000000000000 --- a/third_party/immer/extra/python/src/immer-pybind.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <pybind11/pybind11.h> - -#include <immer/vector.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> - -namespace { - -struct heap_t -{ - template <typename ...Tags> - static void* allocate(std::size_t size, Tags...) - { - return PyMem_Malloc(size); - } - - template <typename ...Tags> - static void deallocate(std::size_t, void* obj, Tags...) - { - PyMem_Free(obj); - } -}; - -using memory_t = immer::memory_policy< - immer::unsafe_free_list_heap_policy<heap_t>, - immer::unsafe_refcount_policy>; - -} // anonymous namespace - -namespace py = pybind11; - -PYBIND11_PLUGIN(immer_python_module) -{ - py::module m("immer", R"pbdoc( - Immer - ----- - .. currentmodule:: immer - .. autosummary:: - :toctree: _generate - Vector - )pbdoc"); - - using vector_t = immer::vector<py::object, memory_t>; - - py::class_<vector_t>(m, "Vector") - .def(py::init<>()) - .def("__len__", &vector_t::size) - .def("__getitem__", - [] (const vector_t& v, std::size_t i) { - if (i > v.size()) - throw py::index_error{"Index out of range"}; - return v[i]; - }) - .def("append", - [] (const vector_t& v, py::object x) { - return v.push_back(std::move(x)); - }) - .def("set", - [] (const vector_t& v, std::size_t i, py::object x) { - return v.set(i, std::move(x)); - }); - -#ifdef VERSION_INFO - m.attr("__version__") = py::str(VERSION_INFO); -#else - m.attr("__version__") = py::str("dev"); -#endif - - return m.ptr(); -} diff --git a/third_party/immer/extra/python/src/immer-raw.cpp b/third_party/immer/extra/python/src/immer-raw.cpp deleted file mode 100644 index 283f973c8d0f..000000000000 --- a/third_party/immer/extra/python/src/immer-raw.cpp +++ /dev/null @@ -1,402 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -extern "C" { -#include <Python.h> -#include <structmember.h> -} - -#include <immer/vector.hpp> -#include <immer/algorithm.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> - -#include <iostream> - -namespace { - -struct heap_t -{ - template <typename ...Tags> - static void* allocate(std::size_t size, Tags...) - { - return PyMem_Malloc(size); - } - - template <typename ...Tags> - static void deallocate(std::size_t, void* obj, Tags...) - { - PyMem_Free(obj); - } -}; - -struct object_t -{ - struct wrap_t {}; - struct adopt_t {}; - - PyObject* ptr_ = nullptr; - - object_t() = delete; - ~object_t() { Py_XDECREF(ptr_); } - - explicit object_t(PyObject* p, wrap_t) : ptr_{p} {} - explicit object_t(PyObject* p, adopt_t) : ptr_{p} - { - assert(p); - Py_INCREF(p); - } - - static object_t wrap(PyObject* p) { return object_t{p, wrap_t{}}; } - static object_t adopt(PyObject* p) { return object_t{p, adopt_t{}}; } - - object_t(const object_t& o) : ptr_(o.ptr_) { Py_INCREF(ptr_); } - object_t(object_t&& o) { std::swap(ptr_, o.ptr_); } - - object_t& operator=(const object_t& o) - { - Py_XINCREF(o.ptr_); - Py_XDECREF(ptr_); - ptr_ = o.ptr_; - return *this; - } - object_t& operator=(object_t&& o) - { - std::swap(ptr_, o.ptr_); - return *this; - } - - PyObject* release() - { - auto p = ptr_; - ptr_ = nullptr; - return p; - } - - PyObject* get() const { return ptr_; } -}; - -using memory_t = immer::memory_policy< - immer::unsafe_free_list_heap_policy<heap_t>, - immer::unsafe_refcount_policy>; - -using vector_impl_t = immer::vector<object_t, memory_t>; - -struct vector_t -{ - PyObject_HEAD - vector_impl_t impl; - PyObject* in_weakreflist; - - static PyTypeObject type; -}; - -vector_t* empty_vector = nullptr; - -vector_t* make_vector() -{ - auto* v = PyObject_GC_New(vector_t, &vector_t::type); - new (&v->impl) vector_impl_t{}; - v->in_weakreflist = nullptr; - PyObject_GC_Track((PyObject*)v); - return v; -} - -vector_t* make_vector(vector_impl_t&& impl) -{ - auto v = PyObject_GC_New(vector_t, &vector_t::type); - new (&v->impl) vector_impl_t{std::move(impl)}; - v->in_weakreflist = nullptr; - PyObject_GC_Track((PyObject*)v); - return v; -} - -auto todo() -{ - PyErr_SetString(PyExc_RuntimeError, "immer: todo!"); - return nullptr; -} - -void vector_dealloc(vector_t* self) -{ - if (self->in_weakreflist != nullptr) - PyObject_ClearWeakRefs((PyObject*)self); - - PyObject_GC_UnTrack((PyObject*)self); - Py_TRASHCAN_SAFE_BEGIN(self); - - self->impl.~vector_impl_t(); - - PyObject_GC_Del(self); - Py_TRASHCAN_SAFE_END(self); -} - -PyObject* vector_to_list(vector_t* self) -{ - auto list = PyList_New(self->impl.size()); - auto idx = 0; - immer::for_each(self->impl, [&] (auto&& obj) { - auto o = obj.get(); - Py_INCREF(o); - PyList_SET_ITEM(list, idx, o); - ++idx; - }); - return list; -} - -PyObject* vector_repr(vector_t *self) -{ - auto list = vector_to_list(self); - auto list_repr = PyObject_Repr(list); - Py_DECREF(list); - - if (!list_repr) return nullptr; - -#if PY_MAJOR_VERSION >= 3 - auto s = PyUnicode_FromFormat("%s%U%s", "immer.vector(", list_repr, ")"); - Py_DECREF(list_repr); -#else - auto s = PyString_FromString("immer.vector("); - PyString_ConcatAndDel(&s, list_repr); - PyString_ConcatAndDel(&s, PyString_FromString(")")); -#endif - return s; -} - -Py_ssize_t vector_len(vector_t* self) -{ - return self->impl.size(); -} - -PyObject* vector_extend(vector_t* self, PyObject* iterable) -{ - return todo(); -} - -vector_t* vector_append(vector_t* self, PyObject *obj) -{ - assert(obj != nullptr); - return make_vector(self->impl.push_back(object_t::adopt(obj))); -} - -vector_t* vector_set(vector_t* self, PyObject* args) -{ - PyObject* obj = nullptr; - Py_ssize_t pos; - // the n parses for size, the O parses for a Python object - if(!PyArg_ParseTuple(args, "nO", &pos, &obj)) { - return nullptr; - } - if (pos < 0) - pos += self->impl.size(); - if (pos < 0 || pos > (Py_ssize_t)self->impl.size()) { - PyErr_Format(PyExc_IndexError, "Index out of range: %zi", pos); - return nullptr; - } - return make_vector(self->impl.set(pos, object_t::adopt(obj))); -} - -PyObject* vector_new(PyTypeObject* subtype, PyObject *args, PyObject *kwds) -{ - Py_INCREF(empty_vector); - return (PyObject*)empty_vector; -} - -long vector_hash(vector_t* self) -{ - todo(); - return 0; -} - -PyObject* vector_get_item(vector_t* self, Py_ssize_t pos) -{ - if (pos < 0) - pos += self->impl.size(); - if (pos < 0 || pos >= (Py_ssize_t)self->impl.size()) { - PyErr_Format(PyExc_IndexError, "Index out of range: %zi", pos); - return nullptr; - } - auto r = self->impl[pos]; - return r.release(); -} - -PyObject* vector_subscript(vector_t* self, PyObject* item) -{ - if (PyIndex_Check(item)) { - auto i = PyNumber_AsSsize_t(item, PyExc_IndexError); - if (i == -1 && PyErr_Occurred()) - return nullptr; - return vector_get_item(self, i); - } else if (PySlice_Check(item)) { - return todo(); - } else { - PyErr_Format(PyExc_TypeError, - "vector indices must be integers, not %.200s", - Py_TYPE(item)->tp_name); - return nullptr; - } -} - -PyObject* vector_repeat(vector_t* self, Py_ssize_t n) -{ - return todo(); -} - -int vector_traverse(vector_t* self, visitproc visit, void* arg) -{ - auto result = 0; - immer::all_of(self->impl, [&] (auto&& o) { - return 0 == (result = [&] { - Py_VISIT(o.get()); - return 0; - }()); - }); - return result; -} - -PyObject* vector_richcompare(PyObject* v, PyObject* w, int op) -{ - return todo(); -} - -PyObject* vector_iter(PyObject* self) -{ - return todo(); -} - -PyMethodDef vector_methods[] = -{ - {"append", (PyCFunction)vector_append, METH_O, "Appends an element"}, - {"set", (PyCFunction)vector_set, METH_VARARGS, "Inserts an element at the specified position"}, - {"extend", (PyCFunction)vector_extend, METH_O|METH_COEXIST, "Extend"}, - {"tolist", (PyCFunction)vector_to_list, METH_NOARGS, "Convert to list"}, - {0} -}; - -PyMemberDef vector_members[] = -{ - {0} /* sentinel */ -}; - -PySequenceMethods vector_sequence_methods = -{ - (lenfunc)vector_len, /* sq_length */ - (binaryfunc)vector_extend, /* sq_concat */ - (ssizeargfunc)vector_repeat, /* sq_repeat */ - (ssizeargfunc)vector_get_item, /* sq_item */ - 0, /* sq_slice */ - 0, /* sq_ass_item */ - 0, /* sq_ass_slice */ - 0, /* sq_contains */ - 0, /* sq_inplace_concat */ - 0, /* sq_inplace_repeat */ -}; - -PyMappingMethods vector_mapping_methods = -{ - (lenfunc)vector_len, - (binaryfunc)vector_subscript, - 0 -}; - -PyTypeObject vector_t::type = -{ - PyVarObject_HEAD_INIT(NULL, 0) - "immer.Vector", /* tp_name */ - sizeof(vector_t), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)vector_dealloc, /* tp_dealloc */ - 0, /* tp_print */ - 0, /* tp_getattr */ - 0, /* tp_setattr */ - 0, /* tp_compare */ - (reprfunc)vector_repr, /* tp_repr */ - 0, /* tp_as_number */ - &vector_sequence_methods, /* tp_as_sequence */ - &vector_mapping_methods, /* tp_as_mapping */ - (hashfunc)vector_hash, /* tp_hash */ - 0, /* tp_call */ - 0, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* tp_flags */ - "", /* tp_doc */ - (traverseproc)vector_traverse, /* tp_traverse */ - 0, /* tp_clear */ - vector_richcompare, /* tp_richcompare */ - offsetof(vector_t, in_weakreflist), /* tp_weaklistoffset */ - vector_iter, /* tp_iter */ - 0, /* tp_iternext */ - vector_methods, /* tp_methods */ - vector_members, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - vector_new, /* tp_new */ -}; - -#if PY_MAJOR_VERSION >= 3 -struct PyModuleDef module_def = -{ - PyModuleDef_HEAD_INIT, - "immer_python_module", /* m_name */ - "", /* m_doc */ - -1, /* m_size */ - /module_methods, /* m_methods */ - 0, /* m_reload */ - 0, /* m_traverse */ - 0, /* m_clear */ - 0, /* m_free */ -}; -#endif - -PyMethodDef module_methods[] = { - {0, 0, 0, 0} -}; - -PyObject* module_init() -{ - if (PyType_Ready(&vector_t::type) < 0) - return nullptr; - -#if PY_MAJOR_VERSION >= 3 - auto m = PyModule_Create(&module_def); -#else - auto m = Py_InitModule3("immer_python_module", module_methods, ""); -#endif - if (!m) - return nullptr; - - if (!empty_vector) - empty_vector = make_vector(); - - Py_INCREF(&vector_t::type); - PyModule_AddObject(m, "Vector", (PyObject*) &vector_t::type); - return m; -} - -} // anonymous namespace - -extern "C" { -#if PY_MAJOR_VERSION >= 3 -PyMODINIT_FUNC PyInit_immer_python_module() -{ - return module_init(); -} -#else -PyMODINIT_FUNC initimmer_python_module() -{ - module_init(); -} -#endif -} diff --git a/third_party/immer/immer/algorithm.hpp b/third_party/immer/immer/algorithm.hpp deleted file mode 100644 index ecdc417e2b07..000000000000 --- a/third_party/immer/immer/algorithm.hpp +++ /dev/null @@ -1,212 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <algorithm> -#include <numeric> -#include <type_traits> - -namespace immer { - -/** - * @defgroup algorithm - * @{ - */ - -/*@{*/ -// Right now these algorithms dispatch directly to the vector -// implementations unconditionally. This will be changed in the -// future to support other kinds of containers. - -/*! - * Apply operation `fn` for every contiguous *chunk* of data in the - * range sequentially. Each time, `Fn` is passed two `value_type` - * pointers describing a range over a part of the vector. This allows - * iterating over the elements in the most efficient way. - * - * @rst - * - * .. tip:: This is a low level method. Most of the time, :doc:`other - * wrapper algorithms <algorithms>` should be used instead. - * - * @endrst - */ -template <typename Range, typename Fn> -void for_each_chunk(const Range& r, Fn&& fn) -{ - r.impl().for_each_chunk(std::forward<Fn>(fn)); -} - -template <typename Iterator, typename Fn> -void for_each_chunk(const Iterator& first, const Iterator& last, Fn&& fn) -{ - assert(&first.impl() == &last.impl()); - first.impl().for_each_chunk( - first.index(), last.index(), std::forward<Fn>(fn)); -} - -template <typename T, typename Fn> -void for_each_chunk(const T* first, const T* last, Fn&& fn) -{ - std::forward<Fn>(fn)(first, last); -} - -/*! - * Apply operation `fn` for every contiguous *chunk* of data in the - * range sequentially, until `fn` returns `false`. Each time, `Fn` is - * passed two `value_type` pointers describing a range over a part of - * the vector. This allows iterating over the elements in the most - * efficient way. - * - * @rst - * - * .. tip:: This is a low level method. Most of the time, :doc:`other - * wrapper algorithms <algorithms>` should be used instead. - * - * @endrst - */ -template <typename Range, typename Fn> -bool for_each_chunk_p(const Range& r, Fn&& fn) -{ - return r.impl().for_each_chunk_p(std::forward<Fn>(fn)); -} - -template <typename Iterator, typename Fn> -bool for_each_chunk_p(const Iterator& first, const Iterator& last, Fn&& fn) -{ - assert(&first.impl() == &last.impl()); - return first.impl().for_each_chunk_p( - first.index(), last.index(), std::forward<Fn>(fn)); -} - -template <typename T, typename Fn> -bool for_each_chunk_p(const T* first, const T* last, Fn&& fn) -{ - return std::forward<Fn>(fn)(first, last); -} - -/*! - * Equivalent of `std::accumulate` applied to the range `r`. - */ -template <typename Range, typename T> -T accumulate(Range&& r, T init) -{ - for_each_chunk(r, [&](auto first, auto last) { - init = std::accumulate(first, last, init); - }); - return init; -} - -template <typename Range, typename T, typename Fn> -T accumulate(Range&& r, T init, Fn fn) -{ - for_each_chunk(r, [&](auto first, auto last) { - init = std::accumulate(first, last, init, fn); - }); - return init; -} - -/*! - * Equivalent of `std::accumulate` applied to the range @f$ [first, - * last) @f$. - */ -template <typename Iterator, typename T> -T accumulate(Iterator first, Iterator last, T init) -{ - for_each_chunk(first, last, [&](auto first, auto last) { - init = std::accumulate(first, last, init); - }); - return init; -} - -template <typename Iterator, typename T, typename Fn> -T accumulate(Iterator first, Iterator last, T init, Fn fn) -{ - for_each_chunk(first, last, [&](auto first, auto last) { - init = std::accumulate(first, last, init, fn); - }); - return init; -} - -/*! - * Equivalent of `std::for_each` applied to the range `r`. - */ -template <typename Range, typename Fn> -Fn&& for_each(Range&& r, Fn&& fn) -{ - for_each_chunk(r, [&](auto first, auto last) { - for (; first != last; ++first) - fn(*first); - }); - return std::forward<Fn>(fn); -} - -/*! - * Equivalent of `std::for_each` applied to the range @f$ [first, - * last) @f$. - */ -template <typename Iterator, typename Fn> -Fn&& for_each(Iterator first, Iterator last, Fn&& fn) -{ - for_each_chunk(first, last, [&](auto first, auto last) { - for (; first != last; ++first) - fn(*first); - }); - return std::forward<Fn>(fn); -} - -/*! - * Equivalent of `std::copy` applied to the range `r`. - */ -template <typename Range, typename OutIter> -OutIter copy(Range&& r, OutIter out) -{ - for_each_chunk( - r, [&](auto first, auto last) { out = std::copy(first, last, out); }); - return out; -} - -/*! - * Equivalent of `std::copy` applied to the range @f$ [first, - * last) @f$. - */ -template <typename InIter, typename OutIter> -OutIter copy(InIter first, InIter last, OutIter out) -{ - for_each_chunk(first, last, [&](auto first, auto last) { - out = std::copy(first, last, out); - }); - return out; -} - -/*! - * Equivalent of `std::all_of` applied to the range `r`. - */ -template <typename Range, typename Pred> -bool all_of(Range&& r, Pred p) -{ - return for_each_chunk_p( - r, [&](auto first, auto last) { return std::all_of(first, last, p); }); -} - -/*! - * Equivalent of `std::all_of` applied to the range @f$ [first, last) - * @f$. - */ -template <typename Iter, typename Pred> -bool all_of(Iter first, Iter last, Pred p) -{ - return for_each_chunk_p(first, last, [&](auto first, auto last) { - return std::all_of(first, last, p); - }); -} - -/** @} */ // group: algorithm - -} // namespace immer diff --git a/third_party/immer/immer/array.hpp b/third_party/immer/immer/array.hpp deleted file mode 100644 index 24c8f84c8bbf..000000000000 --- a/third_party/immer/immer/array.hpp +++ /dev/null @@ -1,364 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/arrays/with_capacity.hpp> -#include <immer/memory_policy.hpp> - -namespace immer { - -template <typename T, typename MemoryPolicy> -class array_transient; - -/*! - * Immutable container that stores a sequence of elements in - * contiguous memory. - * - * @tparam T The type of the values to be stored in the container. - * - * @rst - * - * It supports the most efficient iteration and random access, - * equivalent to a ``std::vector`` or ``std::array``, but all - * manipulations are :math:`O(size)`. - * - * .. tip:: Don't be fooled by the bad complexity of this data - * structure. It is a great choice for short sequence or when it - * is seldom or never changed. This depends on the ``sizeof(T)`` - * and the expensiveness of its ``T``'s copy constructor, in case - * of doubt, measure. For basic types, using an `array` when - * :math:`n < 100` is a good heuristic. - * - * @endrst - */ -template <typename T, typename MemoryPolicy = default_memory_policy> -class array -{ - using impl_t = - std::conditional_t<MemoryPolicy::use_transient_rvalues, - detail::arrays::with_capacity<T, MemoryPolicy>, - detail::arrays::no_capacity<T, MemoryPolicy>>; - - using move_t = - std::integral_constant<bool, MemoryPolicy::use_transient_rvalues>; - -public: - using value_type = T; - using reference = const T&; - using size_type = std::size_t; - using difference_type = std::ptrdiff_t; - using const_reference = const T&; - - using iterator = const T*; - using const_iterator = iterator; - using reverse_iterator = std::reverse_iterator<iterator>; - - using memory_policy = MemoryPolicy; - using transient_type = array_transient<T, MemoryPolicy>; - - /*! - * Default constructor. It creates an array of `size() == 0`. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - array() = default; - - /*! - * Constructs an array containing the elements in `values`. - */ - array(std::initializer_list<T> values) - : impl_{impl_t::from_initializer_list(values)} - {} - - /*! - * Constructs a array containing the elements in the range - * defined by the forward iterator `first` and range sentinel `last`. - */ - template <typename Iter, - typename Sent, - std::enable_if_t<detail::compatible_sentinel_v<Iter, Sent> && - detail::is_forward_iterator_v<Iter>, - bool> = true> - array(Iter first, Sent last) - : impl_{impl_t::from_range(first, last)} - {} - - /*! - * Constructs a array containing the element `val` repeated `n` - * times. - */ - array(size_type n, T v = {}) - : impl_{impl_t::from_fill(n, v)} - {} - - /*! - * Returns an iterator pointing at the first element of the - * collection. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator begin() const { return impl_.data(); } - - /*! - * Returns an iterator pointing just after the last element of the - * collection. It does not allocate and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator end() const { return impl_.data() + impl_.size; } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing at the first element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rbegin() const - { - return reverse_iterator{end()}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing after the last element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rend() const - { - return reverse_iterator{begin()}; - } - - /*! - * Returns the number of elements in the container. It does - * not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD std::size_t size() const { return impl_.size; } - - /*! - * Returns `true` if there are no elements in the container. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD bool empty() const { return impl_.size == 0; } - - /*! - * Access the raw data. - */ - IMMER_NODISCARD const T* data() const { return impl_.data(); } - - /*! - * Access the last element. - */ - IMMER_NODISCARD const T& back() const { return data()[size() - 1]; } - - /*! - * Access the first element. - */ - IMMER_NODISCARD const T& front() const { return data()[0]; } - - /*! - * Returns a `const` reference to the element at position `index`. - * It is undefined when @f$ 0 index \geq size() @f$. It does not - * allocate memory and its complexity is *effectively* @f$ O(1) - * @f$. - */ - IMMER_NODISCARD reference operator[](size_type index) const - { - return impl_.get(index); - } - - /*! - * Returns a `const` reference to the element at position - * `index`. It throws an `std::out_of_range` exception when @f$ - * index \geq size() @f$. It does not allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - reference at(size_type index) const { return impl_.get_check(index); } - - /*! - * Returns whether the vectors are equal. - */ - IMMER_NODISCARD bool operator==(const array& other) const - { - return impl_.equals(other.impl_); - } - IMMER_NODISCARD bool operator!=(const array& other) const - { - return !(*this == other); - } - - /*! - * Returns an array with `value` inserted at the end. It may - * allocate memory and its complexity is @f$ O(size) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/array/array.cpp - * :language: c++ - * :dedent: 8 - * :start-after: push-back/start - * :end-before: push-back/end - * - * @endrst - */ - IMMER_NODISCARD array push_back(value_type value) const& - { - return impl_.push_back(std::move(value)); - } - - IMMER_NODISCARD decltype(auto) push_back(value_type value) && - { - return push_back_move(move_t{}, std::move(value)); - } - - /*! - * Returns an array containing value `value` at position `idx`. - * Undefined for `index >= size()`. - * It may allocate memory and its complexity is @f$ O(size) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/array/array.cpp - * :language: c++ - * :dedent: 8 - * :start-after: set/start - * :end-before: set/end - * - * @endrst - */ - IMMER_NODISCARD array set(std::size_t index, value_type value) const& - { - return impl_.assoc(index, std::move(value)); - } - - IMMER_NODISCARD decltype(auto) set(size_type index, value_type value) && - { - return set_move(move_t{}, index, std::move(value)); - } - - /*! - * Returns an array containing the result of the expression - * `fn((*this)[idx])` at position `idx`. - * Undefined for `index >= size()`. - * It may allocate memory and its complexity is @f$ O(size) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/array/array.cpp - * :language: c++ - * :dedent: 8 - * :start-after: update/start - * :end-before: update/end - * - * @endrst - */ - template <typename FnT> - IMMER_NODISCARD array update(std::size_t index, FnT&& fn) const& - { - return impl_.update(index, std::forward<FnT>(fn)); - } - - template <typename FnT> - IMMER_NODISCARD decltype(auto) update(size_type index, FnT&& fn) && - { - return update_move(move_t{}, index, std::forward<FnT>(fn)); - } - - /*! - * Returns a array containing only the first `min(elems, size())` - * elements. It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/array/array.cpp - * :language: c++ - * :dedent: 8 - * :start-after: take/start - * :end-before: take/end - * - * @endrst - */ - IMMER_NODISCARD array take(size_type elems) const& - { - return impl_.take(elems); - } - - IMMER_NODISCARD decltype(auto) take(size_type elems) && - { - return take_move(move_t{}, elems); - } - - /*! - * Returns an @a transient form of this container, an - * `immer::array_transient`. - */ - IMMER_NODISCARD transient_type transient() const& - { - return transient_type{impl_}; - } - IMMER_NODISCARD transient_type transient() && - { - return transient_type{std::move(impl_)}; - } - - // Semi-private - const impl_t& impl() const { return impl_; } - -private: - friend transient_type; - - array(impl_t impl) - : impl_(std::move(impl)) - {} - - array&& push_back_move(std::true_type, value_type value) - { - impl_.push_back_mut({}, std::move(value)); - return std::move(*this); - } - array push_back_move(std::false_type, value_type value) - { - return impl_.push_back(std::move(value)); - } - - array&& set_move(std::true_type, size_type index, value_type value) - { - impl_.assoc_mut({}, index, std::move(value)); - return std::move(*this); - } - array set_move(std::false_type, size_type index, value_type value) - { - return impl_.assoc(index, std::move(value)); - } - - template <typename Fn> - array&& update_move(std::true_type, size_type index, Fn&& fn) - { - impl_.update_mut({}, index, std::forward<Fn>(fn)); - return std::move(*this); - } - template <typename Fn> - array update_move(std::false_type, size_type index, Fn&& fn) - { - return impl_.update(index, std::forward<Fn>(fn)); - } - - array&& take_move(std::true_type, size_type elems) - { - impl_.take_mut({}, elems); - return std::move(*this); - } - array take_move(std::false_type, size_type elems) - { - return impl_.take(elems); - } - - impl_t impl_ = impl_t::empty(); -}; - -} /* namespace immer */ diff --git a/third_party/immer/immer/array_transient.hpp b/third_party/immer/immer/array_transient.hpp deleted file mode 100644 index bc2d1a5b7b2c..000000000000 --- a/third_party/immer/immer/array_transient.hpp +++ /dev/null @@ -1,202 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/arrays/with_capacity.hpp> -#include <immer/memory_policy.hpp> - -namespace immer { - -template <typename T, typename MemoryPolicy> -class array; - -/*! - * Mutable version of `immer::array`. - * - * @rst - * - * Refer to :doc:`transients` to learn more about when and how to use - * the mutable versions of immutable containers. - * - * @endrst - */ -template <typename T, typename MemoryPolicy = default_memory_policy> -class array_transient : MemoryPolicy::transience_t::owner -{ - using impl_t = detail::arrays::with_capacity<T, MemoryPolicy>; - using impl_no_capacity_t = detail::arrays::no_capacity<T, MemoryPolicy>; - using owner_t = typename MemoryPolicy::transience_t::owner; - -public: - using value_type = T; - using reference = const T&; - using size_type = std::size_t; - using difference_type = std::ptrdiff_t; - using const_reference = const T&; - - using iterator = const T*; - using const_iterator = iterator; - using reverse_iterator = std::reverse_iterator<iterator>; - - using memory_policy = MemoryPolicy; - using persistent_type = array<T, MemoryPolicy>; - - /*! - * Default constructor. It creates a mutable array of `size() == - * 0`. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - array_transient() = default; - - /*! - * Returns an iterator pointing at the first element of the - * collection. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator begin() const { return impl_.data(); } - - /*! - * Returns an iterator pointing just after the last element of the - * collection. It does not allocate and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator end() const { return impl_.data() + impl_.size; } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing at the first element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rbegin() const - { - return reverse_iterator{end()}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing after the last element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rend() const - { - return reverse_iterator{begin()}; - } - - /*! - * Returns the number of elements in the container. It does - * not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD std::size_t size() const { return impl_.size; } - - /*! - * Returns `true` if there are no elements in the container. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD bool empty() const { return impl_.size == 0; } - - /*! - * Access the raw data. - */ - IMMER_NODISCARD const T* data() const { return impl_.data(); } - - /*! - * Provide mutable access to the raw underlaying data. - */ - IMMER_NODISCARD T* data_mut() { return impl_.data_mut(*this); } - - /*! - * Access the last element. - */ - IMMER_NODISCARD const T& back() const { return data()[size() - 1]; } - - /*! - * Access the first element. - */ - IMMER_NODISCARD const T& front() const { return data()[0]; } - - /*! - * Returns a `const` reference to the element at position `index`. - * It is undefined when @f$ 0 index \geq size() @f$. It does not - * allocate memory and its complexity is *effectively* @f$ O(1) - * @f$. - */ - reference operator[](size_type index) const { return impl_.get(index); } - - /*! - * Returns a `const` reference to the element at position - * `index`. It throws an `std::out_of_range` exception when @f$ - * index \geq size() @f$. It does not allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - reference at(size_type index) const { return impl_.get_check(index); } - - /*! - * Inserts `value` at the end. It may allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - void push_back(value_type value) - { - impl_.push_back_mut(*this, std::move(value)); - } - - /*! - * Sets to the value `value` at position `idx`. - * Undefined for `index >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - void set(size_type index, value_type value) - { - impl_.assoc_mut(*this, index, std::move(value)); - } - - /*! - * Updates the array to contain the result of the expression - * `fn((*this)[idx])` at position `idx`. - * Undefined for `0 >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - template <typename FnT> - void update(size_type index, FnT&& fn) - { - impl_.update_mut(*this, index, std::forward<FnT>(fn)); - } - - /*! - * Resizes the array to only contain the first `min(elems, size())` - * elements. It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - void take(size_type elems) { impl_.take_mut(*this, elems); } - - /*! - * Returns an @a immutable form of this container, an - * `immer::array`. - */ - IMMER_NODISCARD persistent_type persistent() & - { - this->owner_t::operator=(owner_t{}); - return persistent_type{impl_}; - } - IMMER_NODISCARD persistent_type persistent() && - { - return persistent_type{std::move(impl_)}; - } - -private: - friend persistent_type; - - array_transient(impl_t impl) - : impl_(std::move(impl)) - {} - - impl_t impl_ = impl_t::empty(); -}; - -} // namespace immer diff --git a/third_party/immer/immer/atom.hpp b/third_party/immer/immer/atom.hpp deleted file mode 100644 index f3ebb5aa1c0e..000000000000 --- a/third_party/immer/immer/atom.hpp +++ /dev/null @@ -1,254 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/box.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -#include <atomic> -#include <type_traits> - -namespace immer { - -namespace detail { - -template <typename T, typename MemoryPolicy> -struct refcount_atom_impl -{ - using box_type = box<T, MemoryPolicy>; - using value_type = T; - using memory_policy = MemoryPolicy; - using spinlock_t = typename MemoryPolicy::refcount::spinlock_type; - using scoped_lock_t = typename spinlock_t::scoped_lock; - - refcount_atom_impl(const refcount_atom_impl&) = delete; - refcount_atom_impl(refcount_atom_impl&&) = delete; - refcount_atom_impl& operator=(const refcount_atom_impl&) = delete; - refcount_atom_impl& operator=(refcount_atom_impl&&) = delete; - - refcount_atom_impl(box_type b) - : impl_{std::move(b)} - {} - - box_type load() const - { - scoped_lock_t lock{lock_}; - return impl_; - } - - void store(box_type b) - { - scoped_lock_t lock{lock_}; - impl_ = std::move(b); - } - - box_type exchange(box_type b) - { - { - scoped_lock_t lock{lock_}; - swap(b, impl_); - } - return b; - } - - template <typename Fn> - box_type update(Fn&& fn) - { - while (true) { - auto oldv = load(); - auto newv = oldv.update(fn); - { - scoped_lock_t lock{lock_}; - if (oldv.impl_ == impl_.impl_) { - impl_ = newv; - return {newv}; - } - } - } - } - -private: - mutable spinlock_t lock_; - box_type impl_; -}; - -template <typename T, typename MemoryPolicy> -struct gc_atom_impl -{ - using box_type = box<T, MemoryPolicy>; - using value_type = T; - using memory_policy = MemoryPolicy; - - static_assert(std::is_same<typename MemoryPolicy::refcount, - no_refcount_policy>::value, - "gc_atom_impl can only be used when there is no refcount!"); - - gc_atom_impl(const gc_atom_impl&) = delete; - gc_atom_impl(gc_atom_impl&&) = delete; - gc_atom_impl& operator=(const gc_atom_impl&) = delete; - gc_atom_impl& operator=(gc_atom_impl&&) = delete; - - gc_atom_impl(box_type b) - : impl_{b.impl_} - {} - - box_type load() const { return {impl_.load()}; } - - void store(box_type b) { impl_.store(b.impl_); } - - box_type exchange(box_type b) { return {impl_.exchange(b.impl_)}; } - - template <typename Fn> - box_type update(Fn&& fn) - { - while (true) { - auto oldv = box_type{impl_.load()}; - auto newv = oldv.update(fn); - if (impl_.compare_exchange_weak(oldv.impl_, newv.impl_)) - return {newv}; - } - } - -private: - std::atomic<typename box_type::holder*> impl_; -}; - -} // namespace detail - -/*! - * Stores for boxed values of type `T` in a thread-safe manner. - * - * @see box - * - * @rst - * - * .. warning:: If memory policy used includes thread unsafe reference counting, - * no no thread safety is assumed, and the atom becomes thread unsafe too! - * - * .. note:: ``box<T>`` provides a value based box of type ``T``, this is, we - * can think about it as a value-based version of ``std::shared_ptr``. In a - * similar fashion, ``atom<T>`` is in spirit the value-based equivalent of - * C++20 ``std::atomic_shared_ptr``. However, the API does not follow - * ``std::atomic`` interface closely, since it attempts to be a higher level - * construction, most similar to Clojure's ``(atom)``. It is remarkable in - * particular that, since ``box<T>`` underlying object is immutable, using - * ``atom<T>`` is fully thread-safe in ways that ``std::atmic_shared_ptr`` is - * not. This is so because dereferencing the underlying pointer in a - * ``std::atomic_share_ptr`` may require further synchronization, in - * particular when invoking non-const methods. - * - * @endrst - */ -template <typename T, typename MemoryPolicy = default_memory_policy> -class atom -{ -public: - using box_type = box<T, MemoryPolicy>; - using value_type = T; - using memory_policy = MemoryPolicy; - - atom(const atom&) = delete; - atom(atom&&) = delete; - void operator=(const atom&) = delete; - void operator=(atom&&) = delete; - - /*! - * Constructs an atom holding a value `b`; - */ - atom(box_type v = {}) - : impl_{std::move(v)} - {} - - /*! - * Sets a new value in the atom. - */ - atom& operator=(box_type b) - { - impl_.store(std::move(b)); - return *this; - } - - /*! - * Reads the currently stored value in a thread-safe manner. - */ - operator box_type() const { return impl_.load(); } - - /*! - * Reads the currently stored value in a thread-safe manner. - */ - operator value_type() const { return *impl_.load(); } - - /*! - * Reads the currently stored value in a thread-safe manner. - */ - IMMER_NODISCARD box_type load() const { return impl_.load(); } - - /*! - * Stores a new value in a thread-safe manner. - */ - void store(box_type b) { impl_.store(std::move(b)); } - - /*! - * Stores a new value and returns the old value, in a thread-safe manner. - */ - IMMER_NODISCARD box_type exchange(box_type b) - { - return impl_.exchange(std::move(b)); - } - - /*! - * Stores the result of applying `fn` to the current value atomically and - * returns the new resulting value. - * - * @rst - * - * .. warning:: ``fn`` must be a pure function and have no side effects! The - * function might be evaluated multiple times when multiple threads - * content to update the value. - * - * @endrst - */ - template <typename Fn> - box_type update(Fn&& fn) - { - return impl_.update(std::forward<Fn>(fn)); - } - -private: - struct get_refcount_atom_impl - { - template <typename U, typename MP> - struct apply - { - using type = detail::refcount_atom_impl<U, MP>; - }; - }; - - struct get_gc_atom_impl - { - template <typename U, typename MP> - struct apply - { - using type = detail::gc_atom_impl<U, MP>; - }; - }; - - // If we are using "real" garbage collection (we assume this when we use - // `no_refcount_policy`), we just store the pointer in an atomic. If we use - // reference counting, we rely on the reference counting spinlock. - using impl_t = typename std::conditional_t< - std::is_same<typename MemoryPolicy::refcount, - no_refcount_policy>::value, - get_gc_atom_impl, - get_refcount_atom_impl>::template apply<T, MemoryPolicy>::type; - - impl_t impl_; -}; - -} // namespace immer diff --git a/third_party/immer/immer/box.hpp b/third_party/immer/immer/box.hpp deleted file mode 100644 index 0fd2961272ca..000000000000 --- a/third_party/immer/immer/box.hpp +++ /dev/null @@ -1,194 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/util.hpp> -#include <immer/memory_policy.hpp> - -namespace immer { - -namespace detail { - -template <typename U, typename MP> -struct gc_atom_impl; - -template <typename U, typename MP> -struct refcount_atom_impl; - -} // namespace detail - -/*! - * Immutable box for a single value of type `T`. - * - * The box is always copiable and movable. The `T` copy or move - * operations are never called. Since a box is immutable, copying or - * moving just copy the underlying pointers. - */ -template <typename T, typename MemoryPolicy = default_memory_policy> -class box -{ - friend struct detail::gc_atom_impl<T, MemoryPolicy>; - friend struct detail::refcount_atom_impl<T, MemoryPolicy>; - - struct holder : MemoryPolicy::refcount - { - T value; - - template <typename... Args> - holder(Args&&... args) - : value{std::forward<Args>(args)...} - {} - }; - - using heap = typename MemoryPolicy::heap::type; - - holder* impl_ = nullptr; - - box(holder* impl) - : impl_{impl} - {} - -public: - using value_type = T; - using memory_policy = MemoryPolicy; - - /*! - * Constructs a box holding `T{}`. - */ - box() - : impl_{detail::make<heap, holder>()} - {} - - /*! - * Constructs a box holding `T{arg}` - */ - template <typename Arg, - typename Enable = std::enable_if_t< - !std::is_same<box, std::decay_t<Arg>>::value && - std::is_constructible<T, Arg>::value>> - box(Arg&& arg) - : impl_{detail::make<heap, holder>(std::forward<Arg>(arg))} - {} - - /*! - * Constructs a box holding `T{arg1, arg2, args...}` - */ - template <typename Arg1, typename Arg2, typename... Args> - box(Arg1&& arg1, Arg2&& arg2, Args&&... args) - : impl_{detail::make<heap, holder>(std::forward<Arg1>(arg1), - std::forward<Arg2>(arg2), - std::forward<Args>(args)...)} - {} - - friend void swap(box& a, box& b) - { - using std::swap; - swap(a.impl_, b.impl_); - } - - box(box&& other) { swap(*this, other); } - box(const box& other) - : impl_(other.impl_) - { - impl_->inc(); - } - box& operator=(box&& other) - { - swap(*this, other); - return *this; - } - box& operator=(const box& other) - { - auto aux = other; - swap(*this, aux); - return *this; - } - ~box() - { - if (impl_ && impl_->dec()) { - impl_->~holder(); - heap::deallocate(sizeof(holder), impl_); - } - } - - /*! Query the current value. */ - IMMER_NODISCARD const T& get() const { return impl_->value; } - - /*! Conversion to the boxed type. */ - operator const T&() const { return get(); } - - /*! Access via dereference */ - const T& operator*() const { return get(); } - - /*! Access via pointer member access */ - const T* operator->() const { return &get(); } - - /*! Comparison. */ - IMMER_NODISCARD bool operator==(detail::exact_t<const box&> other) const - { - return impl_ == other.value.impl_ || get() == other.value.get(); - } - // Note that the `exact_t` disambiguates comparisons against `T{}` - // directly. In that case we want to use `operator T&` and - // compare directly. We definitely never want to convert a value - // to a box (which causes an allocation) just to compare it. - IMMER_NODISCARD bool operator!=(detail::exact_t<const box&> other) const - { - return !(*this == other.value); - } - IMMER_NODISCARD bool operator<(detail::exact_t<const box&> other) const - { - return get() < other.value.get(); - } - - /*! - * Returns a new box built by applying the `fn` to the underlying - * value. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/box/box.cpp - * :language: c++ - * :dedent: 8 - * :start-after: update/start - * :end-before: update/end - * - * @endrst - */ - template <typename Fn> - IMMER_NODISCARD box update(Fn&& fn) const& - { - return std::forward<Fn>(fn)(get()); - } - template <typename Fn> - IMMER_NODISCARD box&& update(Fn&& fn) && - { - if (impl_->unique()) - impl_->value = std::forward<Fn>(fn)(std::move(impl_->value)); - else - *this = std::forward<Fn>(fn)(impl_->value); - return std::move(*this); - } -}; - -} // namespace immer - -namespace std { - -template <typename T, typename MP> -struct hash<immer::box<T, MP>> -{ - std::size_t operator()(const immer::box<T, MP>& x) const - { - return std::hash<T>{}(*x); - } -}; - -} // namespace std diff --git a/third_party/immer/immer/config.hpp b/third_party/immer/immer/config.hpp deleted file mode 100644 index 581e905a4de3..000000000000 --- a/third_party/immer/immer/config.hpp +++ /dev/null @@ -1,93 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#if defined(__has_cpp_attribute) -#if __has_cpp_attribute(nodiscard) -#define IMMER_NODISCARD [[nodiscard]] -#endif -#else -#if _MSVC_LANG >= 201703L -#define IMMER_NODISCARD [[nodiscard]] -#endif -#endif - -#ifndef IMMER_NODISCARD -#define IMMER_NODISCARD -#endif - -#ifndef IMMER_TAGGED_NODE -#ifdef NDEBUG -#define IMMER_TAGGED_NODE 0 -#else -#define IMMER_TAGGED_NODE 1 -#endif -#endif - -#if IMMER_TAGGED_NODE -#define IMMER_ASSERT_TAGGED(assertion) assert(assertion) -#else -#define IMMER_ASSERT_TAGGED(assertion) -#endif - -#ifndef IMMER_DEBUG_TRACES -#define IMMER_DEBUG_TRACES 0 -#endif - -#ifndef IMMER_DEBUG_PRINT -#define IMMER_DEBUG_PRINT 0 -#endif - -#ifndef IMMER_DEBUG_DEEP_CHECK -#define IMMER_DEBUG_DEEP_CHECK 0 -#endif - -#if IMMER_DEBUG_TRACES || IMMER_DEBUG_PRINT -#include <iostream> -#include <prettyprint.hpp> -#endif - -#if IMMER_DEBUG_TRACES -#define IMMER_TRACE(...) std::cout << __VA_ARGS__ << std::endl -#else -#define IMMER_TRACE(...) -#endif -#define IMMER_TRACE_F(...) \ - IMMER_TRACE(__FILE__ << ":" << __LINE__ << ": " << __VA_ARGS__) -#define IMMER_TRACE_E(expr) IMMER_TRACE(" " << #expr << " = " << (expr)) - -#if defined(_MSC_VER) -#define IMMER_UNREACHABLE __assume(false) -#define IMMER_LIKELY(cond) cond -#define IMMER_UNLIKELY(cond) cond -#define IMMER_FORCEINLINE __forceinline -#define IMMER_PREFETCH(p) -#else -#define IMMER_UNREACHABLE __builtin_unreachable() -#define IMMER_LIKELY(cond) __builtin_expect(!!(cond), 1) -#define IMMER_UNLIKELY(cond) __builtin_expect(!!(cond), 0) -#define IMMER_FORCEINLINE inline __attribute__((always_inline)) -#define IMMER_PREFETCH(p) -// #define IMMER_PREFETCH(p) __builtin_prefetch(p) -#endif - -#define IMMER_DESCENT_DEEP 0 - -#ifdef NDEBUG -#define IMMER_ENABLE_DEBUG_SIZE_HEAP 0 -#else -#define IMMER_ENABLE_DEBUG_SIZE_HEAP 1 -#endif - -namespace immer { - -const auto default_bits = 5; -const auto default_free_list_size = 1 << 10; - -} // namespace immer diff --git a/third_party/immer/immer/detail/arrays/no_capacity.hpp b/third_party/immer/immer/detail/arrays/no_capacity.hpp deleted file mode 100644 index 9cb561e14bc1..000000000000 --- a/third_party/immer/immer/detail/arrays/no_capacity.hpp +++ /dev/null @@ -1,203 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/algorithm.hpp> -#include <immer/detail/arrays/node.hpp> - -namespace immer { -namespace detail { -namespace arrays { - -template <typename T, typename MemoryPolicy> -struct no_capacity -{ - using node_t = node<T, MemoryPolicy>; - using edit_t = typename MemoryPolicy::transience_t::edit; - using size_t = std::size_t; - - node_t* ptr; - size_t size; - - static const no_capacity& empty() - { - static const no_capacity empty_{ - node_t::make_n(0), - 0, - }; - return empty_; - } - - no_capacity(node_t* p, size_t s) - : ptr{p} - , size{s} - {} - - no_capacity(const no_capacity& other) - : no_capacity{other.ptr, other.size} - { - inc(); - } - - no_capacity(no_capacity&& other) - : no_capacity{empty()} - { - swap(*this, other); - } - - no_capacity& operator=(const no_capacity& other) - { - auto next = other; - swap(*this, next); - return *this; - } - - no_capacity& operator=(no_capacity&& other) - { - swap(*this, other); - return *this; - } - - friend void swap(no_capacity& x, no_capacity& y) - { - using std::swap; - swap(x.ptr, y.ptr); - swap(x.size, y.size); - } - - ~no_capacity() { dec(); } - - void inc() - { - using immer::detail::get; - ptr->refs().inc(); - } - - void dec() - { - using immer::detail::get; - if (ptr->refs().dec()) - node_t::delete_n(ptr, size, size); - } - - T* data() { return ptr->data(); } - const T* data() const { return ptr->data(); } - - T* data_mut(edit_t e) - { - if (!ptr->can_mutate(e)) - ptr = node_t::copy_e(e, size, ptr, size); - return data(); - } - - template <typename Iter, - typename Sent, - std::enable_if_t<is_forward_iterator_v<Iter> && - compatible_sentinel_v<Iter, Sent>, - bool> = true> - static no_capacity from_range(Iter first, Sent last) - { - auto count = static_cast<size_t>(distance(first, last)); - if (count == 0) - return empty(); - else - return { - node_t::copy_n(count, first, last), - count, - }; - } - - static no_capacity from_fill(size_t n, T v) - { - return {node_t::fill_n(n, v), n}; - } - - template <typename U> - static no_capacity from_initializer_list(std::initializer_list<U> values) - { - using namespace std; - return from_range(begin(values), end(values)); - } - - template <typename Fn> - void for_each_chunk(Fn&& fn) const - { - std::forward<Fn>(fn)(data(), data() + size); - } - - template <typename Fn> - bool for_each_chunk_p(Fn&& fn) const - { - return std::forward<Fn>(fn)(data(), data() + size); - } - - const T& get(std::size_t index) const { return data()[index]; } - - const T& get_check(std::size_t index) const - { - if (index >= size) - throw std::out_of_range{"out of range"}; - return data()[index]; - } - - bool equals(const no_capacity& other) const - { - return ptr == other.ptr || - (size == other.size && - std::equal(data(), data() + size, other.data())); - } - - no_capacity push_back(T value) const - { - auto p = node_t::copy_n(size + 1, ptr, size); - try { - new (p->data() + size) T{std::move(value)}; - return {p, size + 1}; - } catch (...) { - node_t::delete_n(p, size, size + 1); - throw; - } - } - - no_capacity assoc(std::size_t idx, T value) const - { - auto p = node_t::copy_n(size, ptr, size); - try { - p->data()[idx] = std::move(value); - return {p, size}; - } catch (...) { - node_t::delete_n(p, size, size); - throw; - } - } - - template <typename Fn> - no_capacity update(std::size_t idx, Fn&& op) const - { - auto p = node_t::copy_n(size, ptr, size); - try { - auto& elem = p->data()[idx]; - elem = std::forward<Fn>(op)(std::move(elem)); - return {p, size}; - } catch (...) { - node_t::delete_n(p, size, size); - throw; - } - } - - no_capacity take(std::size_t sz) const - { - auto p = node_t::copy_n(sz, ptr, sz); - return {p, sz}; - } -}; - -} // namespace arrays -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/arrays/node.hpp b/third_party/immer/immer/detail/arrays/node.hpp deleted file mode 100644 index f96a63a9f4af..000000000000 --- a/third_party/immer/immer/detail/arrays/node.hpp +++ /dev/null @@ -1,127 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/combine_standard_layout.hpp> -#include <immer/detail/type_traits.hpp> -#include <immer/detail/util.hpp> - -#include <limits> - -namespace immer { -namespace detail { -namespace arrays { - -template <typename T, typename MemoryPolicy> -struct node -{ - using memory = MemoryPolicy; - using heap = typename MemoryPolicy::heap::type; - using transience = typename memory::transience_t; - using refs_t = typename memory::refcount; - using ownee_t = typename transience::ownee; - using node_t = node; - using edit_t = typename transience::edit; - - struct data_t - { - aligned_storage_for<T> buffer; - }; - - using impl_t = combine_standard_layout_t<data_t, refs_t, ownee_t>; - - impl_t impl; - - constexpr static std::size_t sizeof_n(size_t count) - { - return immer_offsetof(impl_t, d.buffer) + - sizeof(T) * (count == 0 ? 1 : count); - } - - refs_t& refs() const { return auto_const_cast(get<refs_t>(impl)); } - - const ownee_t& ownee() const { return get<ownee_t>(impl); } - ownee_t& ownee() { return get<ownee_t>(impl); } - - const T* data() const { return reinterpret_cast<const T*>(&impl.d.buffer); } - T* data() { return reinterpret_cast<T*>(&impl.d.buffer); } - - bool can_mutate(edit_t e) const - { - return refs().unique() || ownee().can_mutate(e); - } - - static void delete_n(node_t* p, size_t sz, size_t cap) - { - destroy_n(p->data(), sz); - heap::deallocate(sizeof_n(cap), p); - } - - static node_t* make_n(size_t n) - { - return new (heap::allocate(sizeof_n(n))) node_t{}; - } - - static node_t* make_e(edit_t e, size_t n) - { - auto p = make_n(n); - p->ownee() = e; - return p; - } - - static node_t* fill_n(size_t n, T v) - { - auto p = make_n(n); - try { - std::uninitialized_fill_n(p->data(), n, v); - return p; - } catch (...) { - heap::deallocate(sizeof_n(n), p); - throw; - } - } - - template <typename Iter, - typename Sent, - std::enable_if_t<detail::compatible_sentinel_v<Iter, Sent>, - bool> = true> - static node_t* copy_n(size_t n, Iter first, Sent last) - { - auto p = make_n(n); - try { - uninitialized_copy(first, last, p->data()); - return p; - } catch (...) { - heap::deallocate(sizeof_n(n), p); - throw; - } - } - - static node_t* copy_n(size_t n, node_t* p, size_t count) - { - return copy_n(n, p->data(), p->data() + count); - } - - template <typename Iter> - static node_t* copy_e(edit_t e, size_t n, Iter first, Iter last) - { - auto p = copy_n(n, first, last); - p->ownee() = e; - return p; - } - - static node_t* copy_e(edit_t e, size_t n, node_t* p, size_t count) - { - return copy_e(e, n, p->data(), p->data() + count); - } -}; - -} // namespace arrays -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/arrays/with_capacity.hpp b/third_party/immer/immer/detail/arrays/with_capacity.hpp deleted file mode 100644 index 290809e4b6e5..000000000000 --- a/third_party/immer/immer/detail/arrays/with_capacity.hpp +++ /dev/null @@ -1,303 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/arrays/no_capacity.hpp> - -namespace immer { -namespace detail { -namespace arrays { - -template <typename T, typename MemoryPolicy> -struct with_capacity -{ - using no_capacity_t = no_capacity<T, MemoryPolicy>; - - using node_t = node<T, MemoryPolicy>; - using edit_t = typename MemoryPolicy::transience_t::edit; - using size_t = std::size_t; - - node_t* ptr; - size_t size; - size_t capacity; - - static const with_capacity& empty() - { - static const with_capacity empty_{node_t::make_n(1), 0, 1}; - return empty_; - } - - with_capacity(node_t* p, size_t s, size_t c) - : ptr{p} - , size{s} - , capacity{c} - {} - - with_capacity(const with_capacity& other) - : with_capacity{other.ptr, other.size, other.capacity} - { - inc(); - } - - with_capacity(const no_capacity_t& other) - : with_capacity{other.ptr, other.size, other.size} - { - inc(); - } - - with_capacity(with_capacity&& other) - : with_capacity{empty()} - { - swap(*this, other); - } - - with_capacity& operator=(const with_capacity& other) - { - auto next = other; - swap(*this, next); - return *this; - } - - with_capacity& operator=(with_capacity&& other) - { - swap(*this, other); - return *this; - } - - friend void swap(with_capacity& x, with_capacity& y) - { - using std::swap; - swap(x.ptr, y.ptr); - swap(x.size, y.size); - swap(x.capacity, y.capacity); - } - - ~with_capacity() { dec(); } - - void inc() - { - using immer::detail::get; - ptr->refs().inc(); - } - - void dec() - { - using immer::detail::get; - if (ptr->refs().dec()) - node_t::delete_n(ptr, size, capacity); - } - - const T* data() const { return ptr->data(); } - T* data() { return ptr->data(); } - - T* data_mut(edit_t e) - { - if (!ptr->can_mutate(e)) { - auto p = node_t::copy_e(e, capacity, ptr, size); - dec(); - ptr = p; - } - return data(); - } - - operator no_capacity_t() const - { - if (size == capacity) { - ptr->refs().inc(); - return {ptr, size}; - } else { - return {node_t::copy_n(size, ptr, size), size}; - } - } - - template <typename Iter, - typename Sent, - std::enable_if_t<is_forward_iterator_v<Iter> && - compatible_sentinel_v<Iter, Sent>, - bool> = true> - static with_capacity from_range(Iter first, Sent last) - { - auto count = static_cast<size_t>(distance(first, last)); - if (count == 0) - return empty(); - else - return {node_t::copy_n(count, first, last), count, count}; - } - - template <typename U> - static with_capacity from_initializer_list(std::initializer_list<U> values) - { - using namespace std; - return from_range(begin(values), end(values)); - } - - static with_capacity from_fill(size_t n, T v) - { - return {node_t::fill_n(n, v), n, n}; - } - - template <typename Fn> - void for_each_chunk(Fn&& fn) const - { - std::forward<Fn>(fn)(data(), data() + size); - } - - template <typename Fn> - bool for_each_chunk_p(Fn&& fn) const - { - return std::forward<Fn>(fn)(data(), data() + size); - } - - const T& get(std::size_t index) const { return data()[index]; } - - const T& get_check(std::size_t index) const - { - if (index >= size) - throw std::out_of_range{"out of range"}; - return data()[index]; - } - - bool equals(const with_capacity& other) const - { - return ptr == other.ptr || - (size == other.size && - std::equal(data(), data() + size, other.data())); - } - - static size_t recommend_up(size_t sz, size_t cap) - { - auto max = std::numeric_limits<size_t>::max(); - return sz <= cap ? cap - : cap >= max / 2 ? max - /* otherwise */ - : std::max(2 * cap, sz); - } - - static size_t recommend_down(size_t sz, size_t cap) - { - return sz == 0 ? 1 - : sz < cap / 2 ? sz * 2 : - /* otherwise */ cap; - } - - with_capacity push_back(T value) const - { - auto cap = recommend_up(size + 1, capacity); - auto p = node_t::copy_n(cap, ptr, size); - try { - new (p->data() + size) T{std::move(value)}; - return {p, size + 1, cap}; - } catch (...) { - node_t::delete_n(p, size, cap); - throw; - } - } - - void push_back_mut(edit_t e, T value) - { - if (ptr->can_mutate(e) && capacity > size) { - new (data() + size) T{std::move(value)}; - ++size; - } else { - auto cap = recommend_up(size + 1, capacity); - auto p = node_t::copy_e(e, cap, ptr, size); - try { - new (p->data() + size) T{std::move(value)}; - *this = {p, size + 1, cap}; - } catch (...) { - node_t::delete_n(p, size, cap); - throw; - } - } - } - - with_capacity assoc(std::size_t idx, T value) const - { - auto p = node_t::copy_n(capacity, ptr, size); - try { - p->data()[idx] = std::move(value); - return {p, size, capacity}; - } catch (...) { - node_t::delete_n(p, size, capacity); - throw; - } - } - - void assoc_mut(edit_t e, std::size_t idx, T value) - { - if (ptr->can_mutate(e)) { - data()[idx] = std::move(value); - } else { - auto p = node_t::copy_n(capacity, ptr, size); - try { - p->data()[idx] = std::move(value); - *this = {p, size, capacity}; - } catch (...) { - node_t::delete_n(p, size, capacity); - throw; - } - } - } - - template <typename Fn> - with_capacity update(std::size_t idx, Fn&& op) const - { - auto p = node_t::copy_n(capacity, ptr, size); - try { - auto& elem = p->data()[idx]; - elem = std::forward<Fn>(op)(std::move(elem)); - return {p, size, capacity}; - } catch (...) { - node_t::delete_n(p, size, capacity); - throw; - } - } - - template <typename Fn> - void update_mut(edit_t e, std::size_t idx, Fn&& op) - { - if (ptr->can_mutate(e)) { - auto& elem = data()[idx]; - elem = std::forward<Fn>(op)(std::move(elem)); - } else { - auto p = node_t::copy_e(e, capacity, ptr, size); - try { - auto& elem = p->data()[idx]; - elem = std::forward<Fn>(op)(std::move(elem)); - *this = {p, size, capacity}; - } catch (...) { - node_t::delete_n(p, size, capacity); - throw; - } - } - } - - with_capacity take(std::size_t sz) const - { - auto cap = recommend_down(sz, capacity); - auto p = node_t::copy_n(cap, ptr, sz); - return {p, sz, cap}; - } - - void take_mut(edit_t e, std::size_t sz) - { - if (ptr->can_mutate(e)) { - destroy_n(data() + size, size - sz); - size = sz; - } else { - auto cap = recommend_down(sz, capacity); - auto p = node_t::copy_e(e, cap, ptr, sz); - *this = {p, sz, cap}; - } - } -}; - -} // namespace arrays -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/combine_standard_layout.hpp b/third_party/immer/immer/detail/combine_standard_layout.hpp deleted file mode 100644 index 55c69bc91682..000000000000 --- a/third_party/immer/immer/detail/combine_standard_layout.hpp +++ /dev/null @@ -1,235 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <type_traits> - -#if defined(__GNUC__) && __GNUC__ == 7 && __GNUC_MINOR__ == 1 -#define IMMER_BROKEN_STANDARD_LAYOUT_DETECTION 1 -#define immer_offsetof(st, m) ((std::size_t) & (((st*) 0)->m)) -#else -#define IMMER_BROKEN_STANDARD_LAYOUT_DETECTION 0 -#define immer_offsetof offsetof -#endif - -namespace immer { -namespace detail { - -// -// Metafunction that returns a standard layout struct that combines -// all the standard layout types in `Ts...`, while making sure that -// empty base optimizations are used. -// -// To query a part of the type do `get<my_part>(x)`; -// -// This is useful when putting together a type that merges various -// types coming from different policies. Some of them might be empty, -// so we shall enable empty base optimizations. But if we just -// inherit from all of them, we would break the "standard layout" -// rules, preventing us from using `offseof(...)`. So metafunction -// will generate the type by sometimes inheriting, sometimes adding as -// member. -// -// Note that the types are added to the combined type from right to -// left! -// -template <typename... Ts> -struct combine_standard_layout; - -template <typename... Ts> -using combine_standard_layout_t = typename combine_standard_layout<Ts...>::type; - -namespace csl { - -template <typename T> -struct type_t -{}; - -template <typename U, typename T> -U& get(T& x); - -template <typename U, typename T> -const U& get(const T& x); - -template <typename T, typename Next = void> -struct inherit -{ - struct type - : T - , Next - { - using Next::get_; - - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return *this; } - const T& get_(type_t<T>) const { return *this; } - }; -}; - -template <typename T> -struct inherit<T, void> -{ - struct type : T - { - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return *this; } - const T& get_(type_t<T>) const { return *this; } - }; -}; - -template <typename T, typename Next = void> -struct member -{ - struct type : Next - { - T d; - - using Next::get_; - - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return d; } - const T& get_(type_t<T>) const { return d; } - }; -}; - -template <typename T> -struct member<T, void> -{ - struct type - { - T d; - - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return d; } - const T& get_(type_t<T>) const { return d; } - }; -}; - -template <typename T, typename Next> -struct member_two -{ - struct type - { - Next n; - T d; - - template <typename U> - friend decltype(auto) get(type& x) - { - return x.get_(type_t<U>{}); - } - template <typename U> - friend decltype(auto) get(const type& x) - { - return x.get_(type_t<U>{}); - } - - T& get_(type_t<T>) { return d; } - const T& get_(type_t<T>) const { return d; } - - template <typename U> - auto get_(type_t<U> t) -> decltype(auto) - { - return n.get_(t); - } - template <typename U> - auto get_(type_t<U> t) const -> decltype(auto) - { - return n.get_(t); - } - }; -}; - -template <typename... Ts> -struct combine_standard_layout_aux; - -template <typename T> -struct combine_standard_layout_aux<T> -{ - static_assert(std::is_standard_layout<T>::value, ""); - - using type = typename std::conditional_t<std::is_empty<T>::value, - csl::inherit<T>, - csl::member<T>>::type; -}; - -template <typename T, typename... Ts> -struct combine_standard_layout_aux<T, Ts...> -{ - static_assert(std::is_standard_layout<T>::value, ""); - - using this_t = T; - using next_t = typename combine_standard_layout_aux<Ts...>::type; - - static constexpr auto empty_this = std::is_empty<this_t>::value; - static constexpr auto empty_next = std::is_empty<next_t>::value; - - using type = typename std::conditional_t< - empty_this, - inherit<this_t, next_t>, - std::conditional_t<empty_next, - member<this_t, next_t>, - member_two<this_t, next_t>>>::type; -}; - -} // namespace csl - -using csl::get; - -template <typename... Ts> -struct combine_standard_layout -{ - using type = typename csl::combine_standard_layout_aux<Ts...>::type; -#if !IMMER_BROKEN_STANDARD_LAYOUT_DETECTION - static_assert(std::is_standard_layout<type>::value, ""); -#endif -}; - -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/hamts/bits.hpp b/third_party/immer/immer/detail/hamts/bits.hpp deleted file mode 100644 index b02caf770666..000000000000 --- a/third_party/immer/immer/detail/hamts/bits.hpp +++ /dev/null @@ -1,108 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <cstdint> - -#if defined(_MSC_VER) -#include <intrin.h> // __popcnt -#endif - -namespace immer { -namespace detail { -namespace hamts { - -using size_t = std::size_t; -using hash_t = std::size_t; -using bits_t = std::uint32_t; -using count_t = std::uint32_t; -using shift_t = std::uint32_t; - -template <bits_t B> -struct get_bitmap_type -{ - static_assert(B < 6u, "B > 6 is not supported."); - - using type = std::uint32_t; -}; - -template <> -struct get_bitmap_type<6u> -{ - using type = std::uint64_t; -}; - -template <bits_t B, typename T = count_t> -constexpr T branches = T{1u} << B; - -template <bits_t B, typename T = size_t> -constexpr T mask = branches<B, T> - 1u; - -template <bits_t B, typename T = count_t> -constexpr T max_depth = (sizeof(hash_t) * 8u + B - 1u) / B; - -template <bits_t B, typename T = count_t> -constexpr T max_shift = max_depth<B, count_t>* B; - -#define IMMER_HAS_BUILTIN_POPCOUNT 1 - -inline auto popcount_fallback(std::uint32_t x) -{ - // More alternatives: - // https://en.wikipedia.org/wiki/Hamming_weight - // http://wm.ite.pl/articles/sse-popcount.html - // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel - x = x - ((x >> 1) & 0x55555555u); - x = (x & 0x33333333u) + ((x >> 2) & 0x33333333u); - return (((x + (x >> 4u)) & 0xF0F0F0Fu) * 0x1010101u) >> 24u; -} - -inline auto popcount_fallback(std::uint64_t x) -{ - x = x - ((x >> 1) & 0x5555555555555555u); - x = (x & 0x3333333333333333u) + ((x >> 2u) & 0x3333333333333333u); - return (((x + (x >> 4)) & 0x0F0F0F0F0F0F0F0Fu) * 0x0101010101010101u) >> - 56u; -} - -inline count_t popcount(std::uint32_t x) -{ -#if IMMER_HAS_BUILTIN_POPCOUNT -#if defined(_MSC_VER) - return __popcnt(x); -#else - return __builtin_popcount(x); -#endif -#else - return popcount_fallback(x); -#endif -} - -inline count_t popcount(std::uint64_t x) -{ -#if IMMER_HAS_BUILTIN_POPCOUNT -#if defined(_MSC_VER) -#if defined(_WIN64) - return __popcnt64(x); -#else - // TODO: benchmark against popcount_fallback(std::uint64_t x) - return popcount(static_cast<std::uint32_t>(x >> 32)) + - popcount(static_cast<std::uint32_t>(x)); -#endif -#else - return __builtin_popcountll(x); -#endif -#else - return popcount_fallback(x); -#endif -} - -} // namespace hamts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/hamts/champ.hpp b/third_party/immer/immer/detail/hamts/champ.hpp deleted file mode 100644 index e3b55d397c72..000000000000 --- a/third_party/immer/immer/detail/hamts/champ.hpp +++ /dev/null @@ -1,473 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/config.hpp> -#include <immer/detail/hamts/node.hpp> - -#include <algorithm> - -namespace immer { -namespace detail { -namespace hamts { - -template <typename T, - typename Hash, - typename Equal, - typename MemoryPolicy, - bits_t B> -struct champ -{ - static constexpr auto bits = B; - - using node_t = node<T, Hash, Equal, MemoryPolicy, B>; - using bitmap_t = typename get_bitmap_type<B>::type; - - static_assert(branches<B> <= sizeof(bitmap_t) * 8, ""); - - node_t* root; - size_t size; - - static const champ& empty() - { - static const champ empty_{ - node_t::make_inner_n(0), - 0, - }; - return empty_; - } - - champ(node_t* r, size_t sz) - : root{r} - , size{sz} - {} - - champ(const champ& other) - : champ{other.root, other.size} - { - inc(); - } - - champ(champ&& other) - : champ{empty()} - { - swap(*this, other); - } - - champ& operator=(const champ& other) - { - auto next = other; - swap(*this, next); - return *this; - } - - champ& operator=(champ&& other) - { - swap(*this, other); - return *this; - } - - friend void swap(champ& x, champ& y) - { - using std::swap; - swap(x.root, y.root); - swap(x.size, y.size); - } - - ~champ() { dec(); } - - void inc() const { root->inc(); } - - void dec() const - { - if (root->dec()) - node_t::delete_deep(root, 0); - } - - template <typename Fn> - void for_each_chunk(Fn&& fn) const - { - for_each_chunk_traversal(root, 0, fn); - } - - template <typename Fn> - void for_each_chunk_traversal(node_t* node, count_t depth, Fn&& fn) const - { - if (depth < max_depth<B>) { - auto datamap = node->datamap(); - if (datamap) - fn(node->values(), node->values() + popcount(datamap)); - auto nodemap = node->nodemap(); - if (nodemap) { - auto fst = node->children(); - auto lst = fst + popcount(nodemap); - for (; fst != lst; ++fst) - for_each_chunk_traversal(*fst, depth + 1, fn); - } - } else { - fn(node->collisions(), - node->collisions() + node->collision_count()); - } - } - - template <typename Project, typename Default, typename K> - decltype(auto) get(const K& k) const - { - auto node = root; - auto hash = Hash{}(k); - for (auto i = count_t{}; i < max_depth<B>; ++i) { - auto bit = bitmap_t{1u} << (hash & mask<B>); - if (node->nodemap() & bit) { - auto offset = popcount(node->nodemap() & (bit - 1)); - node = node->children()[offset]; - hash = hash >> B; - } else if (node->datamap() & bit) { - auto offset = popcount(node->datamap() & (bit - 1)); - auto val = node->values() + offset; - if (Equal{}(*val, k)) - return Project{}(*val); - else - return Default{}(); - } else { - return Default{}(); - } - } - auto fst = node->collisions(); - auto lst = fst + node->collision_count(); - for (; fst != lst; ++fst) - if (Equal{}(*fst, k)) - return Project{}(*fst); - return Default{}(); - } - - std::pair<node_t*, bool> - do_add(node_t* node, T v, hash_t hash, shift_t shift) const - { - if (shift == max_shift<B>) { - auto fst = node->collisions(); - auto lst = fst + node->collision_count(); - for (; fst != lst; ++fst) - if (Equal{}(*fst, v)) - return { - node_t::copy_collision_replace(node, fst, std::move(v)), - false}; - return {node_t::copy_collision_insert(node, std::move(v)), true}; - } else { - auto idx = (hash & (mask<B> << shift)) >> shift; - auto bit = bitmap_t{1u} << idx; - if (node->nodemap() & bit) { - auto offset = popcount(node->nodemap() & (bit - 1)); - auto result = do_add( - node->children()[offset], std::move(v), hash, shift + B); - try { - result.first = - node_t::copy_inner_replace(node, offset, result.first); - return result; - } catch (...) { - node_t::delete_deep_shift(result.first, shift + B); - throw; - } - } else if (node->datamap() & bit) { - auto offset = popcount(node->datamap() & (bit - 1)); - auto val = node->values() + offset; - if (Equal{}(*val, v)) - return {node_t::copy_inner_replace_value( - node, offset, std::move(v)), - false}; - else { - auto child = node_t::make_merged( - shift + B, std::move(v), hash, *val, Hash{}(*val)); - try { - return {node_t::copy_inner_replace_merged( - node, bit, offset, child), - true}; - } catch (...) { - node_t::delete_deep_shift(child, shift + B); - throw; - } - } - } else { - return { - node_t::copy_inner_insert_value(node, bit, std::move(v)), - true}; - } - } - } - - champ add(T v) const - { - auto hash = Hash{}(v); - auto res = do_add(root, std::move(v), hash, 0); - auto new_size = size + (res.second ? 1 : 0); - return {res.first, new_size}; - } - - template <typename Project, - typename Default, - typename Combine, - typename K, - typename Fn> - std::pair<node_t*, bool> - do_update(node_t* node, K&& k, Fn&& fn, hash_t hash, shift_t shift) const - { - if (shift == max_shift<B>) { - auto fst = node->collisions(); - auto lst = fst + node->collision_count(); - for (; fst != lst; ++fst) - if (Equal{}(*fst, k)) - return { - node_t::copy_collision_replace( - node, - fst, - Combine{}(std::forward<K>(k), - std::forward<Fn>(fn)(Project{}(*fst)))), - false}; - return {node_t::copy_collision_insert( - node, - Combine{}(std::forward<K>(k), - std::forward<Fn>(fn)(Default{}()))), - true}; - } else { - auto idx = (hash & (mask<B> << shift)) >> shift; - auto bit = bitmap_t{1u} << idx; - if (node->nodemap() & bit) { - auto offset = popcount(node->nodemap() & (bit - 1)); - auto result = do_update<Project, Default, Combine>( - node->children()[offset], - k, - std::forward<Fn>(fn), - hash, - shift + B); - try { - result.first = - node_t::copy_inner_replace(node, offset, result.first); - return result; - } catch (...) { - node_t::delete_deep_shift(result.first, shift + B); - throw; - } - } else if (node->datamap() & bit) { - auto offset = popcount(node->datamap() & (bit - 1)); - auto val = node->values() + offset; - if (Equal{}(*val, k)) - return { - node_t::copy_inner_replace_value( - node, - offset, - Combine{}(std::forward<K>(k), - std::forward<Fn>(fn)(Project{}(*val)))), - false}; - else { - auto child = node_t::make_merged( - shift + B, - Combine{}(std::forward<K>(k), - std::forward<Fn>(fn)(Default{}())), - hash, - *val, - Hash{}(*val)); - try { - return {node_t::copy_inner_replace_merged( - node, bit, offset, child), - true}; - } catch (...) { - node_t::delete_deep_shift(child, shift + B); - throw; - } - } - } else { - return {node_t::copy_inner_insert_value( - node, - bit, - Combine{}(std::forward<K>(k), - std::forward<Fn>(fn)(Default{}()))), - true}; - } - } - } - - template <typename Project, - typename Default, - typename Combine, - typename K, - typename Fn> - champ update(const K& k, Fn&& fn) const - { - auto hash = Hash{}(k); - auto res = do_update<Project, Default, Combine>( - root, k, std::forward<Fn>(fn), hash, 0); - auto new_size = size + (res.second ? 1 : 0); - return {res.first, new_size}; - } - - // basically: - // variant<monostate_t, T*, node_t*> - // boo bad we are not using... C++17 :'( - struct sub_result - { - enum kind_t - { - nothing, - singleton, - tree - }; - - union data_t - { - T* singleton; - node_t* tree; - }; - - kind_t kind; - data_t data; - - sub_result() - : kind{nothing} {}; - sub_result(T* x) - : kind{singleton} - { - data.singleton = x; - }; - sub_result(node_t* x) - : kind{tree} - { - data.tree = x; - }; - }; - - template <typename K> - sub_result - do_sub(node_t* node, const K& k, hash_t hash, shift_t shift) const - { - if (shift == max_shift<B>) { - auto fst = node->collisions(); - auto lst = fst + node->collision_count(); - for (auto cur = fst; cur != lst; ++cur) - if (Equal{}(*cur, k)) - return node->collision_count() > 2 - ? node_t::copy_collision_remove(node, cur) - : sub_result{fst + (cur == fst)}; - return {}; - } else { - auto idx = (hash & (mask<B> << shift)) >> shift; - auto bit = bitmap_t{1u} << idx; - if (node->nodemap() & bit) { - auto offset = popcount(node->nodemap() & (bit - 1)); - auto result = - do_sub(node->children()[offset], k, hash, shift + B); - switch (result.kind) { - case sub_result::nothing: - return {}; - case sub_result::singleton: - return node->datamap() == 0 && - popcount(node->nodemap()) == 1 && shift > 0 - ? result - : node_t::copy_inner_replace_inline( - node, bit, offset, *result.data.singleton); - case sub_result::tree: - try { - return node_t::copy_inner_replace( - node, offset, result.data.tree); - } catch (...) { - node_t::delete_deep_shift(result.data.tree, shift + B); - throw; - } - } - } else if (node->datamap() & bit) { - auto offset = popcount(node->datamap() & (bit - 1)); - auto val = node->values() + offset; - if (Equal{}(*val, k)) { - auto nv = popcount(node->datamap()); - if (node->nodemap() || nv > 2) - return node_t::copy_inner_remove_value( - node, bit, offset); - else if (nv == 2) { - return shift > 0 ? sub_result{node->values() + !offset} - : node_t::make_inner_n( - 0, - node->datamap() & ~bit, - node->values()[!offset]); - } else { - assert(shift == 0); - return empty().root->inc(); - } - } - } - return {}; - } - } - - template <typename K> - champ sub(const K& k) const - { - auto hash = Hash{}(k); - auto res = do_sub(root, k, hash, 0); - switch (res.kind) { - case sub_result::nothing: - return *this; - case sub_result::tree: - return {res.data.tree, size - 1}; - default: - IMMER_UNREACHABLE; - } - } - - template <typename Eq = Equal> - bool equals(const champ& other) const - { - return size == other.size && equals_tree<Eq>(root, other.root, 0); - } - - template <typename Eq> - static bool equals_tree(const node_t* a, const node_t* b, count_t depth) - { - if (a == b) - return true; - else if (depth == max_depth<B>) { - auto nv = a->collision_count(); - return nv == b->collision_count() && - equals_collisions<Eq>(a->collisions(), b->collisions(), nv); - } else { - if (a->nodemap() != b->nodemap() || a->datamap() != b->datamap()) - return false; - auto n = popcount(a->nodemap()); - for (auto i = count_t{}; i < n; ++i) - if (!equals_tree<Eq>( - a->children()[i], b->children()[i], depth + 1)) - return false; - auto nv = popcount(a->datamap()); - return !nv || equals_values<Eq>(a->values(), b->values(), nv); - } - } - - template <typename Eq> - static bool equals_values(const T* a, const T* b, count_t n) - { - return std::equal(a, a + n, b, Eq{}); - } - - template <typename Eq> - static bool equals_collisions(const T* a, const T* b, count_t n) - { - auto ae = a + n; - auto be = b + n; - for (; a != ae; ++a) { - for (auto fst = b; fst != be; ++fst) - if (Eq{}(*a, *fst)) - goto good; - return false; - good: - continue; - } - return true; - } -}; - -} // namespace hamts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/hamts/champ_iterator.hpp b/third_party/immer/immer/detail/hamts/champ_iterator.hpp deleted file mode 100644 index 72673b41be03..000000000000 --- a/third_party/immer/immer/detail/hamts/champ_iterator.hpp +++ /dev/null @@ -1,148 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/hamts/champ.hpp> -#include <immer/detail/iterator_facade.hpp> - -namespace immer { -namespace detail { -namespace hamts { - -template <typename T, typename Hash, typename Eq, typename MP, bits_t B> -struct champ_iterator - : iterator_facade<champ_iterator<T, Hash, Eq, MP, B>, - std::forward_iterator_tag, - T, - const T&, - std::ptrdiff_t, - const T*> -{ - using tree_t = champ<T, Hash, Eq, MP, B>; - using node_t = typename tree_t::node_t; - - struct end_t - {}; - - champ_iterator() = default; - - champ_iterator(const tree_t& v) - : depth_{0} - { - if (v.root->datamap()) { - cur_ = v.root->values(); - end_ = v.root->values() + popcount(v.root->datamap()); - } else { - cur_ = end_ = nullptr; - } - path_[0] = &v.root; - ensure_valid_(); - } - - champ_iterator(const tree_t& v, end_t) - : cur_{nullptr} - , end_{nullptr} - , depth_{0} - { - path_[0] = &v.root; - } - - champ_iterator(const champ_iterator& other) - : cur_{other.cur_} - , end_{other.end_} - , depth_{other.depth_} - { - std::copy(other.path_, other.path_ + depth_ + 1, path_); - } - -private: - friend iterator_core_access; - - T* cur_; - T* end_; - count_t depth_; - node_t* const* path_[max_depth<B> + 1]; - - void increment() - { - ++cur_; - ensure_valid_(); - } - - bool step_down() - { - if (depth_ < max_depth<B>) { - auto parent = *path_[depth_]; - if (parent->nodemap()) { - ++depth_; - path_[depth_] = parent->children(); - auto child = *path_[depth_]; - if (depth_ < max_depth<B>) { - if (child->datamap()) { - cur_ = child->values(); - end_ = cur_ + popcount(child->datamap()); - } - } else { - cur_ = child->collisions(); - end_ = cur_ + child->collision_count(); - } - return true; - } - } - return false; - } - - bool step_right() - { - while (depth_ > 0) { - auto parent = *path_[depth_ - 1]; - auto last = parent->children() + popcount(parent->nodemap()); - auto next = path_[depth_] + 1; - if (next < last) { - path_[depth_] = next; - auto child = *path_[depth_]; - if (depth_ < max_depth<B>) { - if (child->datamap()) { - cur_ = child->values(); - end_ = cur_ + popcount(child->datamap()); - } - } else { - cur_ = child->collisions(); - end_ = cur_ + child->collision_count(); - } - return true; - } - --depth_; - } - return false; - } - - void ensure_valid_() - { - while (cur_ == end_) { - while (step_down()) - if (cur_ != end_) - return; - if (!step_right()) { - // end of sequence - assert(depth_ == 0); - cur_ = end_ = nullptr; - return; - } - } - } - - bool equal(const champ_iterator& other) const { return cur_ == other.cur_; } - - const T& dereference() const { return *cur_; } -}; - -} // namespace hamts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/hamts/node.hpp b/third_party/immer/immer/detail/hamts/node.hpp deleted file mode 100644 index 216e82b7874f..000000000000 --- a/third_party/immer/immer/detail/hamts/node.hpp +++ /dev/null @@ -1,717 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/combine_standard_layout.hpp> -#include <immer/detail/hamts/bits.hpp> -#include <immer/detail/util.hpp> - -#include <cassert> - -namespace immer { -namespace detail { -namespace hamts { - -template <typename T, - typename Hash, - typename Equal, - typename MemoryPolicy, - bits_t B> -struct node -{ - using node_t = node; - - using memory = MemoryPolicy; - using heap_policy = typename memory::heap; - using heap = typename heap_policy::type; - using transience = typename memory::transience_t; - using refs_t = typename memory::refcount; - using ownee_t = typename transience::ownee; - using edit_t = typename transience::edit; - using value_t = T; - using bitmap_t = typename get_bitmap_type<B>::type; - - enum class kind_t - { - collision, - inner - }; - - struct collision_t - { - count_t count; - aligned_storage_for<T> buffer; - }; - - struct values_data_t - { - aligned_storage_for<T> buffer; - }; - - using values_t = combine_standard_layout_t<values_data_t, refs_t>; - - struct inner_t - { - bitmap_t nodemap; - bitmap_t datamap; - values_t* values; - aligned_storage_for<node_t*> buffer; - }; - - union data_t - { - inner_t inner; - collision_t collision; - }; - - struct impl_data_t - { -#if IMMER_TAGGED_NODE - kind_t kind; -#endif - data_t data; - }; - - using impl_t = combine_standard_layout_t<impl_data_t, refs_t>; - - impl_t impl; - - constexpr static std::size_t sizeof_values_n(count_t count) - { - return std::max(sizeof(values_t), - immer_offsetof(values_t, d.buffer) + - sizeof(values_data_t::buffer) * count); - } - - constexpr static std::size_t sizeof_collision_n(count_t count) - { - return immer_offsetof(impl_t, d.data.collision.buffer) + - sizeof(collision_t::buffer) * count; - } - - constexpr static std::size_t sizeof_inner_n(count_t count) - { - return immer_offsetof(impl_t, d.data.inner.buffer) + - sizeof(inner_t::buffer) * count; - } - -#if IMMER_TAGGED_NODE - kind_t kind() const { return impl.d.kind; } -#endif - - auto values() - { - IMMER_ASSERT_TAGGED(kind() == kind_t::inner); - assert(impl.d.data.inner.values); - return (T*) &impl.d.data.inner.values->d.buffer; - } - - auto values() const - { - IMMER_ASSERT_TAGGED(kind() == kind_t::inner); - assert(impl.d.data.inner.values); - return (const T*) &impl.d.data.inner.values->d.buffer; - } - - auto children() - { - IMMER_ASSERT_TAGGED(kind() == kind_t::inner); - return (node_t**) &impl.d.data.inner.buffer; - } - - auto children() const - { - IMMER_ASSERT_TAGGED(kind() == kind_t::inner); - return (const node_t* const*) &impl.d.data.inner.buffer; - } - - auto datamap() const - { - IMMER_ASSERT_TAGGED(kind() == kind_t::inner); - return impl.d.data.inner.datamap; - } - - auto nodemap() const - { - IMMER_ASSERT_TAGGED(kind() == kind_t::inner); - return impl.d.data.inner.nodemap; - } - - auto collision_count() const - { - IMMER_ASSERT_TAGGED(kind() == kind_t::collision); - return impl.d.data.collision.count; - } - - T* collisions() - { - IMMER_ASSERT_TAGGED(kind() == kind_t::collision); - return (T*) &impl.d.data.collision.buffer; - } - - const T* collisions() const - { - IMMER_ASSERT_TAGGED(kind() == kind_t::collision); - return (const T*) &impl.d.data.collision.buffer; - } - - static refs_t& refs(const values_t* x) - { - return auto_const_cast(get<refs_t>(*x)); - } - static const ownee_t& ownee(const values_t* x) { return get<ownee_t>(*x); } - static ownee_t& ownee(values_t* x) { return get<ownee_t>(*x); } - - static refs_t& refs(const node_t* x) - { - return auto_const_cast(get<refs_t>(x->impl)); - } - static const ownee_t& ownee(const node_t* x) - { - return get<ownee_t>(x->impl); - } - static ownee_t& ownee(node_t* x) { return get<ownee_t>(x->impl); } - - static node_t* make_inner_n(count_t n) - { - assert(n <= branches<B>); - auto m = heap::allocate(sizeof_inner_n(n)); - auto p = new (m) node_t; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::inner; -#endif - p->impl.d.data.inner.nodemap = 0; - p->impl.d.data.inner.datamap = 0; - p->impl.d.data.inner.values = nullptr; - return p; - } - - static node_t* make_inner_n(count_t n, values_t* values) - { - auto p = make_inner_n(n); - if (values) { - p->impl.d.data.inner.values = values; - refs(values).inc(); - } - return p; - } - - static node_t* make_inner_n(count_t n, count_t nv) - { - assert(nv <= branches<B>); - auto p = make_inner_n(n); - if (nv) { - try { - p->impl.d.data.inner.values = - new (heap::allocate(sizeof_values_n(nv))) values_t{}; - } catch (...) { - deallocate_inner(p, n); - throw; - } - } - return p; - } - - static node_t* make_inner_n(count_t n, count_t idx, node_t* child) - { - assert(n >= 1); - auto p = make_inner_n(n); - p->impl.d.data.inner.nodemap = bitmap_t{1u} << idx; - p->children()[0] = child; - return p; - } - - static node_t* make_inner_n(count_t n, bitmap_t bitmap, T x) - { - auto p = make_inner_n(n, 1); - p->impl.d.data.inner.datamap = bitmap; - try { - new (p->values()) T{std::move(x)}; - } catch (...) { - deallocate_inner(p, n, 1); - throw; - } - return p; - } - - static node_t* - make_inner_n(count_t n, count_t idx1, T x1, count_t idx2, T x2) - { - assert(idx1 != idx2); - auto p = make_inner_n(n, 2); - p->impl.d.data.inner.datamap = - (bitmap_t{1u} << idx1) | (bitmap_t{1u} << idx2); - auto assign = [&](auto&& x1, auto&& x2) { - auto vp = p->values(); - try { - new (vp) T{std::move(x1)}; - try { - new (vp + 1) T{std::move(x2)}; - } catch (...) { - vp->~T(); - throw; - } - } catch (...) { - deallocate_inner(p, n, 2); - throw; - } - }; - if (idx1 < idx2) - assign(x1, x2); - else - assign(x2, x1); - return p; - } - - static node_t* make_collision_n(count_t n) - { - auto m = heap::allocate(sizeof_collision_n(n)); - auto p = new (m) node_t; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::collision; -#endif - p->impl.d.data.collision.count = n; - return p; - } - - static node_t* make_collision(T v1, T v2) - { - auto m = heap::allocate(sizeof_collision_n(2)); - auto p = new (m) node_t; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::collision; -#endif - p->impl.d.data.collision.count = 2; - auto cols = p->collisions(); - try { - new (cols) T{std::move(v1)}; - try { - new (cols + 1) T{std::move(v2)}; - } catch (...) { - cols->~T(); - throw; - } - } catch (...) { - deallocate_collision(p, 2); - throw; - } - return p; - } - - static node_t* copy_collision_insert(node_t* src, T v) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::collision); - auto n = src->collision_count(); - auto dst = make_collision_n(n + 1); - auto srcp = src->collisions(); - auto dstp = dst->collisions(); - try { - new (dstp) T{std::move(v)}; - try { - std::uninitialized_copy(srcp, srcp + n, dstp + 1); - } catch (...) { - dstp->~T(); - throw; - } - } catch (...) { - deallocate_collision(dst, n + 1); - throw; - } - return dst; - } - - static node_t* copy_collision_remove(node_t* src, T* v) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::collision); - assert(src->collision_count() > 1); - auto n = src->collision_count(); - auto dst = make_collision_n(n - 1); - auto srcp = src->collisions(); - auto dstp = dst->collisions(); - try { - dstp = std::uninitialized_copy(srcp, v, dstp); - try { - std::uninitialized_copy(v + 1, srcp + n, dstp); - } catch (...) { - destroy(dst->collisions(), dstp); - throw; - } - } catch (...) { - deallocate_collision(dst, n - 1); - throw; - } - return dst; - } - - static node_t* copy_collision_replace(node_t* src, T* pos, T v) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::collision); - auto n = src->collision_count(); - auto dst = make_collision_n(n); - auto srcp = src->collisions(); - auto dstp = dst->collisions(); - assert(pos >= srcp && pos < srcp + n); - try { - new (dstp) T{std::move(v)}; - try { - dstp = std::uninitialized_copy(srcp, pos, dstp + 1); - try { - std::uninitialized_copy(pos + 1, srcp + n, dstp); - } catch (...) { - destroy(dst->collisions(), dstp); - throw; - } - } catch (...) { - dst->collisions()->~T(); - throw; - } - } catch (...) { - deallocate_collision(dst, n); - throw; - } - return dst; - } - - static node_t* - copy_inner_replace(node_t* src, count_t offset, node_t* child) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto n = popcount(src->nodemap()); - auto dst = make_inner_n(n, src->impl.d.data.inner.values); - auto srcp = src->children(); - auto dstp = dst->children(); - dst->impl.d.data.inner.datamap = src->datamap(); - dst->impl.d.data.inner.nodemap = src->nodemap(); - std::uninitialized_copy(srcp, srcp + n, dstp); - inc_nodes(srcp, n); - srcp[offset]->dec_unsafe(); - dstp[offset] = child; - return dst; - } - - static node_t* copy_inner_replace_value(node_t* src, count_t offset, T v) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - assert(offset < popcount(src->datamap())); - auto n = popcount(src->nodemap()); - auto nv = popcount(src->datamap()); - auto dst = make_inner_n(n, nv); - dst->impl.d.data.inner.datamap = src->datamap(); - dst->impl.d.data.inner.nodemap = src->nodemap(); - try { - std::uninitialized_copy( - src->values(), src->values() + nv, dst->values()); - try { - dst->values()[offset] = std::move(v); - } catch (...) { - destroy_n(dst->values(), nv); - throw; - } - } catch (...) { - deallocate_inner(dst, n, nv); - throw; - } - inc_nodes(src->children(), n); - std::uninitialized_copy( - src->children(), src->children() + n, dst->children()); - return dst; - } - - static node_t* copy_inner_replace_merged(node_t* src, - bitmap_t bit, - count_t voffset, - node_t* node) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - assert(!(src->nodemap() & bit)); - assert(src->datamap() & bit); - assert(voffset == popcount(src->datamap() & (bit - 1))); - auto n = popcount(src->nodemap()); - auto nv = popcount(src->datamap()); - auto dst = make_inner_n(n + 1, nv - 1); - auto noffset = popcount(src->nodemap() & (bit - 1)); - dst->impl.d.data.inner.datamap = src->datamap() & ~bit; - dst->impl.d.data.inner.nodemap = src->nodemap() | bit; - if (nv > 1) { - try { - std::uninitialized_copy( - src->values(), src->values() + voffset, dst->values()); - try { - std::uninitialized_copy(src->values() + voffset + 1, - src->values() + nv, - dst->values() + voffset); - } catch (...) { - destroy_n(dst->values(), voffset); - throw; - } - } catch (...) { - deallocate_inner(dst, n + 1, nv - 1); - throw; - } - } - inc_nodes(src->children(), n); - std::uninitialized_copy( - src->children(), src->children() + noffset, dst->children()); - std::uninitialized_copy(src->children() + noffset, - src->children() + n, - dst->children() + noffset + 1); - dst->children()[noffset] = node; - return dst; - } - - static node_t* copy_inner_replace_inline(node_t* src, - bitmap_t bit, - count_t noffset, - T value) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - assert(!(src->datamap() & bit)); - assert(src->nodemap() & bit); - assert(noffset == popcount(src->nodemap() & (bit - 1))); - auto n = popcount(src->nodemap()); - auto nv = popcount(src->datamap()); - auto dst = make_inner_n(n - 1, nv + 1); - auto voffset = popcount(src->datamap() & (bit - 1)); - dst->impl.d.data.inner.nodemap = src->nodemap() & ~bit; - dst->impl.d.data.inner.datamap = src->datamap() | bit; - try { - if (nv) - std::uninitialized_copy( - src->values(), src->values() + voffset, dst->values()); - try { - new (dst->values() + voffset) T{std::move(value)}; - try { - if (nv) - std::uninitialized_copy(src->values() + voffset, - src->values() + nv, - dst->values() + voffset + 1); - } catch (...) { - dst->values()[voffset].~T(); - throw; - } - } catch (...) { - destroy_n(dst->values(), voffset); - throw; - } - } catch (...) { - deallocate_inner(dst, n - 1, nv + 1); - throw; - } - inc_nodes(src->children(), n); - src->children()[noffset]->dec_unsafe(); - std::uninitialized_copy( - src->children(), src->children() + noffset, dst->children()); - std::uninitialized_copy(src->children() + noffset + 1, - src->children() + n, - dst->children() + noffset); - return dst; - } - - static node_t* - copy_inner_remove_value(node_t* src, bitmap_t bit, count_t voffset) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - assert(!(src->nodemap() & bit)); - assert(src->datamap() & bit); - assert(voffset == popcount(src->datamap() & (bit - 1))); - auto n = popcount(src->nodemap()); - auto nv = popcount(src->datamap()); - auto dst = make_inner_n(n, nv - 1); - dst->impl.d.data.inner.datamap = src->datamap() & ~bit; - dst->impl.d.data.inner.nodemap = src->nodemap(); - if (nv > 1) { - try { - std::uninitialized_copy( - src->values(), src->values() + voffset, dst->values()); - try { - std::uninitialized_copy(src->values() + voffset + 1, - src->values() + nv, - dst->values() + voffset); - } catch (...) { - destroy_n(dst->values(), voffset); - throw; - } - } catch (...) { - deallocate_inner(dst, n, nv - 1); - throw; - } - } - inc_nodes(src->children(), n); - std::uninitialized_copy( - src->children(), src->children() + n, dst->children()); - return dst; - } - - static node_t* copy_inner_insert_value(node_t* src, bitmap_t bit, T v) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto n = popcount(src->nodemap()); - auto nv = popcount(src->datamap()); - auto offset = popcount(src->datamap() & (bit - 1)); - auto dst = make_inner_n(n, nv + 1); - dst->impl.d.data.inner.datamap = src->datamap() | bit; - dst->impl.d.data.inner.nodemap = src->nodemap(); - try { - if (nv) - std::uninitialized_copy( - src->values(), src->values() + offset, dst->values()); - try { - new (dst->values() + offset) T{std::move(v)}; - try { - if (nv) - std::uninitialized_copy(src->values() + offset, - src->values() + nv, - dst->values() + offset + 1); - } catch (...) { - dst->values()[offset].~T(); - throw; - } - } catch (...) { - destroy_n(dst->values(), offset); - throw; - } - } catch (...) { - deallocate_inner(dst, n, nv + 1); - throw; - } - inc_nodes(src->children(), n); - std::uninitialized_copy( - src->children(), src->children() + n, dst->children()); - return dst; - } - - static node_t* - make_merged(shift_t shift, T v1, hash_t hash1, T v2, hash_t hash2) - { - if (shift < max_shift<B>) { - auto idx1 = hash1 & (mask<B> << shift); - auto idx2 = hash2 & (mask<B> << shift); - if (idx1 == idx2) { - auto merged = make_merged( - shift + B, std::move(v1), hash1, std::move(v2), hash2); - try { - return make_inner_n(1, idx1 >> shift, merged); - } catch (...) { - delete_deep_shift(merged, shift + B); - throw; - } - } else { - return make_inner_n(0, - idx1 >> shift, - std::move(v1), - idx2 >> shift, - std::move(v2)); - } - } else { - return make_collision(std::move(v1), std::move(v2)); - } - } - - node_t* inc() - { - refs(this).inc(); - return this; - } - - const node_t* inc() const - { - refs(this).inc(); - return this; - } - - bool dec() const { return refs(this).dec(); } - void dec_unsafe() const { refs(this).dec_unsafe(); } - - static void inc_nodes(node_t** p, count_t n) - { - for (auto i = p, e = i + n; i != e; ++i) - refs(*i).inc(); - } - - static void delete_values(values_t* p, count_t n) - { - assert(p); - deallocate_values(p, n); - } - - static void delete_inner(node_t* p) - { - assert(p); - IMMER_ASSERT_TAGGED(p->kind() == kind_t::inner); - auto vp = p->impl.d.data.inner.values; - if (vp && refs(vp).dec()) - delete_values(vp, popcount(p->datamap())); - deallocate_inner(p, popcount(p->nodemap())); - } - - static void delete_collision(node_t* p) - { - assert(p); - IMMER_ASSERT_TAGGED(p->kind() == kind_t::collision); - auto n = p->collision_count(); - deallocate_collision(p, n); - } - - static void delete_deep(node_t* p, shift_t s) - { - if (s == max_depth<B>) - delete_collision(p); - else { - auto fst = p->children(); - auto lst = fst + popcount(p->nodemap()); - for (; fst != lst; ++fst) - if ((*fst)->dec()) - delete_deep(*fst, s + 1); - delete_inner(p); - } - } - - static void delete_deep_shift(node_t* p, shift_t s) - { - if (s == max_shift<B>) - delete_collision(p); - else { - auto fst = p->children(); - auto lst = fst + popcount(p->nodemap()); - for (; fst != lst; ++fst) - if ((*fst)->dec()) - delete_deep_shift(*fst, s + B); - delete_inner(p); - } - } - - static void deallocate_values(values_t* p, count_t n) - { - destroy_n((T*) &p->d.buffer, n); - heap::deallocate(node_t::sizeof_values_n(n), p); - } - - static void deallocate_collision(node_t* p, count_t n) - { - destroy_n(p->collisions(), n); - heap::deallocate(node_t::sizeof_collision_n(n), p); - } - - static void deallocate_inner(node_t* p, count_t n) - { - heap::deallocate(node_t::sizeof_inner_n(n), p); - } - - static void deallocate_inner(node_t* p, count_t n, count_t nv) - { - assert(nv); - heap::deallocate(node_t::sizeof_values_n(nv), - p->impl.d.data.inner.values); - heap::deallocate(node_t::sizeof_inner_n(n), p); - } -}; - -} // namespace hamts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/iterator_facade.hpp b/third_party/immer/immer/detail/iterator_facade.hpp deleted file mode 100644 index ffc237943e09..000000000000 --- a/third_party/immer/immer/detail/iterator_facade.hpp +++ /dev/null @@ -1,212 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <cstddef> -#include <iterator> -#include <type_traits> - -namespace immer { -namespace detail { - -struct iterator_core_access -{ - template <typename T> - static decltype(auto) dereference(T&& x) - { - return x.dereference(); - } - - template <typename T> - static decltype(auto) increment(T&& x) - { - return x.increment(); - } - - template <typename T> - static decltype(auto) decrement(T&& x) - { - return x.decrement(); - } - - template <typename T1, typename T2> - static decltype(auto) equal(T1&& x1, T2&& x2) - { - return x1.equal(x2); - } - - template <typename T, typename D> - static decltype(auto) advance(T&& x, D d) - { - return x.advance(d); - } - - template <typename T1, typename T2> - static decltype(auto) distance_to(T1&& x1, T2&& x2) - { - return x1.distance_to(x2); - } -}; - -/*! - * Minimalistic reimplementation of boost::iterator_facade - */ -template <typename DerivedT, - typename IteratorCategoryT, - typename T, - typename ReferenceT = T&, - typename DifferenceTypeT = std::ptrdiff_t, - typename PointerT = T*> -class iterator_facade -{ -public: - using iterator_category = IteratorCategoryT; - using value_type = T; - using difference_type = DifferenceTypeT; - using pointer = PointerT; - using reference = ReferenceT; - -protected: - using access_t = iterator_core_access; - - constexpr static auto is_random_access = - std::is_base_of<std::random_access_iterator_tag, - IteratorCategoryT>::value; - constexpr static auto is_bidirectional = - std::is_base_of<std::bidirectional_iterator_tag, - IteratorCategoryT>::value; - - class reference_proxy - { - friend iterator_facade; - DerivedT iter_; - - reference_proxy(DerivedT iter) - : iter_{std::move(iter)} - {} - - public: - operator ReferenceT() const { return *iter_; } - }; - - const DerivedT& derived() const - { - static_assert(std::is_base_of<iterator_facade, DerivedT>::value, - "must pass a derived thing"); - return *static_cast<const DerivedT*>(this); - } - DerivedT& derived() - { - static_assert(std::is_base_of<iterator_facade, DerivedT>::value, - "must pass a derived thing"); - return *static_cast<DerivedT*>(this); - } - -public: - ReferenceT operator*() const { return access_t::dereference(derived()); } - PointerT operator->() const { return &access_t::dereference(derived()); } - reference_proxy operator[](DifferenceTypeT n) const - { - static_assert(is_random_access, ""); - return derived() + n; - } - - bool operator==(const DerivedT& rhs) const - { - return access_t::equal(derived(), rhs); - } - bool operator!=(const DerivedT& rhs) const - { - return !access_t::equal(derived(), rhs); - } - - DerivedT& operator++() - { - access_t::increment(derived()); - return derived(); - } - DerivedT operator++(int) - { - auto tmp = derived(); - access_t::increment(derived()); - return tmp; - } - - DerivedT& operator--() - { - static_assert(is_bidirectional || is_random_access, ""); - access_t::decrement(derived()); - return derived(); - } - DerivedT operator--(int) - { - static_assert(is_bidirectional || is_random_access, ""); - auto tmp = derived(); - access_t::decrement(derived()); - return tmp; - } - - DerivedT& operator+=(DifferenceTypeT n) - { - access_t::advance(derived(), n); - return derived(); - } - DerivedT& operator-=(DifferenceTypeT n) - { - access_t::advance(derived(), -n); - return derived(); - } - - DerivedT operator+(DifferenceTypeT n) const - { - static_assert(is_random_access, ""); - auto tmp = derived(); - return tmp += n; - } - friend DerivedT operator+(DifferenceTypeT n, const DerivedT& i) - { - static_assert(is_random_access, ""); - return i + n; - } - DerivedT operator-(DifferenceTypeT n) const - { - static_assert(is_random_access, ""); - auto tmp = derived(); - return tmp -= n; - } - DifferenceTypeT operator-(const DerivedT& rhs) const - { - static_assert(is_random_access, ""); - return access_t::distance_to(rhs, derived()); - } - - bool operator<(const DerivedT& rhs) const - { - static_assert(is_random_access, ""); - return access_t::distance_to(derived(), rhs) > 0; - } - bool operator<=(const DerivedT& rhs) const - { - static_assert(is_random_access, ""); - return access_t::distance_to(derived(), rhs) >= 0; - } - bool operator>(const DerivedT& rhs) const - { - static_assert(is_random_access, ""); - return access_t::distance_to(derived(), rhs) < 0; - } - bool operator>=(const DerivedT& rhs) const - { - static_assert(is_random_access, ""); - return access_t::distance_to(derived(), rhs) <= 0; - } -}; - -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/rbts/bits.hpp b/third_party/immer/immer/detail/rbts/bits.hpp deleted file mode 100644 index 58d4e3c9c93a..000000000000 --- a/third_party/immer/immer/detail/rbts/bits.hpp +++ /dev/null @@ -1,33 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <cstdint> - -namespace immer { -namespace detail { -namespace rbts { - -using bits_t = std::uint32_t; -using shift_t = std::uint32_t; -using count_t = std::uint32_t; -using size_t = std::size_t; - -template <bits_t B, typename T = count_t> -constexpr T branches = T{1} << B; - -template <bits_t B, typename T = size_t> -constexpr T mask = branches<B, T> - 1; - -template <bits_t B, bits_t BL> -constexpr shift_t endshift = shift_t{BL} - shift_t{B}; - -} // namespace rbts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/rbts/node.hpp b/third_party/immer/immer/detail/rbts/node.hpp deleted file mode 100644 index e54e569636ac..000000000000 --- a/third_party/immer/immer/detail/rbts/node.hpp +++ /dev/null @@ -1,932 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/combine_standard_layout.hpp> -#include <immer/detail/rbts/bits.hpp> -#include <immer/detail/util.hpp> -#include <immer/heap/tags.hpp> - -#include <cassert> -#include <cstddef> -#include <memory> -#include <type_traits> - -namespace immer { -namespace detail { -namespace rbts { - -template <typename T, typename MemoryPolicy, bits_t B, bits_t BL> -struct node -{ - static constexpr auto bits = B; - static constexpr auto bits_leaf = BL; - - using node_t = node; - using memory = MemoryPolicy; - using heap_policy = typename memory::heap; - using transience = typename memory::transience_t; - using refs_t = typename memory::refcount; - using ownee_t = typename transience::ownee; - using edit_t = typename transience::edit; - using value_t = T; - - static constexpr bool embed_relaxed = memory::prefer_fewer_bigger_objects; - - enum class kind_t - { - leaf, - inner - }; - - struct relaxed_data_t - { - count_t count; - size_t sizes[branches<B>]; - }; - - using relaxed_data_with_meta_t = - combine_standard_layout_t<relaxed_data_t, refs_t, ownee_t>; - - using relaxed_data_no_meta_t = combine_standard_layout_t<relaxed_data_t>; - - using relaxed_t = std::conditional_t<embed_relaxed, - relaxed_data_no_meta_t, - relaxed_data_with_meta_t>; - - struct leaf_t - { - aligned_storage_for<T> buffer; - }; - - struct inner_t - { - relaxed_t* relaxed; - aligned_storage_for<node_t*> buffer; - }; - - union data_t - { - inner_t inner; - leaf_t leaf; - }; - - struct impl_data_t - { -#if IMMER_TAGGED_NODE - kind_t kind; -#endif - data_t data; - }; - - using impl_t = combine_standard_layout_t<impl_data_t, refs_t, ownee_t>; - - impl_t impl; - - // assume that we need to keep headroom space in the node when we - // are doing reference counting, since any node may become - // transient when it has only one reference - constexpr static bool keep_headroom = !std::is_empty<refs_t>{}; - - constexpr static std::size_t sizeof_packed_leaf_n(count_t count) - { - return immer_offsetof(impl_t, d.data.leaf.buffer) + - sizeof(leaf_t::buffer) * count; - } - - constexpr static std::size_t sizeof_packed_inner_n(count_t count) - { - return immer_offsetof(impl_t, d.data.inner.buffer) + - sizeof(inner_t::buffer) * count; - } - - constexpr static std::size_t sizeof_packed_relaxed_n(count_t count) - { - return immer_offsetof(relaxed_t, d.sizes) + sizeof(size_t) * count; - } - - constexpr static std::size_t sizeof_packed_inner_r_n(count_t count) - { - return embed_relaxed ? sizeof_packed_inner_n(count) + - sizeof_packed_relaxed_n(count) - : sizeof_packed_inner_n(count); - } - - constexpr static std::size_t max_sizeof_leaf = - sizeof_packed_leaf_n(branches<BL>); - - constexpr static std::size_t max_sizeof_inner = - sizeof_packed_inner_n(branches<B>); - - constexpr static std::size_t max_sizeof_relaxed = - sizeof_packed_relaxed_n(branches<B>); - - constexpr static std::size_t max_sizeof_inner_r = - sizeof_packed_inner_r_n(branches<B>); - - constexpr static std::size_t sizeof_inner_n(count_t n) - { - return keep_headroom ? max_sizeof_inner : sizeof_packed_inner_n(n); - } - - constexpr static std::size_t sizeof_inner_r_n(count_t n) - { - return keep_headroom ? max_sizeof_inner_r : sizeof_packed_inner_r_n(n); - } - - constexpr static std::size_t sizeof_relaxed_n(count_t n) - { - return keep_headroom ? max_sizeof_relaxed : sizeof_packed_relaxed_n(n); - } - - constexpr static std::size_t sizeof_leaf_n(count_t n) - { - return keep_headroom ? max_sizeof_leaf : sizeof_packed_leaf_n(n); - } - - using heap = - typename heap_policy::template optimized<max_sizeof_inner>::type; - -#if IMMER_TAGGED_NODE - kind_t kind() const { return impl.d.kind; } -#endif - - relaxed_t* relaxed() - { - IMMER_ASSERT_TAGGED(kind() == kind_t::inner); - return impl.d.data.inner.relaxed; - } - - const relaxed_t* relaxed() const - { - IMMER_ASSERT_TAGGED(kind() == kind_t::inner); - return impl.d.data.inner.relaxed; - } - - node_t** inner() - { - IMMER_ASSERT_TAGGED(kind() == kind_t::inner); - return reinterpret_cast<node_t**>(&impl.d.data.inner.buffer); - } - - T* leaf() - { - IMMER_ASSERT_TAGGED(kind() == kind_t::leaf); - return reinterpret_cast<T*>(&impl.d.data.leaf.buffer); - } - - static refs_t& refs(const relaxed_t* x) - { - return auto_const_cast(get<refs_t>(*x)); - } - static const ownee_t& ownee(const relaxed_t* x) { return get<ownee_t>(*x); } - static ownee_t& ownee(relaxed_t* x) { return get<ownee_t>(*x); } - - static refs_t& refs(const node_t* x) - { - return auto_const_cast(get<refs_t>(x->impl)); - } - static const ownee_t& ownee(const node_t* x) - { - return get<ownee_t>(x->impl); - } - static ownee_t& ownee(node_t* x) { return get<ownee_t>(x->impl); } - - static node_t* make_inner_n(count_t n) - { - assert(n <= branches<B>); - auto m = heap::allocate(sizeof_inner_n(n)); - auto p = new (m) node_t; - p->impl.d.data.inner.relaxed = nullptr; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::inner; -#endif - return p; - } - - static node_t* make_inner_e(edit_t e) - { - auto m = heap::allocate(max_sizeof_inner); - auto p = new (m) node_t; - ownee(p) = e; - p->impl.d.data.inner.relaxed = nullptr; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::inner; -#endif - return p; - } - - static node_t* make_inner_r_n(count_t n) - { - assert(n <= branches<B>); - auto mp = heap::allocate(sizeof_inner_r_n(n)); - auto mr = static_cast<void*>(nullptr); - if (embed_relaxed) { - mr = reinterpret_cast<unsigned char*>(mp) + sizeof_inner_n(n); - } else { - try { - mr = heap::allocate(sizeof_relaxed_n(n), norefs_tag{}); - } catch (...) { - heap::deallocate(sizeof_inner_r_n(n), mp); - throw; - } - } - auto p = new (mp) node_t; - auto r = new (mr) relaxed_t; - r->d.count = 0; - p->impl.d.data.inner.relaxed = r; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::inner; -#endif - return p; - } - - static node_t* make_inner_sr_n(count_t n, relaxed_t* r) - { - return static_if<embed_relaxed, node_t*>( - [&](auto) { return node_t::make_inner_r_n(n); }, - [&](auto) { - auto p = - new (heap::allocate(node_t::sizeof_inner_r_n(n))) node_t; - assert(r->d.count >= n); - node_t::refs(r).inc(); - p->impl.d.data.inner.relaxed = r; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::inner; -#endif - return p; - }); - } - - static node_t* make_inner_r_e(edit_t e) - { - auto mp = heap::allocate(max_sizeof_inner_r); - auto mr = static_cast<void*>(nullptr); - if (embed_relaxed) { - mr = reinterpret_cast<unsigned char*>(mp) + max_sizeof_inner; - } else { - try { - mr = heap::allocate(max_sizeof_relaxed, norefs_tag{}); - } catch (...) { - heap::deallocate(max_sizeof_inner_r, mp); - throw; - } - } - auto p = new (mp) node_t; - auto r = new (mr) relaxed_t; - ownee(p) = e; - static_if<!embed_relaxed>([&](auto) { node_t::ownee(r) = e; }); - r->d.count = 0; - p->impl.d.data.inner.relaxed = r; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::inner; -#endif - return p; - } - - static node_t* make_inner_sr_e(edit_t e, relaxed_t* r) - { - return static_if<embed_relaxed, node_t*>( - [&](auto) { return node_t::make_inner_r_e(e); }, - [&](auto) { - auto p = - new (heap::allocate(node_t::max_sizeof_inner_r)) node_t; - node_t::refs(r).inc(); - p->impl.d.data.inner.relaxed = r; - node_t::ownee(p) = e; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::inner; -#endif - return p; - }); - } - - static node_t* make_leaf_n(count_t n) - { - assert(n <= branches<BL>); - auto p = new (heap::allocate(sizeof_leaf_n(n))) node_t; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::leaf; -#endif - return p; - } - - static node_t* make_leaf_e(edit_t e) - { - auto p = new (heap::allocate(max_sizeof_leaf)) node_t; - ownee(p) = e; -#if IMMER_TAGGED_NODE - p->impl.d.kind = node_t::kind_t::leaf; -#endif - return p; - } - - static node_t* make_inner_n(count_t n, node_t* x) - { - assert(n >= 1); - auto p = make_inner_n(n); - p->inner()[0] = x; - return p; - } - - static node_t* make_inner_n(edit_t n, node_t* x) - { - assert(n >= 1); - auto p = make_inner_n(n); - p->inner()[0] = x; - return p; - } - - static node_t* make_inner_n(count_t n, node_t* x, node_t* y) - { - assert(n >= 2); - auto p = make_inner_n(n); - p->inner()[0] = x; - p->inner()[1] = y; - return p; - } - - static node_t* make_inner_r_n(count_t n, node_t* x) - { - assert(n >= 1); - auto p = make_inner_r_n(n); - auto r = p->relaxed(); - p->inner()[0] = x; - r->d.count = 1; - return p; - } - - static node_t* make_inner_r_n(count_t n, node_t* x, size_t xs) - { - assert(n >= 1); - auto p = make_inner_r_n(n); - auto r = p->relaxed(); - p->inner()[0] = x; - r->d.sizes[0] = xs; - r->d.count = 1; - return p; - } - - static node_t* make_inner_r_n(count_t n, node_t* x, node_t* y) - { - assert(n >= 2); - auto p = make_inner_r_n(n); - auto r = p->relaxed(); - p->inner()[0] = x; - p->inner()[1] = y; - r->d.count = 2; - return p; - } - - static node_t* make_inner_r_n(count_t n, node_t* x, size_t xs, node_t* y) - { - assert(n >= 2); - auto p = make_inner_r_n(n); - auto r = p->relaxed(); - p->inner()[0] = x; - p->inner()[1] = y; - r->d.sizes[0] = xs; - r->d.count = 2; - return p; - } - - static node_t* - make_inner_r_n(count_t n, node_t* x, size_t xs, node_t* y, size_t ys) - { - assert(n >= 2); - auto p = make_inner_r_n(n); - auto r = p->relaxed(); - p->inner()[0] = x; - p->inner()[1] = y; - r->d.sizes[0] = xs; - r->d.sizes[1] = xs + ys; - r->d.count = 2; - return p; - } - - static node_t* make_inner_r_n(count_t n, - node_t* x, - size_t xs, - node_t* y, - size_t ys, - node_t* z, - size_t zs) - { - assert(n >= 3); - auto p = make_inner_r_n(n); - auto r = p->relaxed(); - p->inner()[0] = x; - p->inner()[1] = y; - p->inner()[2] = z; - r->d.sizes[0] = xs; - r->d.sizes[1] = xs + ys; - r->d.sizes[2] = xs + ys + zs; - r->d.count = 3; - return p; - } - - template <typename U> - static node_t* make_leaf_n(count_t n, U&& x) - { - assert(n >= 1); - auto p = make_leaf_n(n); - try { - new (p->leaf()) T{std::forward<U>(x)}; - } catch (...) { - heap::deallocate(node_t::sizeof_leaf_n(n), p); - throw; - } - return p; - } - - template <typename U> - static node_t* make_leaf_e(edit_t e, U&& x) - { - auto p = make_leaf_e(e); - try { - new (p->leaf()) T{std::forward<U>(x)}; - } catch (...) { - heap::deallocate(node_t::max_sizeof_leaf, p); - throw; - } - return p; - } - - static node_t* make_path(shift_t shift, node_t* node) - { - IMMER_ASSERT_TAGGED(node->kind() == kind_t::leaf); - if (shift == endshift<B, BL>) - return node; - else { - auto n = node_t::make_inner_n(1); - try { - n->inner()[0] = make_path(shift - B, node); - } catch (...) { - heap::deallocate(node_t::sizeof_inner_n(1), n); - throw; - } - return n; - } - } - - static node_t* make_path_e(edit_t e, shift_t shift, node_t* node) - { - IMMER_ASSERT_TAGGED(node->kind() == kind_t::leaf); - if (shift == endshift<B, BL>) - return node; - else { - auto n = node_t::make_inner_e(e); - try { - n->inner()[0] = make_path_e(e, shift - B, node); - } catch (...) { - heap::deallocate(node_t::max_sizeof_inner, n); - throw; - } - return n; - } - } - - static node_t* copy_inner(node_t* src, count_t n) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto dst = make_inner_n(n); - inc_nodes(src->inner(), n); - std::uninitialized_copy(src->inner(), src->inner() + n, dst->inner()); - return dst; - } - - static node_t* copy_inner_n(count_t allocn, node_t* src, count_t n) - { - assert(allocn >= n); - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto dst = make_inner_n(allocn); - return do_copy_inner(dst, src, n); - } - - static node_t* copy_inner_e(edit_t e, node_t* src, count_t n) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto dst = make_inner_e(e); - return do_copy_inner(dst, src, n); - } - - static node_t* do_copy_inner(node_t* dst, node_t* src, count_t n) - { - IMMER_ASSERT_TAGGED(dst->kind() == kind_t::inner); - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto p = src->inner(); - inc_nodes(p, n); - std::uninitialized_copy(p, p + n, dst->inner()); - return dst; - } - - static node_t* copy_inner_r(node_t* src, count_t n) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto dst = make_inner_r_n(n); - return do_copy_inner_r(dst, src, n); - } - - static node_t* copy_inner_r_n(count_t allocn, node_t* src, count_t n) - { - assert(allocn >= n); - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto dst = make_inner_r_n(allocn); - return do_copy_inner_r(dst, src, n); - } - - static node_t* copy_inner_r_e(edit_t e, node_t* src, count_t n) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto dst = make_inner_r_e(e); - return do_copy_inner_r(dst, src, n); - } - - static node_t* copy_inner_sr_e(edit_t e, node_t* src, count_t n) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto dst = make_inner_sr_e(e, src->relaxed()); - return do_copy_inner_sr(dst, src, n); - } - - static node_t* do_copy_inner_r(node_t* dst, node_t* src, count_t n) - { - IMMER_ASSERT_TAGGED(dst->kind() == kind_t::inner); - IMMER_ASSERT_TAGGED(src->kind() == kind_t::inner); - auto src_r = src->relaxed(); - auto dst_r = dst->relaxed(); - inc_nodes(src->inner(), n); - std::copy(src->inner(), src->inner() + n, dst->inner()); - std::copy(src_r->d.sizes, src_r->d.sizes + n, dst_r->d.sizes); - dst_r->d.count = n; - return dst; - } - - static node_t* do_copy_inner_sr(node_t* dst, node_t* src, count_t n) - { - if (embed_relaxed) - return do_copy_inner_r(dst, src, n); - else { - inc_nodes(src->inner(), n); - std::copy(src->inner(), src->inner() + n, dst->inner()); - return dst; - } - } - - static node_t* copy_leaf(node_t* src, count_t n) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::leaf); - auto dst = make_leaf_n(n); - try { - std::uninitialized_copy(src->leaf(), src->leaf() + n, dst->leaf()); - } catch (...) { - heap::deallocate(node_t::sizeof_leaf_n(n), dst); - throw; - } - return dst; - } - - static node_t* copy_leaf_e(edit_t e, node_t* src, count_t n) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::leaf); - auto dst = make_leaf_e(e); - try { - std::uninitialized_copy(src->leaf(), src->leaf() + n, dst->leaf()); - } catch (...) { - heap::deallocate(node_t::max_sizeof_leaf, dst); - throw; - } - return dst; - } - - static node_t* copy_leaf_n(count_t allocn, node_t* src, count_t n) - { - assert(allocn >= n); - IMMER_ASSERT_TAGGED(src->kind() == kind_t::leaf); - auto dst = make_leaf_n(allocn); - try { - std::uninitialized_copy(src->leaf(), src->leaf() + n, dst->leaf()); - } catch (...) { - heap::deallocate(node_t::sizeof_leaf_n(allocn), dst); - throw; - } - return dst; - } - - static node_t* copy_leaf(node_t* src1, count_t n1, node_t* src2, count_t n2) - { - IMMER_ASSERT_TAGGED(src1->kind() == kind_t::leaf); - IMMER_ASSERT_TAGGED(src2->kind() == kind_t::leaf); - auto dst = make_leaf_n(n1 + n2); - try { - std::uninitialized_copy( - src1->leaf(), src1->leaf() + n1, dst->leaf()); - } catch (...) { - heap::deallocate(node_t::sizeof_leaf_n(n1 + n2), dst); - throw; - } - try { - std::uninitialized_copy( - src2->leaf(), src2->leaf() + n2, dst->leaf() + n1); - } catch (...) { - destroy_n(dst->leaf(), n1); - heap::deallocate(node_t::sizeof_leaf_n(n1 + n2), dst); - throw; - } - return dst; - } - - static node_t* - copy_leaf_e(edit_t e, node_t* src1, count_t n1, node_t* src2, count_t n2) - { - IMMER_ASSERT_TAGGED(src1->kind() == kind_t::leaf); - IMMER_ASSERT_TAGGED(src2->kind() == kind_t::leaf); - auto dst = make_leaf_e(e); - try { - std::uninitialized_copy( - src1->leaf(), src1->leaf() + n1, dst->leaf()); - } catch (...) { - heap::deallocate(max_sizeof_leaf, dst); - throw; - } - try { - std::uninitialized_copy( - src2->leaf(), src2->leaf() + n2, dst->leaf() + n1); - } catch (...) { - destroy_n(dst->leaf(), n1); - heap::deallocate(max_sizeof_leaf, dst); - throw; - } - return dst; - } - - static node_t* copy_leaf_e(edit_t e, node_t* src, count_t idx, count_t last) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::leaf); - auto dst = make_leaf_e(e); - try { - std::uninitialized_copy( - src->leaf() + idx, src->leaf() + last, dst->leaf()); - } catch (...) { - heap::deallocate(max_sizeof_leaf, dst); - throw; - } - return dst; - } - - static node_t* copy_leaf(node_t* src, count_t idx, count_t last) - { - IMMER_ASSERT_TAGGED(src->kind() == kind_t::leaf); - auto dst = make_leaf_n(last - idx); - try { - std::uninitialized_copy( - src->leaf() + idx, src->leaf() + last, dst->leaf()); - } catch (...) { - heap::deallocate(node_t::sizeof_leaf_n(last - idx), dst); - throw; - } - return dst; - } - - template <typename U> - static node_t* copy_leaf_emplace(node_t* src, count_t n, U&& x) - { - auto dst = copy_leaf_n(n + 1, src, n); - try { - new (dst->leaf() + n) T{std::forward<U>(x)}; - } catch (...) { - destroy_n(dst->leaf(), n); - heap::deallocate(node_t::sizeof_leaf_n(n + 1), dst); - throw; - } - return dst; - } - - static void delete_inner(node_t* p, count_t n) - { - IMMER_ASSERT_TAGGED(p->kind() == kind_t::inner); - assert(!p->relaxed()); - heap::deallocate(ownee(p).owned() ? node_t::max_sizeof_inner - : node_t::sizeof_inner_n(n), - p); - } - - static void delete_inner_e(node_t* p) - { - IMMER_ASSERT_TAGGED(p->kind() == kind_t::inner); - assert(!p->relaxed()); - heap::deallocate(node_t::max_sizeof_inner, p); - } - - static void delete_inner_any(node_t* p, count_t n) - { - if (p->relaxed()) - delete_inner_r(p, n); - else - delete_inner(p, n); - } - - static void delete_inner_r(node_t* p, count_t n) - { - IMMER_ASSERT_TAGGED(p->kind() == kind_t::inner); - auto r = p->relaxed(); - assert(r); - static_if<!embed_relaxed>([&](auto) { - if (node_t::refs(r).dec()) - heap::deallocate(node_t::ownee(r).owned() - ? node_t::max_sizeof_relaxed - : node_t::sizeof_relaxed_n(n), - r); - }); - heap::deallocate(ownee(p).owned() ? node_t::max_sizeof_inner_r - : node_t::sizeof_inner_r_n(n), - p); - } - - static void delete_inner_r_e(node_t* p) - { - IMMER_ASSERT_TAGGED(p->kind() == kind_t::inner); - auto r = p->relaxed(); - assert(r); - static_if<!embed_relaxed>([&](auto) { - if (node_t::refs(r).dec()) - heap::deallocate(node_t::max_sizeof_relaxed, r); - }); - heap::deallocate(node_t::max_sizeof_inner_r, p); - } - - static void delete_leaf(node_t* p, count_t n) - { - IMMER_ASSERT_TAGGED(p->kind() == kind_t::leaf); - destroy_n(p->leaf(), n); - heap::deallocate(ownee(p).owned() ? node_t::max_sizeof_leaf - : node_t::sizeof_leaf_n(n), - p); - } - - bool can_mutate(edit_t e) const - { - return refs(this).unique() || ownee(this).can_mutate(e); - } - - bool can_relax() const { return !embed_relaxed || relaxed(); } - - relaxed_t* ensure_mutable_relaxed(edit_t e) - { - auto src_r = relaxed(); - return static_if<embed_relaxed, relaxed_t*>( - [&](auto) { return src_r; }, - [&](auto) { - if (node_t::refs(src_r).unique() || - node_t::ownee(src_r).can_mutate(e)) - return src_r; - else { - if (src_r) - node_t::refs(src_r).dec_unsafe(); - auto dst_r = impl.d.data.inner.relaxed = - new (heap::allocate(max_sizeof_relaxed)) relaxed_t; - node_t::ownee(dst_r) = e; - return dst_r; - } - }); - } - - relaxed_t* ensure_mutable_relaxed_e(edit_t e, edit_t ec) - { - auto src_r = relaxed(); - return static_if<embed_relaxed, relaxed_t*>( - [&](auto) { return src_r; }, - [&](auto) { - if (src_r && (node_t::refs(src_r).unique() || - node_t::ownee(src_r).can_mutate(e))) { - node_t::ownee(src_r) = ec; - return src_r; - } else { - if (src_r) - node_t::refs(src_r).dec_unsafe(); - auto dst_r = impl.d.data.inner.relaxed = - new (heap::allocate(max_sizeof_relaxed)) relaxed_t; - node_t::ownee(dst_r) = ec; - return dst_r; - } - }); - } - - relaxed_t* ensure_mutable_relaxed_n(edit_t e, count_t n) - { - auto src_r = relaxed(); - return static_if<embed_relaxed, relaxed_t*>( - [&](auto) { return src_r; }, - [&](auto) { - if (node_t::refs(src_r).unique() || - node_t::ownee(src_r).can_mutate(e)) - return src_r; - else { - if (src_r) - node_t::refs(src_r).dec_unsafe(); - auto dst_r = - new (heap::allocate(max_sizeof_relaxed)) relaxed_t; - std::copy( - src_r->d.sizes, src_r->d.sizes + n, dst_r->d.sizes); - node_t::ownee(dst_r) = e; - return impl.d.data.inner.relaxed = dst_r; - } - }); - } - - node_t* inc() - { - refs(this).inc(); - return this; - } - - const node_t* inc() const - { - refs(this).inc(); - return this; - } - - bool dec() const { return refs(this).dec(); } - void dec_unsafe() const { refs(this).dec_unsafe(); } - - static void inc_nodes(node_t** p, count_t n) - { - for (auto i = p, e = i + n; i != e; ++i) - refs(*i).inc(); - } - -#if IMMER_TAGGED_NODE - shift_t compute_shift() - { - if (kind() == kind_t::leaf) - return endshift<B, BL>; - else - return B + inner()[0]->compute_shift(); - } -#endif - - bool check(shift_t shift, size_t size) - { -#if IMMER_DEBUG_DEEP_CHECK - assert(size > 0); - if (shift == endshift<B, BL>) { - IMMER_ASSERT_TAGGED(kind() == kind_t::leaf); - assert(size <= branches<BL>); - } else if (auto r = relaxed()) { - auto count = r->d.count; - assert(count > 0); - assert(count <= branches<B>); - if (r->d.sizes[count - 1] != size) { - IMMER_TRACE_F("check"); - IMMER_TRACE_E(r->d.sizes[count - 1]); - IMMER_TRACE_E(size); - } - assert(r->d.sizes[count - 1] == size); - for (auto i = 1; i < count; ++i) - assert(r->d.sizes[i - 1] < r->d.sizes[i]); - auto last_size = size_t{}; - for (auto i = 0; i < count; ++i) { - assert(inner()[i]->check(shift - B, r->d.sizes[i] - last_size)); - last_size = r->d.sizes[i]; - } - } else { - assert(size <= branches<B> << shift); - auto count = - (size >> shift) + (size - ((size >> shift) << shift) > 0); - assert(count <= branches<B>); - if (count) { - for (auto i = 1; i < count - 1; ++i) - assert(inner()[i]->check(shift - B, 1 << shift)); - assert(inner()[count - 1]->check( - shift - B, size - ((count - 1) << shift))); - } - } -#endif // IMMER_DEBUG_DEEP_CHECK - return true; - } -}; - -template <typename T, typename MP, bits_t B> -constexpr bits_t derive_bits_leaf_aux() -{ - using node_t = node<T, MP, B, B>; - constexpr auto sizeof_elem = sizeof(T); - constexpr auto space = - node_t::max_sizeof_inner - node_t::sizeof_packed_leaf_n(0); - constexpr auto full_elems = space / sizeof_elem; - constexpr auto BL = log2(full_elems); - return BL; -} - -template <typename T, typename MP, bits_t B> -constexpr bits_t derive_bits_leaf = derive_bits_leaf_aux<T, MP, B>(); - -} // namespace rbts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/rbts/operations.hpp b/third_party/immer/immer/detail/rbts/operations.hpp deleted file mode 100644 index ff703e892b42..000000000000 --- a/third_party/immer/immer/detail/rbts/operations.hpp +++ /dev/null @@ -1,2461 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <algorithm> -#include <memory> -#include <numeric> -#include <utility> - -#include <immer/config.hpp> -#include <immer/detail/rbts/position.hpp> -#include <immer/detail/rbts/visitor.hpp> -#include <immer/detail/util.hpp> -#include <immer/heap/tags.hpp> - -namespace immer { -namespace detail { -namespace rbts { - -template <typename T> -struct array_for_visitor : visitor_base<array_for_visitor<T>> -{ - using this_t = array_for_visitor; - - template <typename PosT> - static T* visit_inner(PosT&& pos, size_t idx) - { - return pos.descend(this_t{}, idx); - } - - template <typename PosT> - static T* visit_leaf(PosT&& pos, size_t) - { - return pos.node()->leaf(); - } -}; - -template <typename T> -struct region_for_visitor : visitor_base<region_for_visitor<T>> -{ - using this_t = region_for_visitor; - using result_t = std::tuple<T*, size_t, size_t>; - - template <typename PosT> - static result_t visit_inner(PosT&& pos, size_t idx) - { - return pos.towards(this_t{}, idx); - } - - template <typename PosT> - static result_t visit_leaf(PosT&& pos, size_t idx) - { - return std::make_tuple(pos.node()->leaf(), pos.index(idx), pos.count()); - } -}; - -template <typename T> -struct get_visitor : visitor_base<get_visitor<T>> -{ - using this_t = get_visitor; - - template <typename PosT> - static const T& visit_inner(PosT&& pos, size_t idx) - { - return pos.descend(this_t{}, idx); - } - - template <typename PosT> - static const T& visit_leaf(PosT&& pos, size_t idx) - { - return pos.node()->leaf()[pos.index(idx)]; - } -}; - -struct for_each_chunk_visitor : visitor_base<for_each_chunk_visitor> -{ - using this_t = for_each_chunk_visitor; - - template <typename Pos, typename Fn> - static void visit_inner(Pos&& pos, Fn&& fn) - { - pos.each(this_t{}, fn); - } - - template <typename Pos, typename Fn> - static void visit_leaf(Pos&& pos, Fn&& fn) - { - auto data = pos.node()->leaf(); - fn(data, data + pos.count()); - } -}; - -struct for_each_chunk_p_visitor : visitor_base<for_each_chunk_p_visitor> -{ - using this_t = for_each_chunk_p_visitor; - - template <typename Pos, typename Fn> - static bool visit_inner(Pos&& pos, Fn&& fn) - { - return pos.each_pred(this_t{}, fn); - } - - template <typename Pos, typename Fn> - static bool visit_leaf(Pos&& pos, Fn&& fn) - { - auto data = pos.node()->leaf(); - return fn(data, data + pos.count()); - } -}; - -struct for_each_chunk_left_visitor : visitor_base<for_each_chunk_left_visitor> -{ - using this_t = for_each_chunk_left_visitor; - - template <typename Pos, typename Fn> - static void visit_inner(Pos&& pos, size_t last, Fn&& fn) - { - auto l = pos.index(last); - pos.each_left(for_each_chunk_visitor{}, l, fn); - pos.towards_oh(this_t{}, last, l, fn); - } - - template <typename Pos, typename Fn> - static void visit_leaf(Pos&& pos, size_t last, Fn&& fn) - { - auto data = pos.node()->leaf(); - auto l = pos.index(last); - fn(data, data + l + 1); - } -}; - -struct for_each_chunk_right_visitor : visitor_base<for_each_chunk_right_visitor> -{ - using this_t = for_each_chunk_right_visitor; - - template <typename Pos, typename Fn> - static void visit_inner(Pos&& pos, size_t first, Fn&& fn) - { - auto f = pos.index(first); - pos.towards_oh(this_t{}, first, f, fn); - pos.each_right(for_each_chunk_visitor{}, f + 1, fn); - } - - template <typename Pos, typename Fn> - static void visit_leaf(Pos&& pos, size_t first, Fn&& fn) - { - auto data = pos.node()->leaf(); - auto f = pos.index(first); - fn(data + f, data + pos.count()); - } -}; - -struct for_each_chunk_i_visitor : visitor_base<for_each_chunk_i_visitor> -{ - using this_t = for_each_chunk_i_visitor; - - template <typename Pos, typename Fn> - static void visit_relaxed(Pos&& pos, size_t first, size_t last, Fn&& fn) - { - // we are going towards *two* indices, so we need to do the - // relaxed as a special case to correct the second index - if (first < last) { - auto f = pos.index(first); - auto l = pos.index(last - 1); - if (f == l) { - auto sbh = pos.size_before(f); - pos.towards_oh_sbh(this_t{}, first, f, sbh, last - sbh, fn); - } else { - assert(f < l); - pos.towards_oh(for_each_chunk_right_visitor{}, first, f, fn); - pos.each_i(for_each_chunk_visitor{}, f + 1, l, fn); - pos.towards_oh(for_each_chunk_left_visitor{}, last - 1, l, fn); - } - } - } - - template <typename Pos, typename Fn> - static void visit_regular(Pos&& pos, size_t first, size_t last, Fn&& fn) - { - if (first < last) { - auto f = pos.index(first); - auto l = pos.index(last - 1); - if (f == l) - pos.towards_oh(this_t{}, first, f, last, fn); - else { - assert(f < l); - pos.towards_oh(for_each_chunk_right_visitor{}, first, f, fn); - pos.each_i(for_each_chunk_visitor{}, f + 1, l, fn); - pos.towards_oh(for_each_chunk_left_visitor{}, last - 1, l, fn); - } - } - } - - template <typename Pos, typename Fn> - static void visit_leaf(Pos&& pos, size_t first, size_t last, Fn&& fn) - { - auto data = pos.node()->leaf(); - if (first < last) { - auto f = pos.index(first); - auto l = pos.index(last - 1); - fn(data + f, data + l + 1); - } - } -}; - -struct for_each_chunk_p_left_visitor - : visitor_base<for_each_chunk_p_left_visitor> -{ - using this_t = for_each_chunk_p_left_visitor; - - template <typename Pos, typename Fn> - static bool visit_inner(Pos&& pos, size_t last, Fn&& fn) - { - auto l = pos.index(last); - return pos.each_pred_left(for_each_chunk_p_visitor{}, l, fn) && - pos.towards_oh(this_t{}, last, l, fn); - } - - template <typename Pos, typename Fn> - static bool visit_leaf(Pos&& pos, size_t last, Fn&& fn) - { - auto data = pos.node()->leaf(); - auto l = pos.index(last); - return fn(data, data + l + 1); - } -}; - -struct for_each_chunk_p_right_visitor - : visitor_base<for_each_chunk_p_right_visitor> -{ - using this_t = for_each_chunk_p_right_visitor; - - template <typename Pos, typename Fn> - static bool visit_inner(Pos&& pos, size_t first, Fn&& fn) - { - auto f = pos.index(first); - return pos.towards_oh(this_t{}, first, f, fn) && - pos.each_pred_right(for_each_chunk_p_visitor{}, f + 1, fn); - } - - template <typename Pos, typename Fn> - static bool visit_leaf(Pos&& pos, size_t first, Fn&& fn) - { - auto data = pos.node()->leaf(); - auto f = pos.index(first); - return fn(data + f, data + pos.count()); - } -}; - -struct for_each_chunk_p_i_visitor : visitor_base<for_each_chunk_p_i_visitor> -{ - using this_t = for_each_chunk_p_i_visitor; - - template <typename Pos, typename Fn> - static bool visit_relaxed(Pos&& pos, size_t first, size_t last, Fn&& fn) - { - // we are going towards *two* indices, so we need to do the - // relaxed as a special case to correct the second index - if (first < last) { - auto f = pos.index(first); - auto l = pos.index(last - 1); - if (f == l) { - auto sbh = pos.size_before(f); - return pos.towards_oh_sbh( - this_t{}, first, f, sbh, last - sbh, fn); - } else { - assert(f < l); - return pos.towards_oh( - for_each_chunk_p_right_visitor{}, first, f, fn) && - pos.each_pred_i( - for_each_chunk_p_visitor{}, f + 1, l, fn) && - pos.towards_oh( - for_each_chunk_p_left_visitor{}, last - 1, l, fn); - } - } - return true; - } - - template <typename Pos, typename Fn> - static bool visit_regular(Pos&& pos, size_t first, size_t last, Fn&& fn) - { - if (first < last) { - auto f = pos.index(first); - auto l = pos.index(last - 1); - if (f == l) - return pos.towards_oh(this_t{}, first, f, last, fn); - else { - assert(f < l); - return pos.towards_oh( - for_each_chunk_p_right_visitor{}, first, f, fn) && - pos.each_pred_i( - for_each_chunk_p_visitor{}, f + 1, l, fn) && - pos.towards_oh( - for_each_chunk_p_left_visitor{}, last - 1, l, fn); - } - } - return true; - } - - template <typename Pos, typename Fn> - static bool visit_leaf(Pos&& pos, size_t first, size_t last, Fn&& fn) - { - auto data = pos.node()->leaf(); - if (first < last) { - auto f = pos.index(first); - auto l = pos.index(last - 1); - return fn(data + f, data + l + 1); - } - return true; - } -}; - -struct equals_visitor : visitor_base<equals_visitor> -{ - using this_t = equals_visitor; - - struct this_aux_t : visitor_base<this_aux_t> - { - template <typename PosR, typename PosL, typename Iter> - static bool visit_inner( - PosR&& posr, count_t i, PosL&& posl, Iter&& first, size_t idx) - { - return posl.nth_sub(i, this_t{}, posr, first, idx); - } - - template <typename PosR, typename PosL, typename Iter> - static bool visit_leaf( - PosR&& posr, count_t i, PosL&& posl, Iter&& first, size_t idx) - { - return posl.nth_sub_leaf(i, this_t{}, posr, first, idx); - } - }; - - struct rrb : visitor_base<rrb> - { - template <typename PosR, typename Iter, typename Node> - static bool visit_node(PosR&& posr, - Iter&& first, - Node* rootl, - shift_t shiftl, - size_t sizel) - { - assert(shiftl <= posr.shift()); - return shiftl == posr.shift() - ? visit_maybe_relaxed_sub(rootl, - shiftl, - sizel, - this_t{}, - posr, - first, - size_t{}) - : posr.first_sub_inner( - rrb{}, first, rootl, shiftl, sizel); - } - }; - - template <typename Iter> - static auto equal_chunk_p(Iter&& iter) - { - return [iter](auto f, auto e) mutable { - if (f == &*iter) { - iter += e - f; - return true; - } - for (; f != e; ++f, ++iter) - if (*f != *iter) - return false; - return true; - }; - } - - template <typename PosL, typename PosR, typename Iter> - static bool - visit_relaxed(PosL&& posl, PosR&& posr, Iter&& first, size_t idx) - { - auto nl = posl.node(); - auto nr = posr.node(); - if (nl == nr) - return true; - auto cl = posl.count(); - auto cr = posr.count(); - assert(cr > 0); - auto sbr = size_t{}; - auto i = count_t{}; - auto j = count_t{}; - for (; i < cl; ++i) { - auto sbl = posl.size_before(i); - for (; j + 1 < cr && (sbr = posr.size_before(j)) < sbl; ++j) - ; - auto res = - sbl == sbr - ? posr.nth_sub(j, this_aux_t{}, i, posl, first, idx + sbl) - : posl.nth_sub(i, - for_each_chunk_p_visitor{}, - this_t::equal_chunk_p(first + (idx + sbl))); - if (!res) - return false; - } - return true; - } - - template <typename PosL, typename PosR, typename Iter> - static std::enable_if_t<is_relaxed_v<PosR>, bool> - visit_regular(PosL&& posl, PosR&& posr, Iter&& first, size_t idx) - { - return this_t::visit_relaxed(posl, posr, first, idx); - } - - template <typename PosL, typename PosR, typename Iter> - static std::enable_if_t<!is_relaxed_v<PosR>, bool> - visit_regular(PosL&& posl, PosR&& posr, Iter&& first, size_t idx) - { - return posl.count() >= posr.count() - ? this_t::visit_regular(posl, posr.node()) - : this_t::visit_regular(posr, posl.node()); - } - - template <typename PosL, typename PosR, typename Iter> - static bool visit_leaf(PosL&& posl, PosR&& posr, Iter&& first, size_t idx) - { - if (posl.node() == posr.node()) - return true; - auto cl = posl.count(); - auto cr = posr.count(); - auto mp = std::min(cl, cr); - return std::equal(posl.node()->leaf(), - posl.node()->leaf() + mp, - posr.node()->leaf()) && - std::equal(posl.node()->leaf() + mp, - posl.node()->leaf() + posl.count(), - first + (idx + mp)); - } - - template <typename Pos, typename NodeT> - static bool visit_regular(Pos&& pos, NodeT* other) - { - auto node = pos.node(); - return node == other || pos.each_pred_zip(this_t{}, other); - } - - template <typename Pos, typename NodeT> - static bool visit_leaf(Pos&& pos, NodeT* other) - { - auto node = pos.node(); - return node == other || std::equal(node->leaf(), - node->leaf() + pos.count(), - other->leaf()); - } -}; - -template <typename NodeT> -struct update_visitor : visitor_base<update_visitor<NodeT>> -{ - using node_t = NodeT; - using this_t = update_visitor; - - template <typename Pos, typename Fn> - static node_t* visit_relaxed(Pos&& pos, size_t idx, Fn&& fn) - { - auto offset = pos.index(idx); - auto count = pos.count(); - auto node = node_t::make_inner_sr_n(count, pos.relaxed()); - try { - auto child = pos.towards_oh(this_t{}, idx, offset, fn); - node_t::do_copy_inner_sr(node, pos.node(), count); - node->inner()[offset]->dec_unsafe(); - node->inner()[offset] = child; - return node; - } catch (...) { - node_t::delete_inner_r(node, count); - throw; - } - } - - template <typename Pos, typename Fn> - static node_t* visit_regular(Pos&& pos, size_t idx, Fn&& fn) - { - auto offset = pos.index(idx); - auto count = pos.count(); - auto node = node_t::make_inner_n(count); - try { - auto child = pos.towards_oh_ch(this_t{}, idx, offset, count, fn); - node_t::do_copy_inner(node, pos.node(), count); - node->inner()[offset]->dec_unsafe(); - node->inner()[offset] = child; - return node; - } catch (...) { - node_t::delete_inner(node, count); - throw; - } - } - - template <typename Pos, typename Fn> - static node_t* visit_leaf(Pos&& pos, size_t idx, Fn&& fn) - { - auto offset = pos.index(idx); - auto node = node_t::copy_leaf(pos.node(), pos.count()); - try { - node->leaf()[offset] = - std::forward<Fn>(fn)(std::move(node->leaf()[offset])); - return node; - } catch (...) { - node_t::delete_leaf(node, pos.count()); - throw; - } - } -}; - -struct dec_visitor : visitor_base<dec_visitor> -{ - using this_t = dec_visitor; - - template <typename Pos> - static void visit_relaxed(Pos&& p) - { - using node_t = node_type<Pos>; - auto node = p.node(); - if (node->dec()) { - p.each(this_t{}); - node_t::delete_inner_r(node, p.count()); - } - } - - template <typename Pos> - static void visit_regular(Pos&& p) - { - using node_t = node_type<Pos>; - auto node = p.node(); - if (node->dec()) { - p.each(this_t{}); - node_t::delete_inner(node, p.count()); - } - } - - template <typename Pos> - static void visit_leaf(Pos&& p) - { - using node_t = node_type<Pos>; - auto node = p.node(); - if (node->dec()) { - node_t::delete_leaf(node, p.count()); - } - } -}; - -template <typename NodeT> -void dec_leaf(NodeT* node, count_t n) -{ - make_leaf_sub_pos(node, n).visit(dec_visitor{}); -} - -template <typename NodeT> -void dec_inner(NodeT* node, shift_t shift, size_t size) -{ - visit_maybe_relaxed_sub(node, shift, size, dec_visitor()); -} - -template <typename NodeT> -void dec_relaxed(NodeT* node, shift_t shift) -{ - make_relaxed_pos(node, shift, node->relaxed()).visit(dec_visitor()); -} - -template <typename NodeT> -void dec_regular(NodeT* node, shift_t shift, size_t size) -{ - make_regular_pos(node, shift, size).visit(dec_visitor()); -} - -template <typename NodeT> -void dec_empty_regular(NodeT* node) -{ - make_empty_regular_pos(node).visit(dec_visitor()); -} - -template <typename NodeT> -struct get_mut_visitor : visitor_base<get_mut_visitor<NodeT>> -{ - using node_t = NodeT; - using this_t = get_mut_visitor; - using value_t = typename NodeT::value_t; - using edit_t = typename NodeT::edit_t; - - template <typename Pos> - static value_t& - visit_relaxed(Pos&& pos, size_t idx, edit_t e, node_t** location) - { - auto offset = pos.index(idx); - auto count = pos.count(); - auto node = pos.node(); - if (node->can_mutate(e)) { - return pos.towards_oh( - this_t{}, idx, offset, e, &node->inner()[offset]); - } else { - auto new_node = node_t::copy_inner_sr_e(e, node, count); - try { - auto& res = pos.towards_oh( - this_t{}, idx, offset, e, &new_node->inner()[offset]); - pos.visit(dec_visitor{}); - *location = new_node; - return res; - } catch (...) { - dec_relaxed(new_node, pos.shift()); - throw; - } - } - } - - template <typename Pos> - static value_t& - visit_regular(Pos&& pos, size_t idx, edit_t e, node_t** location) - { - assert(pos.node() == *location); - auto offset = pos.index(idx); - auto count = pos.count(); - auto node = pos.node(); - if (node->can_mutate(e)) { - return pos.towards_oh_ch( - this_t{}, idx, offset, count, e, &node->inner()[offset]); - } else { - auto new_node = node_t::copy_inner_e(e, node, count); - try { - auto& res = pos.towards_oh_ch(this_t{}, - idx, - offset, - count, - e, - &new_node->inner()[offset]); - pos.visit(dec_visitor{}); - *location = new_node; - return res; - } catch (...) { - dec_regular(new_node, pos.shift(), pos.size()); - throw; - } - } - } - - template <typename Pos> - static value_t& - visit_leaf(Pos&& pos, size_t idx, edit_t e, node_t** location) - { - assert(pos.node() == *location); - auto node = pos.node(); - if (node->can_mutate(e)) { - return node->leaf()[pos.index(idx)]; - } else { - auto new_node = node_t::copy_leaf_e(e, pos.node(), pos.count()); - pos.visit(dec_visitor{}); - *location = new_node; - return new_node->leaf()[pos.index(idx)]; - } - } -}; - -template <typename NodeT, bool Mutating = true> -struct push_tail_mut_visitor - : visitor_base<push_tail_mut_visitor<NodeT, Mutating>> -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using this_t = push_tail_mut_visitor; - using this_no_mut_t = push_tail_mut_visitor<NodeT, false>; - using node_t = NodeT; - using edit_t = typename NodeT::edit_t; - - template <typename Pos> - static node_t* visit_relaxed(Pos&& pos, edit_t e, node_t* tail, count_t ts) - { - auto node = pos.node(); - auto level = pos.shift(); - auto idx = pos.count() - 1; - auto children = pos.size(idx); - auto new_idx = - children == size_t{1} << level || level == BL ? idx + 1 : idx; - auto new_child = static_cast<node_t*>(nullptr); - auto mutate = Mutating && node->can_mutate(e); - - if (new_idx >= branches<B>) - return nullptr; - else if (idx == new_idx) { - new_child = - mutate ? pos.last_oh_csh(this_t{}, idx, children, e, tail, ts) - : pos.last_oh_csh( - this_no_mut_t{}, idx, children, e, tail, ts); - if (!new_child) { - if (++new_idx < branches<B>) - new_child = node_t::make_path_e(e, level - B, tail); - else - return nullptr; - } - } else - new_child = node_t::make_path_e(e, level - B, tail); - - if (mutate) { - auto count = new_idx + 1; - auto relaxed = node->ensure_mutable_relaxed_n(e, new_idx); - node->inner()[new_idx] = new_child; - relaxed->d.sizes[new_idx] = pos.size() + ts; - relaxed->d.count = count; - return node; - } else { - try { - auto count = new_idx + 1; - auto new_node = node_t::copy_inner_r_e(e, pos.node(), new_idx); - auto relaxed = new_node->relaxed(); - new_node->inner()[new_idx] = new_child; - relaxed->d.sizes[new_idx] = pos.size() + ts; - relaxed->d.count = count; - if (Mutating) - pos.visit(dec_visitor{}); - return new_node; - } catch (...) { - auto shift = pos.shift(); - auto size = new_idx == idx ? children + ts : ts; - if (shift > BL) { - tail->inc(); - dec_inner(new_child, shift - B, size); - } - throw; - } - } - } - - template <typename Pos, typename... Args> - static node_t* visit_regular(Pos&& pos, edit_t e, node_t* tail, Args&&...) - { - assert((pos.size() & mask<BL>) == 0); - auto node = pos.node(); - auto idx = pos.index(pos.size() - 1); - auto new_idx = pos.index(pos.size() + branches<BL> - 1); - auto mutate = Mutating && node->can_mutate(e); - if (mutate) { - node->inner()[new_idx] = - idx == new_idx ? pos.last_oh(this_t{}, idx, e, tail) - /* otherwise */ - : node_t::make_path_e(e, pos.shift() - B, tail); - return node; - } else { - auto new_parent = node_t::make_inner_e(e); - try { - new_parent->inner()[new_idx] = - idx == new_idx - ? pos.last_oh(this_no_mut_t{}, idx, e, tail) - /* otherwise */ - : node_t::make_path_e(e, pos.shift() - B, tail); - node_t::do_copy_inner(new_parent, node, new_idx); - if (Mutating) - pos.visit(dec_visitor{}); - return new_parent; - } catch (...) { - node_t::delete_inner_e(new_parent); - throw; - } - } - } - - template <typename Pos, typename... Args> - static node_t* visit_leaf(Pos&& pos, edit_t e, node_t* tail, Args&&...) - { - IMMER_UNREACHABLE; - } -}; - -template <typename NodeT> -struct push_tail_visitor : visitor_base<push_tail_visitor<NodeT>> -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using this_t = push_tail_visitor; - using node_t = NodeT; - - template <typename Pos> - static node_t* visit_relaxed(Pos&& pos, node_t* tail, count_t ts) - { - auto level = pos.shift(); - auto idx = pos.count() - 1; - auto children = pos.size(idx); - auto new_idx = - children == size_t{1} << level || level == BL ? idx + 1 : idx; - auto new_child = static_cast<node_t*>(nullptr); - if (new_idx >= branches<B>) - return nullptr; - else if (idx == new_idx) { - new_child = pos.last_oh_csh(this_t{}, idx, children, tail, ts); - if (!new_child) { - if (++new_idx < branches<B>) - new_child = node_t::make_path(level - B, tail); - else - return nullptr; - } - } else - new_child = node_t::make_path(level - B, tail); - try { - auto count = new_idx + 1; - auto new_parent = - node_t::copy_inner_r_n(count, pos.node(), new_idx); - auto new_relaxed = new_parent->relaxed(); - new_parent->inner()[new_idx] = new_child; - new_relaxed->d.sizes[new_idx] = pos.size() + ts; - new_relaxed->d.count = count; - return new_parent; - } catch (...) { - auto shift = pos.shift(); - auto size = new_idx == idx ? children + ts : ts; - if (shift > BL) { - tail->inc(); - dec_inner(new_child, shift - B, size); - } - throw; - } - } - - template <typename Pos, typename... Args> - static node_t* visit_regular(Pos&& pos, node_t* tail, Args&&...) - { - assert((pos.size() & mask<BL>) == 0); - auto idx = pos.index(pos.size() - 1); - auto new_idx = pos.index(pos.size() + branches<BL> - 1); - auto count = new_idx + 1; - auto new_parent = node_t::make_inner_n(count); - try { - new_parent->inner()[new_idx] = - idx == new_idx ? pos.last_oh(this_t{}, idx, tail) - /* otherwise */ - : node_t::make_path(pos.shift() - B, tail); - } catch (...) { - node_t::delete_inner(new_parent, count); - throw; - } - return node_t::do_copy_inner(new_parent, pos.node(), new_idx); - } - - template <typename Pos, typename... Args> - static node_t* visit_leaf(Pos&& pos, node_t* tail, Args&&...) - { - IMMER_UNREACHABLE; - } -}; - -struct dec_right_visitor : visitor_base<dec_right_visitor> -{ - using this_t = dec_right_visitor; - using dec_t = dec_visitor; - - template <typename Pos> - static void visit_relaxed(Pos&& p, count_t idx) - { - using node_t = node_type<Pos>; - auto node = p.node(); - if (node->dec()) { - p.each_right(dec_t{}, idx); - node_t::delete_inner_r(node, p.count()); - } - } - - template <typename Pos> - static void visit_regular(Pos&& p, count_t idx) - { - using node_t = node_type<Pos>; - auto node = p.node(); - if (node->dec()) { - p.each_right(dec_t{}, idx); - node_t::delete_inner(node, p.count()); - } - } - - template <typename Pos> - static void visit_leaf(Pos&& p, count_t idx) - { - IMMER_UNREACHABLE; - } -}; - -template <typename NodeT, bool Collapse = true, bool Mutating = true> -struct slice_right_mut_visitor - : visitor_base<slice_right_mut_visitor<NodeT, Collapse, Mutating>> -{ - using node_t = NodeT; - using this_t = slice_right_mut_visitor; - using edit_t = typename NodeT::edit_t; - - // returns a new shift, new root, the new tail size and the new tail - using result_t = std::tuple<shift_t, NodeT*, count_t, NodeT*>; - using no_collapse_t = slice_right_mut_visitor<NodeT, false, true>; - using no_collapse_no_mut_t = slice_right_mut_visitor<NodeT, false, false>; - using no_mut_t = slice_right_mut_visitor<NodeT, Collapse, false>; - - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - template <typename PosT> - static result_t visit_relaxed(PosT&& pos, size_t last, edit_t e) - { - auto idx = pos.index(last); - auto node = pos.node(); - auto mutate = Mutating && node->can_mutate(e); - if (Collapse && idx == 0) { - auto res = mutate ? pos.towards_oh(this_t{}, last, idx, e) - : pos.towards_oh(no_mut_t{}, last, idx, e); - if (Mutating) - pos.visit(dec_right_visitor{}, count_t{1}); - return res; - } else { - using std::get; - auto subs = - mutate ? pos.towards_oh(no_collapse_t{}, last, idx, e) - : pos.towards_oh(no_collapse_no_mut_t{}, last, idx, e); - auto next = get<1>(subs); - auto ts = get<2>(subs); - auto tail = get<3>(subs); - try { - if (next) { - if (mutate) { - auto nodr = node->ensure_mutable_relaxed_n(e, idx); - pos.each_right(dec_visitor{}, idx + 1); - node->inner()[idx] = next; - nodr->d.sizes[idx] = last + 1 - ts; - nodr->d.count = idx + 1; - return std::make_tuple(pos.shift(), node, ts, tail); - } else { - auto newn = node_t::copy_inner_r_e(e, node, idx); - auto newr = newn->relaxed(); - newn->inner()[idx] = next; - newr->d.sizes[idx] = last + 1 - ts; - newr->d.count = idx + 1; - if (Mutating) - pos.visit(dec_visitor{}); - return std::make_tuple(pos.shift(), newn, ts, tail); - } - } else if (idx == 0) { - if (Mutating) - pos.visit(dec_right_visitor{}, count_t{1}); - return std::make_tuple(pos.shift(), nullptr, ts, tail); - } else if (Collapse && idx == 1 && pos.shift() > BL) { - auto newn = pos.node()->inner()[0]; - if (!mutate) - newn->inc(); - if (Mutating) - pos.visit(dec_right_visitor{}, count_t{2}); - return std::make_tuple(pos.shift() - B, newn, ts, tail); - } else { - if (mutate) { - pos.each_right(dec_visitor{}, idx + 1); - node->ensure_mutable_relaxed_n(e, idx)->d.count = idx; - return std::make_tuple(pos.shift(), node, ts, tail); - } else { - auto newn = node_t::copy_inner_r_e(e, node, idx); - if (Mutating) - pos.visit(dec_visitor{}); - return std::make_tuple(pos.shift(), newn, ts, tail); - } - } - } catch (...) { - assert(!mutate); - assert(!next || pos.shift() > BL); - if (next) - dec_inner(next, - pos.shift() - B, - last + 1 - ts - pos.size_before(idx)); - dec_leaf(tail, ts); - throw; - } - } - } - - template <typename PosT> - static result_t visit_regular(PosT&& pos, size_t last, edit_t e) - { - auto idx = pos.index(last); - auto node = pos.node(); - auto mutate = Mutating && node->can_mutate(e); - if (Collapse && idx == 0) { - auto res = mutate ? pos.towards_oh(this_t{}, last, idx, e) - : pos.towards_oh(no_mut_t{}, last, idx, e); - if (Mutating) - pos.visit(dec_right_visitor{}, count_t{1}); - return res; - } else { - using std::get; - auto subs = - mutate ? pos.towards_oh(no_collapse_t{}, last, idx, e) - : pos.towards_oh(no_collapse_no_mut_t{}, last, idx, e); - auto next = get<1>(subs); - auto ts = get<2>(subs); - auto tail = get<3>(subs); - try { - if (next) { - if (mutate) { - node->inner()[idx] = next; - pos.each_right(dec_visitor{}, idx + 1); - return std::make_tuple(pos.shift(), node, ts, tail); - } else { - auto newn = node_t::copy_inner_e(e, node, idx); - newn->inner()[idx] = next; - if (Mutating) - pos.visit(dec_visitor{}); - return std::make_tuple(pos.shift(), newn, ts, tail); - } - } else if (idx == 0) { - if (Mutating) - pos.visit(dec_right_visitor{}, count_t{1}); - return std::make_tuple(pos.shift(), nullptr, ts, tail); - } else if (Collapse && idx == 1 && pos.shift() > BL) { - auto newn = pos.node()->inner()[0]; - if (!mutate) - newn->inc(); - if (Mutating) - pos.visit(dec_right_visitor{}, count_t{2}); - return std::make_tuple(pos.shift() - B, newn, ts, tail); - } else { - if (mutate) { - pos.each_right(dec_visitor{}, idx + 1); - return std::make_tuple(pos.shift(), node, ts, tail); - } else { - auto newn = node_t::copy_inner_e(e, node, idx); - if (Mutating) - pos.visit(dec_visitor{}); - return std::make_tuple(pos.shift(), newn, ts, tail); - } - } - } catch (...) { - assert(!mutate); - assert(!next || pos.shift() > BL); - assert(tail); - if (next) - dec_regular(next, pos.shift() - B, last + 1 - ts); - dec_leaf(tail, ts); - throw; - } - } - } - - template <typename PosT> - static result_t visit_leaf(PosT&& pos, size_t last, edit_t e) - { - auto old_tail_size = pos.count(); - auto new_tail_size = pos.index(last) + 1; - auto node = pos.node(); - auto mutate = Mutating && node->can_mutate(e); - if (new_tail_size == old_tail_size) { - if (!Mutating) - node->inc(); - return std::make_tuple(0, nullptr, new_tail_size, node); - } else if (mutate) { - destroy_n(node->leaf() + new_tail_size, - old_tail_size - new_tail_size); - return std::make_tuple(0, nullptr, new_tail_size, node); - } else { - auto new_tail = node_t::copy_leaf_e(e, node, new_tail_size); - if (Mutating) - pos.visit(dec_visitor{}); - return std::make_tuple(0, nullptr, new_tail_size, new_tail); - } - } -}; - -template <typename NodeT, bool Collapse = true> -struct slice_right_visitor : visitor_base<slice_right_visitor<NodeT, Collapse>> -{ - using node_t = NodeT; - using this_t = slice_right_visitor; - - // returns a new shift, new root, the new tail size and the new tail - using result_t = std::tuple<shift_t, NodeT*, count_t, NodeT*>; - using no_collapse_t = slice_right_visitor<NodeT, false>; - - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - template <typename PosT> - static result_t visit_relaxed(PosT&& pos, size_t last) - { - auto idx = pos.index(last); - if (Collapse && idx == 0) { - return pos.towards_oh(this_t{}, last, idx); - } else { - using std::get; - auto subs = pos.towards_oh(no_collapse_t{}, last, idx); - auto next = get<1>(subs); - auto ts = get<2>(subs); - auto tail = get<3>(subs); - try { - if (next) { - auto count = idx + 1; - auto newn = node_t::copy_inner_r_n(count, pos.node(), idx); - auto newr = newn->relaxed(); - newn->inner()[idx] = next; - newr->d.sizes[idx] = last + 1 - ts; - newr->d.count = count; - return std::make_tuple(pos.shift(), newn, ts, tail); - } else if (idx == 0) { - return std::make_tuple(pos.shift(), nullptr, ts, tail); - } else if (Collapse && idx == 1 && pos.shift() > BL) { - auto newn = pos.node()->inner()[0]; - return std::make_tuple( - pos.shift() - B, newn->inc(), ts, tail); - } else { - auto newn = node_t::copy_inner_r(pos.node(), idx); - return std::make_tuple(pos.shift(), newn, ts, tail); - } - } catch (...) { - assert(!next || pos.shift() > BL); - if (next) - dec_inner(next, - pos.shift() - B, - last + 1 - ts - pos.size_before(idx)); - if (tail) - dec_leaf(tail, ts); - throw; - } - } - } - - template <typename PosT> - static result_t visit_regular(PosT&& pos, size_t last) - { - auto idx = pos.index(last); - if (Collapse && idx == 0) { - return pos.towards_oh(this_t{}, last, idx); - } else { - using std::get; - auto subs = pos.towards_oh(no_collapse_t{}, last, idx); - auto next = get<1>(subs); - auto ts = get<2>(subs); - auto tail = get<3>(subs); - try { - if (next) { - auto newn = node_t::copy_inner_n(idx + 1, pos.node(), idx); - newn->inner()[idx] = next; - return std::make_tuple(pos.shift(), newn, ts, tail); - } else if (idx == 0) { - return std::make_tuple(pos.shift(), nullptr, ts, tail); - } else if (Collapse && idx == 1 && pos.shift() > BL) { - auto newn = pos.node()->inner()[0]; - return std::make_tuple( - pos.shift() - B, newn->inc(), ts, tail); - } else { - auto newn = node_t::copy_inner_n(idx, pos.node(), idx); - return std::make_tuple(pos.shift(), newn, ts, tail); - } - } catch (...) { - assert(!next || pos.shift() > BL); - assert(tail); - if (next) - dec_regular(next, pos.shift() - B, last + 1 - ts); - dec_leaf(tail, ts); - throw; - } - } - } - - template <typename PosT> - static result_t visit_leaf(PosT&& pos, size_t last) - { - auto old_tail_size = pos.count(); - auto new_tail_size = pos.index(last) + 1; - auto new_tail = new_tail_size == old_tail_size - ? pos.node()->inc() - : node_t::copy_leaf(pos.node(), new_tail_size); - return std::make_tuple(0, nullptr, new_tail_size, new_tail); - } -}; - -struct dec_left_visitor : visitor_base<dec_left_visitor> -{ - using this_t = dec_left_visitor; - using dec_t = dec_visitor; - - template <typename Pos> - static void visit_relaxed(Pos&& p, count_t idx) - { - using node_t = node_type<Pos>; - auto node = p.node(); - if (node->dec()) { - p.each_left(dec_t{}, idx); - node_t::delete_inner_r(node, p.count()); - } - } - - template <typename Pos> - static void visit_regular(Pos&& p, count_t idx) - { - using node_t = node_type<Pos>; - auto node = p.node(); - if (node->dec()) { - p.each_left(dec_t{}, idx); - node_t::delete_inner(node, p.count()); - } - } - - template <typename Pos> - static void visit_leaf(Pos&& p, count_t idx) - { - IMMER_UNREACHABLE; - } -}; - -template <typename NodeT, bool Collapse = true, bool Mutating = true> -struct slice_left_mut_visitor - : visitor_base<slice_left_mut_visitor<NodeT, Collapse, Mutating>> -{ - using node_t = NodeT; - using this_t = slice_left_mut_visitor; - using edit_t = typename NodeT::edit_t; - using value_t = typename NodeT::value_t; - using relaxed_t = typename NodeT::relaxed_t; - // returns a new shift and new root - using result_t = std::tuple<shift_t, NodeT*>; - - using no_collapse_t = slice_left_mut_visitor<NodeT, false, true>; - using no_collapse_no_mut_t = slice_left_mut_visitor<NodeT, false, false>; - using no_mut_t = slice_left_mut_visitor<NodeT, Collapse, false>; - - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - template <typename PosT> - static result_t visit_relaxed(PosT&& pos, size_t first, edit_t e) - { - auto idx = pos.subindex(first); - auto count = pos.count(); - auto node = pos.node(); - auto mutate = Mutating && node->can_mutate(e); - auto left_size = pos.size_before(idx); - auto child_size = pos.size_sbh(idx, left_size); - auto dropped_size = first; - auto child_dropped_size = dropped_size - left_size; - if (Collapse && pos.shift() > BL && idx == pos.count() - 1) { - auto r = mutate ? pos.towards_sub_oh(this_t{}, first, idx, e) - : pos.towards_sub_oh(no_mut_t{}, first, idx, e); - if (Mutating) - pos.visit(dec_left_visitor{}, idx); - return r; - } else { - using std::get; - auto newn = mutate ? (node->ensure_mutable_relaxed(e), node) - : node_t::make_inner_r_e(e); - auto newr = newn->relaxed(); - auto newcount = count - idx; - auto new_child_size = child_size - child_dropped_size; - try { - auto subs = - mutate ? pos.towards_sub_oh(no_collapse_t{}, first, idx, e) - : pos.towards_sub_oh( - no_collapse_no_mut_t{}, first, idx, e); - if (mutate) - pos.each_left(dec_visitor{}, idx); - pos.copy_sizes( - idx + 1, newcount - 1, new_child_size, newr->d.sizes + 1); - std::uninitialized_copy(node->inner() + idx + 1, - node->inner() + count, - newn->inner() + 1); - newn->inner()[0] = get<1>(subs); - newr->d.sizes[0] = new_child_size; - newr->d.count = newcount; - if (!mutate) { - node_t::inc_nodes(newn->inner() + 1, newcount - 1); - if (Mutating) - pos.visit(dec_visitor{}); - } - return std::make_tuple(pos.shift(), newn); - } catch (...) { - if (!mutate) - node_t::delete_inner_r_e(newn); - throw; - } - } - } - - template <typename PosT> - static result_t visit_regular(PosT&& pos, size_t first, edit_t e) - { - auto idx = pos.subindex(first); - auto count = pos.count(); - auto node = pos.node(); - auto mutate = Mutating - // this is more restrictive than actually needed because - // it causes the algorithm to also avoid mutating the leaf - // in place - && !node_t::embed_relaxed && node->can_mutate(e); - auto left_size = pos.size_before(idx); - auto child_size = pos.size_sbh(idx, left_size); - auto dropped_size = first; - auto child_dropped_size = dropped_size - left_size; - if (Collapse && pos.shift() > BL && idx == pos.count() - 1) { - auto r = mutate ? pos.towards_sub_oh(this_t{}, first, idx, e) - : pos.towards_sub_oh(no_mut_t{}, first, idx, e); - if (Mutating) - pos.visit(dec_left_visitor{}, idx); - return r; - } else { - using std::get; - // if possible, we convert the node to a relaxed one - // simply by allocating a `relaxed_t` size table for - // it... maybe some of this magic should be moved as a - // `node<...>` static method... - auto newcount = count - idx; - auto newn = - mutate ? (node->impl.d.data.inner.relaxed = new ( - node_t::heap::allocate(node_t::max_sizeof_relaxed, - norefs_tag{})) relaxed_t, - node) - : node_t::make_inner_r_e(e); - auto newr = newn->relaxed(); - try { - auto subs = - mutate ? pos.towards_sub_oh(no_collapse_t{}, first, idx, e) - : pos.towards_sub_oh( - no_collapse_no_mut_t{}, first, idx, e); - if (mutate) - pos.each_left(dec_visitor{}, idx); - newr->d.sizes[0] = child_size - child_dropped_size; - pos.copy_sizes( - idx + 1, newcount - 1, newr->d.sizes[0], newr->d.sizes + 1); - newr->d.count = newcount; - newn->inner()[0] = get<1>(subs); - std::uninitialized_copy(node->inner() + idx + 1, - node->inner() + count, - newn->inner() + 1); - if (!mutate) { - node_t::inc_nodes(newn->inner() + 1, newcount - 1); - if (Mutating) - pos.visit(dec_visitor{}); - } - return std::make_tuple(pos.shift(), newn); - } catch (...) { - if (!mutate) - node_t::delete_inner_r_e(newn); - else { - // restore the regular node that we were - // attempting to relax... - node_t::heap::deallocate(node_t::max_sizeof_relaxed, - node->impl.d.data.inner.relaxed); - node->impl.d.data.inner.relaxed = nullptr; - } - throw; - } - } - } - - template <typename PosT> - static result_t visit_leaf(PosT&& pos, size_t first, edit_t e) - { - auto node = pos.node(); - auto idx = pos.index(first); - auto count = pos.count(); - auto mutate = Mutating && - std::is_nothrow_move_constructible<value_t>::value && - node->can_mutate(e); - if (mutate) { - auto data = node->leaf(); - auto newcount = count - idx; - std::move(data + idx, data + count, data); - destroy_n(data + newcount, idx); - return std::make_tuple(0, node); - } else { - auto newn = node_t::copy_leaf_e(e, node, idx, count); - if (Mutating) - pos.visit(dec_visitor{}); - return std::make_tuple(0, newn); - } - } -}; - -template <typename NodeT, bool Collapse = true> -struct slice_left_visitor : visitor_base<slice_left_visitor<NodeT, Collapse>> -{ - using node_t = NodeT; - using this_t = slice_left_visitor; - - // returns a new shift and new root - using result_t = std::tuple<shift_t, NodeT*>; - using no_collapse_t = slice_left_visitor<NodeT, false>; - - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - template <typename PosT> - static result_t visit_inner(PosT&& pos, size_t first) - { - auto idx = pos.subindex(first); - auto count = pos.count(); - auto left_size = pos.size_before(idx); - auto child_size = pos.size_sbh(idx, left_size); - auto dropped_size = first; - auto child_dropped_size = dropped_size - left_size; - if (Collapse && pos.shift() > BL && idx == pos.count() - 1) { - return pos.towards_sub_oh(this_t{}, first, idx); - } else { - using std::get; - auto n = pos.node(); - auto newc = count - idx; - auto newn = node_t::make_inner_r_n(newc); - try { - auto subs = pos.towards_sub_oh(no_collapse_t{}, first, idx); - auto newr = newn->relaxed(); - newr->d.count = count - idx; - newr->d.sizes[0] = child_size - child_dropped_size; - pos.copy_sizes(idx + 1, - newr->d.count - 1, - newr->d.sizes[0], - newr->d.sizes + 1); - assert(newr->d.sizes[newr->d.count - 1] == - pos.size() - dropped_size); - newn->inner()[0] = get<1>(subs); - std::uninitialized_copy(n->inner() + idx + 1, - n->inner() + count, - newn->inner() + 1); - node_t::inc_nodes(newn->inner() + 1, newr->d.count - 1); - return std::make_tuple(pos.shift(), newn); - } catch (...) { - node_t::delete_inner_r(newn, newc); - throw; - } - } - } - - template <typename PosT> - static result_t visit_leaf(PosT&& pos, size_t first) - { - auto n = node_t::copy_leaf(pos.node(), pos.index(first), pos.count()); - return std::make_tuple(0, n); - } -}; - -template <typename Node> -struct concat_center_pos -{ - static constexpr auto B = Node::bits; - static constexpr auto BL = Node::bits_leaf; - - static constexpr count_t max_children = 3; - - using node_t = Node; - using edit_t = typename Node::edit_t; - - shift_t shift_ = 0u; - count_t count_ = 0u; - node_t* nodes_[max_children]; - size_t sizes_[max_children]; - - auto shift() const { return shift_; } - - concat_center_pos(shift_t s, Node* n0, size_t s0) - : shift_{s} - , count_{1} - , nodes_{n0} - , sizes_{s0} - {} - - concat_center_pos(shift_t s, Node* n0, size_t s0, Node* n1, size_t s1) - : shift_{s} - , count_{2} - , nodes_{n0, n1} - , sizes_{s0, s1} - {} - - concat_center_pos(shift_t s, - Node* n0, - size_t s0, - Node* n1, - size_t s1, - Node* n2, - size_t s2) - : shift_{s} - , count_{3} - , nodes_{n0, n1, n2} - , sizes_{s0, s1, s2} - {} - - template <typename Visitor, typename... Args> - void each_sub(Visitor v, Args&&... args) - { - if (shift_ == BL) { - for (auto i = count_t{0}; i < count_; ++i) - make_leaf_sub_pos(nodes_[i], sizes_[i]).visit(v, args...); - } else { - for (auto i = count_t{0}; i < count_; ++i) - make_relaxed_pos(nodes_[i], shift_ - B, nodes_[i]->relaxed()) - .visit(v, args...); - } - } - - relaxed_pos<Node> realize() && - { - if (count_ > 1) { - try { - auto result = node_t::make_inner_r_n(count_); - auto r = result->relaxed(); - r->d.count = count_; - std::copy(nodes_, nodes_ + count_, result->inner()); - std::copy(sizes_, sizes_ + count_, r->d.sizes); - return {result, shift_, r}; - } catch (...) { - each_sub(dec_visitor{}); - throw; - } - } else { - assert(shift_ >= B + BL); - return {nodes_[0], shift_ - B, nodes_[0]->relaxed()}; - } - } - - relaxed_pos<Node> realize_e(edit_t e) - { - if (count_ > 1) { - auto result = node_t::make_inner_r_e(e); - auto r = result->relaxed(); - r->d.count = count_; - std::copy(nodes_, nodes_ + count_, result->inner()); - std::copy(sizes_, sizes_ + count_, r->d.sizes); - return {result, shift_, r}; - } else { - assert(shift_ >= B + BL); - return {nodes_[0], shift_ - B, nodes_[0]->relaxed()}; - } - } -}; - -template <typename Node> -struct concat_merger -{ - using node_t = Node; - static constexpr auto B = Node::bits; - static constexpr auto BL = Node::bits_leaf; - - using result_t = concat_center_pos<Node>; - - count_t* curr_; - count_t n_; - result_t result_; - - concat_merger(shift_t shift, count_t* counts, count_t n) - : curr_{counts} - , n_{n} - , result_{ - shift + B, node_t::make_inner_r_n(std::min(n_, branches<B>)), 0} - {} - - node_t* to_ = {}; - count_t to_offset_ = {}; - size_t to_size_ = {}; - - void add_child(node_t* p, size_t size) - { - ++curr_; - auto parent = result_.nodes_[result_.count_ - 1]; - auto relaxed = parent->relaxed(); - if (relaxed->d.count == branches<B>) { - assert(result_.count_ < result_t::max_children); - n_ -= branches<B>; - parent = node_t::make_inner_r_n(std::min(n_, branches<B>)); - relaxed = parent->relaxed(); - result_.nodes_[result_.count_] = parent; - result_.sizes_[result_.count_] = result_.sizes_[result_.count_ - 1]; - ++result_.count_; - } - auto idx = relaxed->d.count++; - result_.sizes_[result_.count_ - 1] += size; - relaxed->d.sizes[idx] = size + (idx ? relaxed->d.sizes[idx - 1] : 0); - parent->inner()[idx] = p; - }; - - template <typename Pos> - void merge_leaf(Pos&& p) - { - auto from = p.node(); - auto from_size = p.size(); - auto from_count = p.count(); - assert(from_size); - if (!to_ && *curr_ == from_count) { - add_child(from, from_size); - from->inc(); - } else { - auto from_offset = count_t{}; - auto from_data = from->leaf(); - do { - if (!to_) { - to_ = node_t::make_leaf_n(*curr_); - to_offset_ = 0; - } - auto data = to_->leaf(); - auto to_copy = - std::min(from_count - from_offset, *curr_ - to_offset_); - std::uninitialized_copy(from_data + from_offset, - from_data + from_offset + to_copy, - data + to_offset_); - to_offset_ += to_copy; - from_offset += to_copy; - if (*curr_ == to_offset_) { - add_child(to_, to_offset_); - to_ = nullptr; - } - } while (from_offset != from_count); - } - } - - template <typename Pos> - void merge_inner(Pos&& p) - { - auto from = p.node(); - auto from_size = p.size(); - auto from_count = p.count(); - assert(from_size); - if (!to_ && *curr_ == from_count) { - add_child(from, from_size); - from->inc(); - } else { - auto from_offset = count_t{}; - auto from_data = from->inner(); - do { - if (!to_) { - to_ = node_t::make_inner_r_n(*curr_); - to_offset_ = 0; - to_size_ = 0; - } - auto data = to_->inner(); - auto to_copy = - std::min(from_count - from_offset, *curr_ - to_offset_); - std::uninitialized_copy(from_data + from_offset, - from_data + from_offset + to_copy, - data + to_offset_); - node_t::inc_nodes(from_data + from_offset, to_copy); - auto sizes = to_->relaxed()->d.sizes; - p.copy_sizes( - from_offset, to_copy, to_size_, sizes + to_offset_); - to_offset_ += to_copy; - from_offset += to_copy; - to_size_ = sizes[to_offset_ - 1]; - if (*curr_ == to_offset_) { - to_->relaxed()->d.count = to_offset_; - add_child(to_, to_size_); - to_ = nullptr; - } - } while (from_offset != from_count); - } - } - - concat_center_pos<Node> finish() const - { - assert(!to_); - return result_; - } - - void abort() - { - auto shift = result_.shift_ - B; - if (to_) { - if (shift == BL) - node_t::delete_leaf(to_, to_offset_); - else { - to_->relaxed()->d.count = to_offset_; - dec_relaxed(to_, shift - B); - } - } - result_.each_sub(dec_visitor()); - } -}; - -struct concat_merger_visitor : visitor_base<concat_merger_visitor> -{ - using this_t = concat_merger_visitor; - - template <typename Pos, typename Merger> - static void visit_inner(Pos&& p, Merger& merger) - { - merger.merge_inner(p); - } - - template <typename Pos, typename Merger> - static void visit_leaf(Pos&& p, Merger& merger) - { - merger.merge_leaf(p); - } -}; - -struct concat_rebalance_plan_fill_visitor - : visitor_base<concat_rebalance_plan_fill_visitor> -{ - using this_t = concat_rebalance_plan_fill_visitor; - - template <typename Pos, typename Plan> - static void visit_node(Pos&& p, Plan& plan) - { - auto count = p.count(); - assert(plan.n < Plan::max_children); - plan.counts[plan.n++] = count; - plan.total += count; - } -}; - -template <bits_t B, bits_t BL> -struct concat_rebalance_plan -{ - static constexpr auto max_children = 2 * branches<B> + 1; - - count_t counts[max_children]; - count_t n = 0u; - count_t total = 0u; - - template <typename LPos, typename CPos, typename RPos> - void fill(LPos&& lpos, CPos&& cpos, RPos&& rpos) - { - assert(n == 0u); - assert(total == 0u); - using visitor_t = concat_rebalance_plan_fill_visitor; - lpos.each_left_sub(visitor_t{}, *this); - cpos.each_sub(visitor_t{}, *this); - rpos.each_right_sub(visitor_t{}, *this); - } - - void shuffle(shift_t shift) - { - // gcc seems to not really understand this code... :( -#if !defined(_MSC_VER) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Warray-bounds" -#endif - constexpr count_t rrb_extras = 2; - constexpr count_t rrb_invariant = 1; - const auto bits = shift == BL ? BL : B; - const auto branches = count_t{1} << bits; - const auto optimal = ((total - 1) >> bits) + 1; - count_t i = 0; - while (n >= optimal + rrb_extras) { - // skip ok nodes - while (counts[i] > branches - rrb_invariant) - i++; - // short node, redistribute - auto remaining = counts[i]; - do { - auto count = std::min(remaining + counts[i + 1], branches); - counts[i] = count; - remaining += counts[i + 1] - count; - ++i; - } while (remaining > 0); - // remove node - std::move(counts + i + 1, counts + n, counts + i); - --n; - --i; - } -#if !defined(_MSC_VER) -#pragma GCC diagnostic pop -#endif - } - - template <typename LPos, typename CPos, typename RPos> - concat_center_pos<node_type<CPos>> - merge(LPos&& lpos, CPos&& cpos, RPos&& rpos) - { - using node_t = node_type<CPos>; - using merger_t = concat_merger<node_t>; - using visitor_t = concat_merger_visitor; - auto merger = merger_t{cpos.shift(), counts, n}; - try { - lpos.each_left_sub(visitor_t{}, merger); - cpos.each_sub(visitor_t{}, merger); - rpos.each_right_sub(visitor_t{}, merger); - cpos.each_sub(dec_visitor{}); - return merger.finish(); - } catch (...) { - merger.abort(); - throw; - } - } -}; - -template <typename Node, typename LPos, typename CPos, typename RPos> -concat_center_pos<Node> concat_rebalance(LPos&& lpos, CPos&& cpos, RPos&& rpos) -{ - auto plan = concat_rebalance_plan<Node::bits, Node::bits_leaf>{}; - plan.fill(lpos, cpos, rpos); - plan.shuffle(cpos.shift()); - try { - return plan.merge(lpos, cpos, rpos); - } catch (...) { - cpos.each_sub(dec_visitor{}); - throw; - } -} - -template <typename Node, typename LPos, typename TPos, typename RPos> -concat_center_pos<Node> concat_leafs(LPos&& lpos, TPos&& tpos, RPos&& rpos) -{ - static_assert(Node::bits >= 2, ""); - assert(lpos.shift() == tpos.shift()); - assert(lpos.shift() == rpos.shift()); - assert(lpos.shift() == 0); - if (tpos.count() > 0) - return { - Node::bits_leaf, - lpos.node()->inc(), - lpos.count(), - tpos.node()->inc(), - tpos.count(), - rpos.node()->inc(), - rpos.count(), - }; - else - return { - Node::bits_leaf, - lpos.node()->inc(), - lpos.count(), - rpos.node()->inc(), - rpos.count(), - }; -} - -template <typename Node> -struct concat_left_visitor; -template <typename Node> -struct concat_right_visitor; -template <typename Node> -struct concat_both_visitor; - -template <typename Node, typename LPos, typename TPos, typename RPos> -concat_center_pos<Node> concat_inners(LPos&& lpos, TPos&& tpos, RPos&& rpos) -{ - auto lshift = lpos.shift(); - auto rshift = rpos.shift(); - if (lshift > rshift) { - auto cpos = lpos.last_sub(concat_left_visitor<Node>{}, tpos, rpos); - return concat_rebalance<Node>(lpos, cpos, null_sub_pos{}); - } else if (lshift < rshift) { - auto cpos = rpos.first_sub(concat_right_visitor<Node>{}, lpos, tpos); - return concat_rebalance<Node>(null_sub_pos{}, cpos, rpos); - } else { - assert(lshift == rshift); - assert(Node::bits_leaf == 0u || lshift > 0); - auto cpos = lpos.last_sub(concat_both_visitor<Node>{}, tpos, rpos); - return concat_rebalance<Node>(lpos, cpos, rpos); - } -} - -template <typename Node> -struct concat_left_visitor : visitor_base<concat_left_visitor<Node>> -{ - using this_t = concat_left_visitor; - - template <typename LPos, typename TPos, typename RPos> - static concat_center_pos<Node> - visit_inner(LPos&& lpos, TPos&& tpos, RPos&& rpos) - { - return concat_inners<Node>(lpos, tpos, rpos); - } - - template <typename LPos, typename TPos, typename RPos> - static concat_center_pos<Node> - visit_leaf(LPos&& lpos, TPos&& tpos, RPos&& rpos) - { - IMMER_UNREACHABLE; - } -}; - -template <typename Node> -struct concat_right_visitor : visitor_base<concat_right_visitor<Node>> -{ - using this_t = concat_right_visitor; - - template <typename RPos, typename LPos, typename TPos> - static concat_center_pos<Node> - visit_inner(RPos&& rpos, LPos&& lpos, TPos&& tpos) - { - return concat_inners<Node>(lpos, tpos, rpos); - } - - template <typename RPos, typename LPos, typename TPos> - static concat_center_pos<Node> - visit_leaf(RPos&& rpos, LPos&& lpos, TPos&& tpos) - { - return concat_leafs<Node>(lpos, tpos, rpos); - } -}; - -template <typename Node> -struct concat_both_visitor : visitor_base<concat_both_visitor<Node>> -{ - using this_t = concat_both_visitor; - - template <typename LPos, typename TPos, typename RPos> - static concat_center_pos<Node> - visit_inner(LPos&& lpos, TPos&& tpos, RPos&& rpos) - { - return rpos.first_sub(concat_right_visitor<Node>{}, lpos, tpos); - } - - template <typename LPos, typename TPos, typename RPos> - static concat_center_pos<Node> - visit_leaf(LPos&& lpos, TPos&& tpos, RPos&& rpos) - { - return rpos.first_sub_leaf(concat_right_visitor<Node>{}, lpos, tpos); - } -}; - -template <typename Node> -struct concat_trees_right_visitor - : visitor_base<concat_trees_right_visitor<Node>> -{ - using this_t = concat_trees_right_visitor; - - template <typename RPos, typename LPos, typename TPos> - static concat_center_pos<Node> - visit_node(RPos&& rpos, LPos&& lpos, TPos&& tpos) - { - return concat_inners<Node>(lpos, tpos, rpos); - } -}; - -template <typename Node> -struct concat_trees_left_visitor : visitor_base<concat_trees_left_visitor<Node>> -{ - using this_t = concat_trees_left_visitor; - - template <typename LPos, typename TPos, typename... Args> - static concat_center_pos<Node> - visit_node(LPos&& lpos, TPos&& tpos, Args&&... args) - { - return visit_maybe_relaxed_sub( - args..., concat_trees_right_visitor<Node>{}, lpos, tpos); - } -}; - -template <typename Node> -relaxed_pos<Node> concat_trees(Node* lroot, - shift_t lshift, - size_t lsize, - Node* ltail, - count_t ltcount, - Node* rroot, - shift_t rshift, - size_t rsize) -{ - return visit_maybe_relaxed_sub(lroot, - lshift, - lsize, - concat_trees_left_visitor<Node>{}, - make_leaf_pos(ltail, ltcount), - rroot, - rshift, - rsize) - .realize(); -} - -template <typename Node> -relaxed_pos<Node> concat_trees( - Node* ltail, count_t ltcount, Node* rroot, shift_t rshift, size_t rsize) -{ - return make_singleton_regular_sub_pos(ltail, ltcount) - .visit(concat_trees_left_visitor<Node>{}, - empty_leaf_pos<Node>{}, - rroot, - rshift, - rsize) - .realize(); -} - -template <typename Node> -using concat_center_mut_pos = concat_center_pos<Node>; - -template <typename Node> -struct concat_merger_mut -{ - using node_t = Node; - using edit_t = typename Node::edit_t; - - static constexpr auto B = Node::bits; - static constexpr auto BL = Node::bits_leaf; - - using result_t = concat_center_pos<Node>; - - edit_t ec_ = {}; - - count_t* curr_; - count_t n_; - result_t result_; - count_t count_ = 0; - node_t* candidate_ = nullptr; - edit_t candidate_e_ = Node::memory::transience_t::noone; - - concat_merger_mut(edit_t ec, - shift_t shift, - count_t* counts, - count_t n, - edit_t candidate_e, - node_t* candidate) - : ec_{ec} - , curr_{counts} - , n_{n} - , result_{shift + B, nullptr, 0} - { - if (candidate) { - candidate->ensure_mutable_relaxed_e(candidate_e, ec); - result_.nodes_[0] = candidate; - } else { - result_.nodes_[0] = node_t::make_inner_r_e(ec); - } - } - - node_t* to_ = {}; - count_t to_offset_ = {}; - size_t to_size_ = {}; - - void set_candidate(edit_t candidate_e, node_t* candidate) - { - candidate_ = candidate; - candidate_e_ = candidate_e; - } - - void add_child(node_t* p, size_t size) - { - ++curr_; - auto parent = result_.nodes_[result_.count_ - 1]; - auto relaxed = parent->relaxed(); - if (count_ == branches<B>) { - parent->relaxed()->d.count = count_; - assert(result_.count_ < result_t::max_children); - n_ -= branches<B>; - if (candidate_) { - parent = candidate_; - parent->ensure_mutable_relaxed_e(candidate_e_, ec_); - candidate_ = nullptr; - } else - parent = node_t::make_inner_r_e(ec_); - count_ = 0; - relaxed = parent->relaxed(); - result_.nodes_[result_.count_] = parent; - result_.sizes_[result_.count_] = result_.sizes_[result_.count_ - 1]; - ++result_.count_; - } - auto idx = count_++; - result_.sizes_[result_.count_ - 1] += size; - relaxed->d.sizes[idx] = size + (idx ? relaxed->d.sizes[idx - 1] : 0); - parent->inner()[idx] = p; - }; - - template <typename Pos> - void merge_leaf(Pos&& p, edit_t e) - { - auto from = p.node(); - auto from_size = p.size(); - auto from_count = p.count(); - assert(from_size); - if (!to_ && *curr_ == from_count) { - add_child(from, from_size); - } else { - auto from_offset = count_t{}; - auto from_data = from->leaf(); - auto from_mutate = from->can_mutate(e); - do { - if (!to_) { - if (from_mutate) { - node_t::ownee(from) = ec_; - to_ = from->inc(); - assert(from_count); - } else { - to_ = node_t::make_leaf_e(ec_); - } - to_offset_ = 0; - } - auto data = to_->leaf(); - auto to_copy = - std::min(from_count - from_offset, *curr_ - to_offset_); - if (from == to_) { - if (from_offset != to_offset_) - std::move(from_data + from_offset, - from_data + from_offset + to_copy, - data + to_offset_); - } else { - if (!from_mutate) - std::uninitialized_copy(from_data + from_offset, - from_data + from_offset + - to_copy, - data + to_offset_); - else - detail::uninitialized_move(from_data + from_offset, - from_data + from_offset + - to_copy, - data + to_offset_); - } - to_offset_ += to_copy; - from_offset += to_copy; - if (*curr_ == to_offset_) { - add_child(to_, to_offset_); - to_ = nullptr; - } - } while (from_offset != from_count); - } - } - - template <typename Pos> - void merge_inner(Pos&& p, edit_t e) - { - auto from = p.node(); - auto from_size = p.size(); - auto from_count = p.count(); - assert(from_size); - if (!to_ && *curr_ == from_count) { - add_child(from, from_size); - } else { - auto from_offset = count_t{}; - auto from_data = from->inner(); - auto from_mutate = from->can_relax() && from->can_mutate(e); - do { - if (!to_) { - if (from_mutate) { - node_t::ownee(from) = ec_; - from->ensure_mutable_relaxed_e(e, ec_); - to_ = from; - } else { - to_ = node_t::make_inner_r_e(ec_); - } - to_offset_ = 0; - to_size_ = 0; - } - auto data = to_->inner(); - auto to_copy = - std::min(from_count - from_offset, *curr_ - to_offset_); - auto sizes = to_->relaxed()->d.sizes; - if (from != to_ || from_offset != to_offset_) { - std::copy(from_data + from_offset, - from_data + from_offset + to_copy, - data + to_offset_); - p.copy_sizes( - from_offset, to_copy, to_size_, sizes + to_offset_); - } - to_offset_ += to_copy; - from_offset += to_copy; - to_size_ = sizes[to_offset_ - 1]; - if (*curr_ == to_offset_) { - to_->relaxed()->d.count = to_offset_; - add_child(to_, to_size_); - to_ = nullptr; - } - } while (from_offset != from_count); - } - } - - concat_center_pos<Node> finish() const - { - assert(!to_); - result_.nodes_[result_.count_ - 1]->relaxed()->d.count = count_; - return result_; - } - - void abort() - { - // We may have mutated stuff the tree in place, leaving - // everything in a corrupted state... It should be possible - // to define cleanup properly, but that is a task for some - // other day... ;) - std::terminate(); - } -}; - -struct concat_merger_mut_visitor : visitor_base<concat_merger_mut_visitor> -{ - using this_t = concat_merger_mut_visitor; - - template <typename Pos, typename Merger> - static void visit_inner(Pos&& p, Merger& merger, edit_type<Pos> e) - { - merger.merge_inner(p, e); - } - - template <typename Pos, typename Merger> - static void visit_leaf(Pos&& p, Merger& merger, edit_type<Pos> e) - { - merger.merge_leaf(p, e); - } -}; - -template <bits_t B, bits_t BL> -struct concat_rebalance_plan_mut : concat_rebalance_plan<B, BL> -{ - using this_t = concat_rebalance_plan_mut; - - template <typename LPos, typename CPos, typename RPos> - concat_center_mut_pos<node_type<CPos>> merge(edit_type<CPos> ec, - edit_type<CPos> el, - LPos&& lpos, - CPos&& cpos, - edit_type<CPos> er, - RPos&& rpos) - { - using node_t = node_type<CPos>; - using merger_t = concat_merger_mut<node_t>; - using visitor_t = concat_merger_mut_visitor; - auto lnode = ((node_t*) lpos.node()); - auto rnode = ((node_t*) rpos.node()); - auto lmut2 = lnode && lnode->can_relax() && lnode->can_mutate(el); - auto rmut2 = rnode && rnode->can_relax() && rnode->can_mutate(er); - auto merger = merger_t{ec, - cpos.shift(), - this->counts, - this->n, - el, - lmut2 ? lnode : nullptr}; - try { - lpos.each_left_sub(visitor_t{}, merger, el); - cpos.each_sub(visitor_t{}, merger, ec); - if (rmut2) - merger.set_candidate(er, rnode); - rpos.each_right_sub(visitor_t{}, merger, er); - return merger.finish(); - } catch (...) { - merger.abort(); - throw; - } - } -}; - -template <typename Node, typename LPos, typename CPos, typename RPos> -concat_center_pos<Node> concat_rebalance_mut(edit_type<Node> ec, - edit_type<Node> el, - LPos&& lpos, - CPos&& cpos, - edit_type<Node> er, - RPos&& rpos) -{ - auto plan = concat_rebalance_plan_mut<Node::bits, Node::bits_leaf>{}; - plan.fill(lpos, cpos, rpos); - plan.shuffle(cpos.shift()); - return plan.merge(ec, el, lpos, cpos, er, rpos); -} - -template <typename Node, typename LPos, typename TPos, typename RPos> -concat_center_mut_pos<Node> concat_leafs_mut(edit_type<Node> ec, - edit_type<Node> el, - LPos&& lpos, - TPos&& tpos, - edit_type<Node> er, - RPos&& rpos) -{ - static_assert(Node::bits >= 2, ""); - assert(lpos.shift() == tpos.shift()); - assert(lpos.shift() == rpos.shift()); - assert(lpos.shift() == 0); - if (tpos.count() > 0) - return { - Node::bits_leaf, - lpos.node(), - lpos.count(), - tpos.node(), - tpos.count(), - rpos.node(), - rpos.count(), - }; - else - return { - Node::bits_leaf, - lpos.node(), - lpos.count(), - rpos.node(), - rpos.count(), - }; -} - -template <typename Node> -struct concat_left_mut_visitor; -template <typename Node> -struct concat_right_mut_visitor; -template <typename Node> -struct concat_both_mut_visitor; - -template <typename Node, typename LPos, typename TPos, typename RPos> -concat_center_mut_pos<Node> concat_inners_mut(edit_type<Node> ec, - edit_type<Node> el, - LPos&& lpos, - TPos&& tpos, - edit_type<Node> er, - RPos&& rpos) -{ - auto lshift = lpos.shift(); - auto rshift = rpos.shift(); - // lpos.node() can be null it is a singleton_regular_sub_pos<...>, - // this is, when the tree is just a tail... - if (lshift > rshift) { - auto cpos = lpos.last_sub( - concat_left_mut_visitor<Node>{}, ec, el, tpos, er, rpos); - return concat_rebalance_mut<Node>( - ec, el, lpos, cpos, er, null_sub_pos{}); - } else if (lshift < rshift) { - auto cpos = rpos.first_sub( - concat_right_mut_visitor<Node>{}, ec, el, lpos, tpos, er); - return concat_rebalance_mut<Node>( - ec, el, null_sub_pos{}, cpos, er, rpos); - } else { - assert(lshift == rshift); - assert(Node::bits_leaf == 0u || lshift > 0); - auto cpos = lpos.last_sub( - concat_both_mut_visitor<Node>{}, ec, el, tpos, er, rpos); - return concat_rebalance_mut<Node>(ec, el, lpos, cpos, er, rpos); - } -} - -template <typename Node> -struct concat_left_mut_visitor : visitor_base<concat_left_mut_visitor<Node>> -{ - using this_t = concat_left_mut_visitor; - using edit_t = typename Node::edit_t; - - template <typename LPos, typename TPos, typename RPos> - static concat_center_mut_pos<Node> visit_inner( - LPos&& lpos, edit_t ec, edit_t el, TPos&& tpos, edit_t er, RPos&& rpos) - { - return concat_inners_mut<Node>(ec, el, lpos, tpos, er, rpos); - } - - template <typename LPos, typename TPos, typename RPos> - static concat_center_mut_pos<Node> visit_leaf( - LPos&& lpos, edit_t ec, edit_t el, TPos&& tpos, edit_t er, RPos&& rpos) - { - IMMER_UNREACHABLE; - } -}; - -template <typename Node> -struct concat_right_mut_visitor : visitor_base<concat_right_mut_visitor<Node>> -{ - using this_t = concat_right_mut_visitor; - using edit_t = typename Node::edit_t; - - template <typename RPos, typename LPos, typename TPos> - static concat_center_mut_pos<Node> visit_inner( - RPos&& rpos, edit_t ec, edit_t el, LPos&& lpos, TPos&& tpos, edit_t er) - { - return concat_inners_mut<Node>(ec, el, lpos, tpos, er, rpos); - } - - template <typename RPos, typename LPos, typename TPos> - static concat_center_mut_pos<Node> visit_leaf( - RPos&& rpos, edit_t ec, edit_t el, LPos&& lpos, TPos&& tpos, edit_t er) - { - return concat_leafs_mut<Node>(ec, el, lpos, tpos, er, rpos); - } -}; - -template <typename Node> -struct concat_both_mut_visitor : visitor_base<concat_both_mut_visitor<Node>> -{ - using this_t = concat_both_mut_visitor; - using edit_t = typename Node::edit_t; - - template <typename LPos, typename TPos, typename RPos> - static concat_center_mut_pos<Node> visit_inner( - LPos&& lpos, edit_t ec, edit_t el, TPos&& tpos, edit_t er, RPos&& rpos) - { - return rpos.first_sub( - concat_right_mut_visitor<Node>{}, ec, el, lpos, tpos, er); - } - - template <typename LPos, typename TPos, typename RPos> - static concat_center_mut_pos<Node> visit_leaf( - LPos&& lpos, edit_t ec, edit_t el, TPos&& tpos, edit_t er, RPos&& rpos) - { - return rpos.first_sub_leaf( - concat_right_mut_visitor<Node>{}, ec, el, lpos, tpos, er); - } -}; - -template <typename Node> -struct concat_trees_right_mut_visitor - : visitor_base<concat_trees_right_mut_visitor<Node>> -{ - using this_t = concat_trees_right_mut_visitor; - using edit_t = typename Node::edit_t; - - template <typename RPos, typename LPos, typename TPos> - static concat_center_mut_pos<Node> visit_node( - RPos&& rpos, edit_t ec, edit_t el, LPos&& lpos, TPos&& tpos, edit_t er) - { - return concat_inners_mut<Node>(ec, el, lpos, tpos, er, rpos); - } -}; - -template <typename Node> -struct concat_trees_left_mut_visitor - : visitor_base<concat_trees_left_mut_visitor<Node>> -{ - using this_t = concat_trees_left_mut_visitor; - using edit_t = typename Node::edit_t; - - template <typename LPos, typename TPos, typename... Args> - static concat_center_mut_pos<Node> visit_node(LPos&& lpos, - edit_t ec, - edit_t el, - TPos&& tpos, - edit_t er, - Args&&... args) - { - return visit_maybe_relaxed_sub(args..., - concat_trees_right_mut_visitor<Node>{}, - ec, - el, - lpos, - tpos, - er); - } -}; - -template <typename Node> -relaxed_pos<Node> concat_trees_mut(edit_type<Node> ec, - edit_type<Node> el, - Node* lroot, - shift_t lshift, - size_t lsize, - Node* ltail, - count_t ltcount, - edit_type<Node> er, - Node* rroot, - shift_t rshift, - size_t rsize) -{ - return visit_maybe_relaxed_sub(lroot, - lshift, - lsize, - concat_trees_left_mut_visitor<Node>{}, - ec, - el, - make_leaf_pos(ltail, ltcount), - er, - rroot, - rshift, - rsize) - .realize_e(ec); -} - -template <typename Node> -relaxed_pos<Node> concat_trees_mut(edit_type<Node> ec, - edit_type<Node> el, - Node* ltail, - count_t ltcount, - edit_type<Node> er, - Node* rroot, - shift_t rshift, - size_t rsize) -{ - return make_singleton_regular_sub_pos(ltail, ltcount) - .visit(concat_trees_left_mut_visitor<Node>{}, - ec, - el, - empty_leaf_pos<Node>{}, - er, - rroot, - rshift, - rsize) - .realize_e(ec); -} - -} // namespace rbts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/rbts/position.hpp b/third_party/immer/immer/detail/rbts/position.hpp deleted file mode 100644 index e9472b294088..000000000000 --- a/third_party/immer/immer/detail/rbts/position.hpp +++ /dev/null @@ -1,1977 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/config.hpp> -#include <immer/detail/rbts/bits.hpp> - -#include <cassert> -#include <type_traits> -#include <utility> - -namespace immer { -namespace detail { -namespace rbts { - -template <typename Pos> -constexpr auto bits = std::decay_t<Pos>::node_t::bits; - -template <typename Pos> -constexpr auto bits_leaf = std::decay_t<Pos>::node_t::bits_leaf; - -template <typename Pos> -using node_type = typename std::decay<Pos>::type::node_t; - -template <typename Pos> -using edit_type = typename std::decay<Pos>::type::node_t::edit_t; - -template <typename NodeT> -struct empty_regular_pos -{ - using node_t = NodeT; - node_t* node_; - - count_t count() const { return 0; } - node_t* node() const { return node_; } - shift_t shift() const { return 0; } - size_t size() const { return 0; } - - template <typename Visitor, typename... Args> - void each(Visitor, Args&&...) - {} - template <typename Visitor, typename... Args> - bool each_pred(Visitor, Args&&...) - { - return true; - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_regular(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT> -empty_regular_pos<NodeT> make_empty_regular_pos(NodeT* node) -{ - return {node}; -} - -template <typename NodeT> -struct empty_leaf_pos -{ - using node_t = NodeT; - node_t* node_; - - count_t count() const { return 0; } - node_t* node() const { return node_; } - shift_t shift() const { return 0; } - size_t size() const { return 0; } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_leaf(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT> -empty_leaf_pos<NodeT> make_empty_leaf_pos(NodeT* node) -{ - assert(node); - return {node}; -} - -template <typename NodeT> -struct leaf_pos -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using node_t = NodeT; - node_t* node_; - size_t size_; - - count_t count() const { return index(size_ - 1) + 1; } - node_t* node() const { return node_; } - size_t size() const { return size_; } - shift_t shift() const { return 0; } - count_t index(size_t idx) const { return idx & mask<BL>; } - count_t subindex(size_t idx) const { return idx; } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_leaf(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT> -leaf_pos<NodeT> make_leaf_pos(NodeT* node, size_t size) -{ - assert(node); - assert(size > 0); - return {node, size}; -} - -template <typename NodeT> -struct leaf_sub_pos -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using node_t = NodeT; - node_t* node_; - count_t count_; - - count_t count() const { return count_; } - node_t* node() const { return node_; } - size_t size() const { return count_; } - shift_t shift() const { return 0; } - count_t index(size_t idx) const { return idx & mask<BL>; } - count_t subindex(size_t idx) const { return idx; } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_leaf(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT> -leaf_sub_pos<NodeT> make_leaf_sub_pos(NodeT* node, count_t count) -{ - assert(node); - assert(count <= branches<NodeT::bits_leaf>); - return {node, count}; -} - -template <typename NodeT> -struct leaf_descent_pos -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using node_t = NodeT; - node_t* node_; - - node_t* node() const { return node_; } - shift_t shift() const { return 0; } - count_t index(size_t idx) const { return idx & mask<BL>; } - - template <typename... Args> - decltype(auto) descend(Args&&...) - {} - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_leaf(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT> -leaf_descent_pos<NodeT> make_leaf_descent_pos(NodeT* node) -{ - assert(node); - return {node}; -} - -template <typename NodeT> -struct full_leaf_pos -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using node_t = NodeT; - node_t* node_; - - count_t count() const { return branches<BL>; } - node_t* node() const { return node_; } - size_t size() const { return branches<BL>; } - shift_t shift() const { return 0; } - count_t index(size_t idx) const { return idx & mask<BL>; } - count_t subindex(size_t idx) const { return idx; } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_leaf(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT> -full_leaf_pos<NodeT> make_full_leaf_pos(NodeT* node) -{ - assert(node); - return {node}; -} - -template <typename NodeT> -struct regular_pos -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using node_t = NodeT; - node_t* node_; - shift_t shift_; - size_t size_; - - count_t count() const { return index(size_ - 1) + 1; } - node_t* node() const { return node_; } - size_t size() const { return size_; } - shift_t shift() const { return shift_; } - count_t index(size_t idx) const { return (idx >> shift_) & mask<B>; } - count_t subindex(size_t idx) const { return idx >> shift_; } - size_t this_size() const - { - return ((size_ - 1) & ~(~size_t{} << (shift_ + B))) + 1; - } - - template <typename Visitor, typename... Args> - void each(Visitor v, Args&&... args) - { - return each_regular(*this, v, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred(Visitor v, Args&&... args) - { - return each_pred_regular(*this, v, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred_zip(Visitor v, node_t* other, Args&&... args) - { - return each_pred_zip_regular(*this, v, other, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred_i(Visitor v, count_t i, count_t n, Args&&... args) - { - return each_pred_i_regular(*this, v, i, n, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred_right(Visitor v, count_t start, Args&&... args) - { - return each_pred_right_regular(*this, v, start, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred_left(Visitor v, count_t n, Args&&... args) - { - return each_pred_left_regular(*this, v, n, args...); - } - - template <typename Visitor, typename... Args> - void each_i(Visitor v, count_t i, count_t n, Args&&... args) - { - return each_i_regular(*this, v, i, n, args...); - } - - template <typename Visitor, typename... Args> - void each_right(Visitor v, count_t start, Args&&... args) - { - return each_right_regular(*this, v, start, args...); - } - - template <typename Visitor, typename... Args> - void each_left(Visitor v, count_t n, Args&&... args) - { - return each_left_regular(*this, v, n, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) towards(Visitor v, size_t idx, Args&&... args) - { - return towards_oh_ch_regular( - *this, v, idx, index(idx), count(), args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) - towards_oh(Visitor v, size_t idx, count_t offset_hint, Args&&... args) - { - return towards_oh_ch_regular( - *this, v, idx, offset_hint, count(), args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) towards_oh_ch(Visitor v, - size_t idx, - count_t offset_hint, - count_t count_hint, - Args&&... args) - { - return towards_oh_ch_regular( - *this, v, idx, offset_hint, count(), args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) - towards_sub_oh(Visitor v, size_t idx, count_t offset_hint, Args&&... args) - { - return towards_sub_oh_regular(*this, v, idx, offset_hint, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) last_oh(Visitor v, count_t offset_hint, Args&&... args) - { - return last_oh_regular(*this, v, offset_hint, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_regular(*this, std::forward<Args>(args)...); - } -}; - -template <typename Pos, typename Visitor, typename... Args> -void each_regular(Pos&& p, Visitor v, Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - auto n = p.node()->inner(); - auto last = p.count() - 1; - auto e = n + last; - if (p.shift() == BL) { - for (; n != e; ++n) { - IMMER_PREFETCH(n + 1); - make_full_leaf_pos(*n).visit(v, args...); - } - make_leaf_pos(*n, p.size()).visit(v, args...); - } else { - auto ss = p.shift() - B; - for (; n != e; ++n) - make_full_pos(*n, ss).visit(v, args...); - make_regular_pos(*n, ss, p.size()).visit(v, args...); - } -} - -template <typename Pos, typename Visitor, typename... Args> -bool each_pred_regular(Pos&& p, Visitor v, Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - auto n = p.node()->inner(); - auto last = p.count() - 1; - auto e = n + last; - if (p.shift() == BL) { - for (; n != e; ++n) { - IMMER_PREFETCH(n + 1); - if (!make_full_leaf_pos(*n).visit(v, args...)) - return false; - } - return make_leaf_pos(*n, p.size()).visit(v, args...); - } else { - auto ss = p.shift() - B; - for (; n != e; ++n) - if (!make_full_pos(*n, ss).visit(v, args...)) - return false; - return make_regular_pos(*n, ss, p.size()).visit(v, args...); - } -} - -template <typename Pos, typename Visitor, typename... Args> -bool each_pred_zip_regular(Pos&& p, - Visitor v, - node_type<Pos>* other, - Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - - auto n = p.node()->inner(); - auto n2 = other->inner(); - auto last = p.count() - 1; - auto e = n + last; - if (p.shift() == BL) { - for (; n != e; ++n, ++n2) { - IMMER_PREFETCH(n + 1); - IMMER_PREFETCH(n2 + 1); - if (!make_full_leaf_pos(*n).visit(v, *n2, args...)) - return false; - } - return make_leaf_pos(*n, p.size()).visit(v, *n2, args...); - } else { - auto ss = p.shift() - B; - for (; n != e; ++n, ++n2) - if (!make_full_pos(*n, ss).visit(v, *n2, args...)) - return false; - return make_regular_pos(*n, ss, p.size()).visit(v, *n2, args...); - } -} - -template <typename Pos, typename Visitor, typename... Args> -bool each_pred_i_regular( - Pos&& p, Visitor v, count_t f, count_t l, Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - - if (p.shift() == BL) { - if (l > f) { - if (l < p.count()) { - auto n = p.node()->inner() + f; - auto e = p.node()->inner() + l; - for (; n < e; ++n) { - IMMER_PREFETCH(n + 1); - if (!make_full_leaf_pos(*n).visit(v, args...)) - return false; - } - } else { - auto n = p.node()->inner() + f; - auto e = p.node()->inner() + l - 1; - for (; n < e; ++n) { - IMMER_PREFETCH(n + 1); - if (!make_full_leaf_pos(*n).visit(v, args...)) - return false; - } - if (!make_leaf_pos(*n, p.size()).visit(v, args...)) - return false; - } - } - } else { - if (l > f) { - auto ss = p.shift() - B; - if (l < p.count()) { - auto n = p.node()->inner() + f; - auto e = p.node()->inner() + l; - for (; n < e; ++n) - if (!make_full_pos(*n, ss).visit(v, args...)) - return false; - } else { - auto n = p.node()->inner() + f; - auto e = p.node()->inner() + l - 1; - for (; n < e; ++n) - if (!make_full_pos(*n, ss).visit(v, args...)) - return false; - if (!make_regular_pos(*n, ss, p.size()).visit(v, args...)) - return false; - } - } - } - return true; -} - -template <typename Pos, typename Visitor, typename... Args> -bool each_pred_left_regular(Pos&& p, Visitor v, count_t last, Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - assert(last < p.count()); - if (p.shift() == BL) { - auto n = p.node()->inner(); - auto e = n + last; - for (; n != e; ++n) { - IMMER_PREFETCH(n + 1); - if (!make_full_leaf_pos(*n).visit(v, args...)) - return false; - } - } else { - auto n = p.node()->inner(); - auto e = n + last; - auto ss = p.shift() - B; - for (; n != e; ++n) - if (!make_full_pos(*n, ss).visit(v, args...)) - return false; - } - return true; -} - -template <typename Pos, typename Visitor, typename... Args> -bool each_pred_right_regular(Pos&& p, Visitor v, count_t start, Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - - if (p.shift() == BL) { - auto n = p.node()->inner() + start; - auto last = p.count() - 1; - auto e = p.node()->inner() + last; - if (n <= e) { - for (; n != e; ++n) { - IMMER_PREFETCH(n + 1); - if (!make_full_leaf_pos(*n).visit(v, args...)) - return false; - } - if (!make_leaf_pos(*n, p.size()).visit(v, args...)) - return false; - } - } else { - auto n = p.node()->inner() + start; - auto last = p.count() - 1; - auto e = p.node()->inner() + last; - auto ss = p.shift() - B; - if (n <= e) { - for (; n != e; ++n) - if (!make_full_pos(*n, ss).visit(v, args...)) - return false; - if (!make_regular_pos(*n, ss, p.size()).visit(v, args...)) - return false; - } - } - return true; -} - -template <typename Pos, typename Visitor, typename... Args> -void each_i_regular(Pos&& p, Visitor v, count_t f, count_t l, Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - - if (p.shift() == BL) { - if (l > f) { - if (l < p.count()) { - auto n = p.node()->inner() + f; - auto e = p.node()->inner() + l; - for (; n < e; ++n) { - IMMER_PREFETCH(n + 1); - make_full_leaf_pos(*n).visit(v, args...); - } - } else { - auto n = p.node()->inner() + f; - auto e = p.node()->inner() + l - 1; - for (; n < e; ++n) { - IMMER_PREFETCH(n + 1); - make_full_leaf_pos(*n).visit(v, args...); - } - make_leaf_pos(*n, p.size()).visit(v, args...); - } - } - } else { - if (l > f) { - auto ss = p.shift() - B; - if (l < p.count()) { - auto n = p.node()->inner() + f; - auto e = p.node()->inner() + l; - for (; n < e; ++n) - make_full_pos(*n, ss).visit(v, args...); - } else { - auto n = p.node()->inner() + f; - auto e = p.node()->inner() + l - 1; - for (; n < e; ++n) - make_full_pos(*n, ss).visit(v, args...); - make_regular_pos(*n, ss, p.size()).visit(v, args...); - } - } - } -} - -template <typename Pos, typename Visitor, typename... Args> -void each_left_regular(Pos&& p, Visitor v, count_t last, Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - assert(last < p.count()); - if (p.shift() == BL) { - auto n = p.node()->inner(); - auto e = n + last; - for (; n != e; ++n) { - IMMER_PREFETCH(n + 1); - make_full_leaf_pos(*n).visit(v, args...); - } - } else { - auto n = p.node()->inner(); - auto e = n + last; - auto ss = p.shift() - B; - for (; n != e; ++n) - make_full_pos(*n, ss).visit(v, args...); - } -} - -template <typename Pos, typename Visitor, typename... Args> -void each_right_regular(Pos&& p, Visitor v, count_t start, Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - - if (p.shift() == BL) { - auto n = p.node()->inner() + start; - auto last = p.count() - 1; - auto e = p.node()->inner() + last; - if (n <= e) { - for (; n != e; ++n) { - IMMER_PREFETCH(n + 1); - make_full_leaf_pos(*n).visit(v, args...); - } - make_leaf_pos(*n, p.size()).visit(v, args...); - } - } else { - auto n = p.node()->inner() + start; - auto last = p.count() - 1; - auto e = p.node()->inner() + last; - auto ss = p.shift() - B; - if (n <= e) { - for (; n != e; ++n) - make_full_pos(*n, ss).visit(v, args...); - make_regular_pos(*n, ss, p.size()).visit(v, args...); - } - } -} - -template <typename Pos, typename Visitor, typename... Args> -decltype(auto) towards_oh_ch_regular(Pos&& p, - Visitor v, - size_t idx, - count_t offset_hint, - count_t count_hint, - Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - assert(offset_hint == p.index(idx)); - assert(count_hint == p.count()); - auto is_leaf = p.shift() == BL; - auto child = p.node()->inner()[offset_hint]; - auto is_full = offset_hint + 1 != count_hint; - return is_full - ? (is_leaf ? make_full_leaf_pos(child).visit(v, idx, args...) - : make_full_pos(child, p.shift() - B) - .visit(v, idx, args...)) - : (is_leaf - ? make_leaf_pos(child, p.size()).visit(v, idx, args...) - : make_regular_pos(child, p.shift() - B, p.size()) - .visit(v, idx, args...)); -} - -template <typename Pos, typename Visitor, typename... Args> -decltype(auto) towards_sub_oh_regular( - Pos&& p, Visitor v, size_t idx, count_t offset_hint, Args&&... args) -{ - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - assert(offset_hint == p.index(idx)); - auto is_leaf = p.shift() == BL; - auto child = p.node()->inner()[offset_hint]; - auto lsize = offset_hint << p.shift(); - auto size = p.this_size(); - auto is_full = (size - lsize) >= (size_t{1} << p.shift()); - return is_full - ? (is_leaf - ? make_full_leaf_pos(child).visit(v, idx - lsize, args...) - : make_full_pos(child, p.shift() - B) - .visit(v, idx - lsize, args...)) - : (is_leaf - ? make_leaf_sub_pos(child, size - lsize) - .visit(v, idx - lsize, args...) - : make_regular_sub_pos(child, p.shift() - B, size - lsize) - .visit(v, idx - lsize, args...)); -} - -template <typename Pos, typename Visitor, typename... Args> -decltype(auto) -last_oh_regular(Pos&& p, Visitor v, count_t offset_hint, Args&&... args) -{ - assert(offset_hint == p.count() - 1); - constexpr auto B = bits<Pos>; - constexpr auto BL = bits_leaf<Pos>; - auto child = p.node()->inner()[offset_hint]; - auto is_leaf = p.shift() == BL; - return is_leaf ? make_leaf_pos(child, p.size()).visit(v, args...) - : make_regular_pos(child, p.shift() - B, p.size()) - .visit(v, args...); -} - -template <typename NodeT> -regular_pos<NodeT> make_regular_pos(NodeT* node, shift_t shift, size_t size) -{ - assert(node); - assert(shift >= NodeT::bits_leaf); - assert(size > 0); - return {node, shift, size}; -} - -struct null_sub_pos -{ - auto node() const { return nullptr; } - - template <typename Visitor, typename... Args> - void each_sub(Visitor, Args&&...) - {} - template <typename Visitor, typename... Args> - void each_right_sub(Visitor, Args&&...) - {} - template <typename Visitor, typename... Args> - void each_left_sub(Visitor, Args&&...) - {} - template <typename Visitor, typename... Args> - void visit(Visitor, Args&&...) - {} -}; - -template <typename NodeT> -struct singleton_regular_sub_pos -{ - // this is a fake regular pos made out of a single child... useful - // to treat a single leaf node as a whole tree - - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using node_t = NodeT; - node_t* leaf_; - count_t count_; - - count_t count() const { return 1; } - node_t* node() const { return nullptr; } - size_t size() const { return count_; } - shift_t shift() const { return BL; } - count_t index(size_t idx) const { return 0; } - count_t subindex(size_t idx) const { return 0; } - size_t size_before(count_t offset) const { return 0; } - size_t this_size() const { return count_; } - size_t size(count_t offset) { return count_; } - - template <typename Visitor, typename... Args> - void each_left_sub(Visitor v, Args&&... args) - {} - template <typename Visitor, typename... Args> - void each(Visitor v, Args&&... args) - {} - - template <typename Visitor, typename... Args> - decltype(auto) last_sub(Visitor v, Args&&... args) - { - return make_leaf_sub_pos(leaf_, count_).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_regular(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT> -auto make_singleton_regular_sub_pos(NodeT* leaf, count_t count) -{ - assert(leaf); - IMMER_ASSERT_TAGGED(leaf->kind() == NodeT::kind_t::leaf); - assert(count > 0); - return singleton_regular_sub_pos<NodeT>{leaf, count}; -} - -template <typename NodeT> -struct regular_sub_pos -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using node_t = NodeT; - node_t* node_; - shift_t shift_; - size_t size_; - - count_t count() const { return subindex(size_ - 1) + 1; } - node_t* node() const { return node_; } - size_t size() const { return size_; } - shift_t shift() const { return shift_; } - count_t index(size_t idx) const { return (idx >> shift_) & mask<B>; } - count_t subindex(size_t idx) const { return idx >> shift_; } - size_t size_before(count_t offset) const { return offset << shift_; } - size_t this_size() const { return size_; } - - auto size(count_t offset) - { - return offset == subindex(size_ - 1) ? size_ - size_before(offset) - : size_t{1} << shift_; - } - - auto size_sbh(count_t offset, size_t size_before_hint) - { - assert(size_before_hint == size_before(offset)); - return offset == subindex(size_ - 1) ? size_ - size_before_hint - : size_t{1} << shift_; - } - - void copy_sizes(count_t offset, count_t n, size_t init, size_t* sizes) - { - if (n) { - auto last = offset + n - 1; - auto e = sizes + n - 1; - for (; sizes != e; ++sizes) - init = *sizes = init + (size_t{1} << shift_); - *sizes = init + size(last); - } - } - - template <typename Visitor, typename... Args> - void each(Visitor v, Args&&... args) - { - return each_regular(*this, v, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred(Visitor v, Args&&... args) - { - return each_pred_regular(*this, v, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred_zip(Visitor v, node_t* other, Args&&... args) - { - return each_pred_zip_regular(*this, v, other, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred_i(Visitor v, count_t i, count_t n, Args&&... args) - { - return each_pred_i_regular(*this, v, i, n, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred_right(Visitor v, count_t start, Args&&... args) - { - return each_pred_right_regular(*this, v, start, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred_left(Visitor v, count_t last, Args&&... args) - { - return each_pred_left_regular(*this, v, last, args...); - } - - template <typename Visitor, typename... Args> - void each_i(Visitor v, count_t i, count_t n, Args&&... args) - { - return each_i_regular(*this, v, i, n, args...); - } - - template <typename Visitor, typename... Args> - void each_right(Visitor v, count_t start, Args&&... args) - { - return each_right_regular(*this, v, start, args...); - } - - template <typename Visitor, typename... Args> - void each_left(Visitor v, count_t last, Args&&... args) - { - return each_left_regular(*this, v, last, args...); - } - - template <typename Visitor, typename... Args> - void each_right_sub_(Visitor v, count_t i, Args&&... args) - { - auto last = count() - 1; - auto lsize = size_ - (last << shift_); - auto n = node()->inner() + i; - auto e = node()->inner() + last; - if (shift() == BL) { - for (; n != e; ++n) { - IMMER_PREFETCH(n + 1); - make_full_leaf_pos(*n).visit(v, args...); - } - make_leaf_sub_pos(*n, lsize).visit(v, args...); - } else { - auto ss = shift_ - B; - for (; n != e; ++n) - make_full_pos(*n, ss).visit(v, args...); - make_regular_sub_pos(*n, ss, lsize).visit(v, args...); - } - } - - template <typename Visitor, typename... Args> - void each_sub(Visitor v, Args&&... args) - { - each_right_sub_(v, 0, args...); - } - - template <typename Visitor, typename... Args> - void each_right_sub(Visitor v, Args&&... args) - { - if (count() > 1) - each_right_sub_(v, 1, args...); - } - - template <typename Visitor, typename... Args> - void each_left_sub(Visitor v, Args&&... args) - { - each_left(v, count() - 1, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) towards(Visitor v, size_t idx, Args&&... args) - { - return towards_oh_ch_regular( - *this, v, idx, index(idx), count(), args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) - towards_oh(Visitor v, size_t idx, count_t offset_hint, Args&&... args) - { - return towards_oh_ch_regular( - *this, v, idx, offset_hint, count(), args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) towards_oh_ch(Visitor v, - size_t idx, - count_t offset_hint, - count_t count_hint, - Args&&... args) - { - return towards_oh_ch_regular( - *this, v, idx, offset_hint, count(), args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) - towards_sub_oh(Visitor v, size_t idx, count_t offset_hint, Args&&... args) - { - return towards_sub_oh_regular(*this, v, idx, offset_hint, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) last_oh(Visitor v, count_t offset_hint, Args&&... args) - { - return last_oh_regular(*this, v, offset_hint, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) last_sub(Visitor v, Args&&... args) - { - auto offset = count() - 1; - auto child = node_->inner()[offset]; - auto is_leaf = shift_ == BL; - auto lsize = size_ - (offset << shift_); - return is_leaf ? make_leaf_sub_pos(child, lsize).visit(v, args...) - : make_regular_sub_pos(child, shift_ - B, lsize) - .visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) first_sub(Visitor v, Args&&... args) - { - auto is_leaf = shift_ == BL; - auto child = node_->inner()[0]; - auto is_full = size_ >= (size_t{1} << shift_); - return is_full - ? (is_leaf - ? make_full_leaf_pos(child).visit(v, args...) - : make_full_pos(child, shift_ - B).visit(v, args...)) - : (is_leaf - ? make_leaf_sub_pos(child, size_).visit(v, args...) - : make_regular_sub_pos(child, shift_ - B, size_) - .visit(v, args...)); - } - - template <typename Visitor, typename... Args> - decltype(auto) first_sub_leaf(Visitor v, Args&&... args) - { - assert(shift_ == BL); - auto child = node_->inner()[0]; - auto is_full = size_ >= branches<BL>; - return is_full ? make_full_leaf_pos(child).visit(v, args...) - : make_leaf_sub_pos(child, size_).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) first_sub_inner(Visitor v, Args&&... args) - { - assert(shift_ >= BL); - auto child = node_->inner()[0]; - auto is_full = size_ >= branches<BL>; - return is_full ? make_full_pos(child, shift_ - B).visit(v, args...) - : make_regular_sub_pos(child, shift_ - B, size_) - .visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) nth_sub(count_t idx, Visitor v, Args&&... args) - { - assert(idx < count()); - auto is_leaf = shift_ == BL; - auto child = node_->inner()[idx]; - auto lsize = size(idx); - auto is_full = idx + 1 < count(); - return is_full - ? (is_leaf - ? make_full_leaf_pos(child).visit(v, args...) - : make_full_pos(child, shift_ - B).visit(v, args...)) - : (is_leaf - ? make_leaf_sub_pos(child, lsize).visit(v, args...) - : make_regular_sub_pos(child, shift_ - B, lsize) - .visit(v, args...)); - } - - template <typename Visitor, typename... Args> - decltype(auto) nth_sub_leaf(count_t idx, Visitor v, Args&&... args) - { - assert(shift_ == BL); - auto child = node_->inner()[idx]; - auto lsize = size(idx); - auto is_full = idx + 1 < count(); - return is_full ? make_full_leaf_pos(child).visit(v, args...) - : make_leaf_sub_pos(child, lsize).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_regular(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT> -regular_sub_pos<NodeT> -make_regular_sub_pos(NodeT* node, shift_t shift, size_t size) -{ - assert(node); - assert(shift >= NodeT::bits_leaf); - assert(size > 0); - assert(size <= (branches<NodeT::bits, size_t> << shift)); - return {node, shift, size}; -} - -template <typename NodeT, - shift_t Shift, - bits_t B = NodeT::bits, - bits_t BL = NodeT::bits_leaf> -struct regular_descent_pos -{ - static_assert(Shift > 0, "not leaf..."); - - using node_t = NodeT; - node_t* node_; - - node_t* node() const { return node_; } - shift_t shift() const { return Shift; } - count_t index(size_t idx) const - { -#if !defined(_MSC_VER) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshift-count-overflow" -#endif - return (idx >> Shift) & mask<B>; -#if !defined(_MSC_VER) -#pragma GCC diagnostic pop -#endif - } - - template <typename Visitor> - decltype(auto) descend(Visitor v, size_t idx) - { - auto offset = index(idx); - auto child = node_->inner()[offset]; - return regular_descent_pos<NodeT, Shift - B>{child}.visit(v, idx); - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_regular(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT, bits_t B, bits_t BL> -struct regular_descent_pos<NodeT, BL, B, BL> -{ - using node_t = NodeT; - node_t* node_; - - node_t* node() const { return node_; } - shift_t shift() const { return BL; } - count_t index(size_t idx) const { return (idx >> BL) & mask<B>; } - - template <typename Visitor> - decltype(auto) descend(Visitor v, size_t idx) - { - auto offset = index(idx); - auto child = node_->inner()[offset]; - return make_leaf_descent_pos(child).visit(v, idx); - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_regular(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT, typename Visitor> -decltype(auto) -visit_regular_descent(NodeT* node, shift_t shift, Visitor v, size_t idx) -{ - constexpr auto B = NodeT::bits; - constexpr auto BL = NodeT::bits_leaf; - assert(node); - assert(shift >= BL); - switch (shift) { - case BL + B * 0: - return regular_descent_pos<NodeT, BL + B * 0>{node}.visit(v, idx); - case BL + B * 1: - return regular_descent_pos<NodeT, BL + B * 1>{node}.visit(v, idx); - case BL + B * 2: - return regular_descent_pos<NodeT, BL + B * 2>{node}.visit(v, idx); - case BL + B * 3: - return regular_descent_pos<NodeT, BL + B * 3>{node}.visit(v, idx); - case BL + B * 4: - return regular_descent_pos<NodeT, BL + B * 4>{node}.visit(v, idx); - case BL + B * 5: - return regular_descent_pos<NodeT, BL + B * 5>{node}.visit(v, idx); -#if IMMER_DESCENT_DEEP - default: - for (auto level = shift; level != endshift<B, BL>; level -= B) - node = node->inner()[(idx >> level) & mask<B>]; - return make_leaf_descent_pos(node).visit(v, idx); -#endif // IMMER_DEEP_DESCENT - } - IMMER_UNREACHABLE; -} - -template <typename NodeT> -struct full_pos -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using node_t = NodeT; - node_t* node_; - shift_t shift_; - - count_t count() const { return branches<B>; } - node_t* node() const { return node_; } - size_t size() const { return branches<B> << shift_; } - shift_t shift() const { return shift_; } - count_t index(size_t idx) const { return (idx >> shift_) & mask<B>; } - count_t subindex(size_t idx) const { return idx >> shift_; } - size_t size(count_t offset) const { return size_t{1} << shift_; } - size_t size_sbh(count_t offset, size_t) const - { - return size_t{1} << shift_; - } - size_t size_before(count_t offset) const { return offset << shift_; } - - void copy_sizes(count_t offset, count_t n, size_t init, size_t* sizes) - { - auto e = sizes + n; - for (; sizes != e; ++sizes) - init = *sizes = init + (size_t{1} << shift_); - } - - template <typename Visitor, typename... Args> - void each(Visitor v, Args&&... args) - { - auto p = node_->inner(); - auto e = p + branches<B>; - if (shift_ == BL) { - for (; p != e; ++p) { - IMMER_PREFETCH(p + 1); - make_full_leaf_pos(*p).visit(v, args...); - } - } else { - auto ss = shift_ - B; - for (; p != e; ++p) - make_full_pos(*p, ss).visit(v, args...); - } - } - - template <typename Visitor, typename... Args> - bool each_pred(Visitor v, Args&&... args) - { - auto p = node_->inner(); - auto e = p + branches<B>; - if (shift_ == BL) { - for (; p != e; ++p) { - IMMER_PREFETCH(p + 1); - if (!make_full_leaf_pos(*p).visit(v, args...)) - return false; - } - } else { - auto ss = shift_ - B; - for (; p != e; ++p) - if (!make_full_pos(*p, ss).visit(v, args...)) - return false; - } - return true; - } - - template <typename Visitor, typename... Args> - bool each_pred_zip(Visitor v, node_t* other, Args&&... args) - { - auto p = node_->inner(); - auto p2 = other->inner(); - auto e = p + branches<B>; - if (shift_ == BL) { - for (; p != e; ++p, ++p2) { - IMMER_PREFETCH(p + 1); - if (!make_full_leaf_pos(*p).visit(v, *p2, args...)) - return false; - } - } else { - auto ss = shift_ - B; - for (; p != e; ++p, ++p2) - if (!make_full_pos(*p, ss).visit(v, *p2, args...)) - return false; - } - return true; - } - - template <typename Visitor, typename... Args> - bool each_pred_i(Visitor v, count_t i, count_t n, Args&&... args) - { - auto p = node_->inner() + i; - auto e = node_->inner() + n; - if (shift_ == BL) { - for (; p != e; ++p) { - IMMER_PREFETCH(p + 1); - if (!make_full_leaf_pos(*p).visit(v, args...)) - return false; - } - } else { - auto ss = shift_ - B; - for (; p != e; ++p) - if (!make_full_pos(*p, ss).visit(v, args...)) - return false; - } - return true; - } - - template <typename Visitor, typename... Args> - void each_i(Visitor v, count_t i, count_t n, Args&&... args) - { - auto p = node_->inner() + i; - auto e = node_->inner() + n; - if (shift_ == BL) { - for (; p != e; ++p) { - IMMER_PREFETCH(p + 1); - make_full_leaf_pos(*p).visit(v, args...); - } - } else { - auto ss = shift_ - B; - for (; p != e; ++p) - make_full_pos(*p, ss).visit(v, args...); - } - } - - template <typename Visitor, typename... Args> - bool each_pred_right(Visitor v, count_t start, Args&&... args) - { - return each_pred_i(v, start, branches<B>, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred_left(Visitor v, count_t last, Args&&... args) - { - return each_pred_i(v, 0, last, args...); - } - - template <typename Visitor, typename... Args> - void each_sub(Visitor v, Args&&... args) - { - each(v, args...); - } - - template <typename Visitor, typename... Args> - void each_left_sub(Visitor v, Args&&... args) - { - each_i(v, 0, branches<B> - 1, args...); - } - - template <typename Visitor, typename... Args> - void each_right_sub(Visitor v, Args&&... args) - { - each_i(v, 1, branches<B>, args...); - } - - template <typename Visitor, typename... Args> - void each_right(Visitor v, count_t start, Args&&... args) - { - each_i(v, start, branches<B>, args...); - } - - template <typename Visitor, typename... Args> - void each_left(Visitor v, count_t last, Args&&... args) - { - each_i(v, 0, last, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) towards(Visitor v, size_t idx, Args&&... args) - { - return towards_oh(v, idx, index(idx), args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) towards_oh_ch( - Visitor v, size_t idx, count_t offset_hint, count_t, Args&&... args) - { - return towards_oh(v, idx, offset_hint, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) - towards_oh(Visitor v, size_t idx, count_t offset_hint, Args&&... args) - { - assert(offset_hint == index(idx)); - auto is_leaf = shift_ == BL; - auto child = node_->inner()[offset_hint]; - return is_leaf - ? make_full_leaf_pos(child).visit(v, idx, args...) - : make_full_pos(child, shift_ - B).visit(v, idx, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) - towards_sub_oh(Visitor v, size_t idx, count_t offset_hint, Args&&... args) - { - assert(offset_hint == index(idx)); - auto is_leaf = shift_ == BL; - auto child = node_->inner()[offset_hint]; - auto lsize = offset_hint << shift_; - return is_leaf - ? make_full_leaf_pos(child).visit(v, idx - lsize, args...) - : make_full_pos(child, shift_ - B) - .visit(v, idx - lsize, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) first_sub(Visitor v, Args&&... args) - { - auto is_leaf = shift_ == BL; - auto child = node_->inner()[0]; - return is_leaf ? make_full_leaf_pos(child).visit(v, args...) - : make_full_pos(child, shift_ - B).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) first_sub_leaf(Visitor v, Args&&... args) - { - assert(shift_ == BL); - auto child = node_->inner()[0]; - return make_full_leaf_pos(child).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) first_sub_inner(Visitor v, Args&&... args) - { - assert(shift_ >= BL); - auto child = node_->inner()[0]; - return make_full_pos(child, shift_ - B).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) nth_sub(count_t idx, Visitor v, Args&&... args) - { - assert(idx < count()); - auto is_leaf = shift_ == BL; - auto child = node_->inner()[idx]; - return is_leaf ? make_full_leaf_pos(child).visit(v, args...) - : make_full_pos(child, shift_ - B).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) nth_sub_leaf(count_t idx, Visitor v, Args&&... args) - { - assert(shift_ == BL); - assert(idx < count()); - auto child = node_->inner()[idx]; - return make_full_leaf_pos(child).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_regular(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT> -full_pos<NodeT> make_full_pos(NodeT* node, shift_t shift) -{ - assert(node); - assert(shift >= NodeT::bits_leaf); - return {node, shift}; -} - -template <typename NodeT> -struct relaxed_pos -{ - static constexpr auto B = NodeT::bits; - static constexpr auto BL = NodeT::bits_leaf; - - using node_t = NodeT; - using relaxed_t = typename NodeT::relaxed_t; - node_t* node_; - shift_t shift_; - relaxed_t* relaxed_; - - count_t count() const { return relaxed_->d.count; } - node_t* node() const { return node_; } - size_t size() const { return relaxed_->d.sizes[relaxed_->d.count - 1]; } - shift_t shift() const { return shift_; } - count_t subindex(size_t idx) const { return index(idx); } - relaxed_t* relaxed() const { return relaxed_; } - - size_t size_before(count_t offset) const - { - return offset ? relaxed_->d.sizes[offset - 1] : 0; - } - - size_t size(count_t offset) const - { - return size_sbh(offset, size_before(offset)); - } - - size_t size_sbh(count_t offset, size_t size_before_hint) const - { - assert(size_before_hint == size_before(offset)); - return relaxed_->d.sizes[offset] - size_before_hint; - } - - count_t index(size_t idx) const - { - auto offset = idx >> shift_; - while (relaxed_->d.sizes[offset] <= idx) - ++offset; - return offset; - } - - void copy_sizes(count_t offset, count_t n, size_t init, size_t* sizes) - { - auto e = sizes + n; - auto prev = size_before(offset); - auto these = relaxed_->d.sizes + offset; - for (; sizes != e; ++sizes, ++these) { - auto this_size = *these; - init = *sizes = init + (this_size - prev); - prev = this_size; - } - } - - template <typename Visitor, typename... Args> - void each(Visitor v, Args&&... args) - { - each_left(v, relaxed_->d.count, args...); - } - - template <typename Visitor, typename... Args> - bool each_pred(Visitor v, Args&&... args) - { - auto p = node_->inner(); - auto s = size_t{}; - auto n = count(); - if (shift_ == BL) { - for (auto i = count_t{0}; i < n; ++i) { - IMMER_PREFETCH(p + i + 1); - if (!make_leaf_sub_pos(p[i], relaxed_->d.sizes[i] - s) - .visit(v, args...)) - return false; - s = relaxed_->d.sizes[i]; - } - } else { - auto ss = shift_ - B; - for (auto i = count_t{0}; i < n; ++i) { - if (!visit_maybe_relaxed_sub( - p[i], ss, relaxed_->d.sizes[i] - s, v, args...)) - return false; - s = relaxed_->d.sizes[i]; - } - } - return true; - } - - template <typename Visitor, typename... Args> - bool each_pred_i(Visitor v, count_t i, count_t n, Args&&... args) - { - if (shift_ == BL) { - auto p = node_->inner(); - auto s = i > 0 ? relaxed_->d.sizes[i - 1] : 0; - for (; i < n; ++i) { - IMMER_PREFETCH(p + i + 1); - if (!make_leaf_sub_pos(p[i], relaxed_->d.sizes[i] - s) - .visit(v, args...)) - return false; - s = relaxed_->d.sizes[i]; - } - } else { - auto p = node_->inner(); - auto s = i > 0 ? relaxed_->d.sizes[i - 1] : 0; - auto ss = shift_ - B; - for (; i < n; ++i) { - if (!visit_maybe_relaxed_sub( - p[i], ss, relaxed_->d.sizes[i] - s, v, args...)) - return false; - s = relaxed_->d.sizes[i]; - } - } - return true; - } - - template <typename Visitor, typename... Args> - bool each_pred_left(Visitor v, count_t n, Args&&... args) - { - auto p = node_->inner(); - auto s = size_t{}; - if (shift_ == BL) { - for (auto i = count_t{0}; i < n; ++i) { - IMMER_PREFETCH(p + i + 1); - if (!make_leaf_sub_pos(p[i], relaxed_->d.sizes[i] - s) - .visit(v, args...)) - return false; - s = relaxed_->d.sizes[i]; - } - } else { - auto ss = shift_ - B; - for (auto i = count_t{0}; i < n; ++i) { - if (!visit_maybe_relaxed_sub( - p[i], ss, relaxed_->d.sizes[i] - s, v, args...)) - return false; - s = relaxed_->d.sizes[i]; - } - } - return true; - } - - template <typename Visitor, typename... Args> - bool each_pred_right(Visitor v, count_t start, Args&&... args) - { - assert(start > 0); - assert(start <= relaxed_->d.count); - auto s = relaxed_->d.sizes[start - 1]; - auto p = node_->inner(); - if (shift_ == BL) { - for (auto i = start; i < relaxed_->d.count; ++i) { - IMMER_PREFETCH(p + i + 1); - if (!make_leaf_sub_pos(p[i], relaxed_->d.sizes[i] - s) - .visit(v, args...)) - return false; - s = relaxed_->d.sizes[i]; - } - } else { - auto ss = shift_ - B; - for (auto i = start; i < relaxed_->d.count; ++i) { - if (!visit_maybe_relaxed_sub( - p[i], ss, relaxed_->d.sizes[i] - s, v, args...)) - return false; - s = relaxed_->d.sizes[i]; - } - } - return true; - } - - template <typename Visitor, typename... Args> - void each_i(Visitor v, count_t i, count_t n, Args&&... args) - { - if (shift_ == BL) { - auto p = node_->inner(); - auto s = i > 0 ? relaxed_->d.sizes[i - 1] : 0; - for (; i < n; ++i) { - IMMER_PREFETCH(p + i + 1); - make_leaf_sub_pos(p[i], relaxed_->d.sizes[i] - s) - .visit(v, args...); - s = relaxed_->d.sizes[i]; - } - } else { - auto p = node_->inner(); - auto s = i > 0 ? relaxed_->d.sizes[i - 1] : 0; - auto ss = shift_ - B; - for (; i < n; ++i) { - visit_maybe_relaxed_sub( - p[i], ss, relaxed_->d.sizes[i] - s, v, args...); - s = relaxed_->d.sizes[i]; - } - } - } - - template <typename Visitor, typename... Args> - void each_sub(Visitor v, Args&&... args) - { - each_left(v, relaxed_->d.count, args...); - } - - template <typename Visitor, typename... Args> - void each_left_sub(Visitor v, Args&&... args) - { - each_left(v, relaxed_->d.count - 1, args...); - } - - template <typename Visitor, typename... Args> - void each_left(Visitor v, count_t n, Args&&... args) - { - auto p = node_->inner(); - auto s = size_t{}; - if (shift_ == BL) { - for (auto i = count_t{0}; i < n; ++i) { - IMMER_PREFETCH(p + i + 1); - make_leaf_sub_pos(p[i], relaxed_->d.sizes[i] - s) - .visit(v, args...); - s = relaxed_->d.sizes[i]; - } - } else { - auto ss = shift_ - B; - for (auto i = count_t{0}; i < n; ++i) { - visit_maybe_relaxed_sub( - p[i], ss, relaxed_->d.sizes[i] - s, v, args...); - s = relaxed_->d.sizes[i]; - } - } - } - - template <typename Visitor, typename... Args> - void each_right_sub(Visitor v, Args&&... args) - { - each_right(v, 1, std::forward<Args>(args)...); - } - - template <typename Visitor, typename... Args> - void each_right(Visitor v, count_t start, Args&&... args) - { - assert(start > 0); - assert(start <= relaxed_->d.count); - auto s = relaxed_->d.sizes[start - 1]; - auto p = node_->inner(); - if (shift_ == BL) { - for (auto i = start; i < relaxed_->d.count; ++i) { - IMMER_PREFETCH(p + i + 1); - make_leaf_sub_pos(p[i], relaxed_->d.sizes[i] - s) - .visit(v, args...); - s = relaxed_->d.sizes[i]; - } - } else { - auto ss = shift_ - B; - for (auto i = start; i < relaxed_->d.count; ++i) { - visit_maybe_relaxed_sub( - p[i], ss, relaxed_->d.sizes[i] - s, v, args...); - s = relaxed_->d.sizes[i]; - } - } - } - - template <typename Visitor, typename... Args> - decltype(auto) towards(Visitor v, size_t idx, Args&&... args) - { - return towards_oh(v, idx, subindex(idx), args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) - towards_oh(Visitor v, size_t idx, count_t offset_hint, Args&&... args) - { - assert(offset_hint == index(idx)); - auto left_size = offset_hint ? relaxed_->d.sizes[offset_hint - 1] : 0; - return towards_oh_sbh(v, idx, offset_hint, left_size, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) towards_oh_sbh(Visitor v, - size_t idx, - count_t offset_hint, - size_t left_size_hint, - Args&&... args) - { - return towards_sub_oh_sbh(v, idx, offset_hint, left_size_hint, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) - towards_sub_oh(Visitor v, size_t idx, count_t offset_hint, Args&&... args) - { - assert(offset_hint == index(idx)); - auto left_size = offset_hint ? relaxed_->d.sizes[offset_hint - 1] : 0; - return towards_sub_oh_sbh(v, idx, offset_hint, left_size, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) towards_sub_oh_sbh(Visitor v, - size_t idx, - count_t offset_hint, - size_t left_size_hint, - Args&&... args) - { - assert(offset_hint == index(idx)); - assert(left_size_hint == - (offset_hint ? relaxed_->d.sizes[offset_hint - 1] : 0)); - auto child = node_->inner()[offset_hint]; - auto is_leaf = shift_ == BL; - auto next_size = relaxed_->d.sizes[offset_hint] - left_size_hint; - auto next_idx = idx - left_size_hint; - return is_leaf - ? make_leaf_sub_pos(child, next_size) - .visit(v, next_idx, args...) - : visit_maybe_relaxed_sub( - child, shift_ - B, next_size, v, next_idx, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) last_oh_csh(Visitor v, - count_t offset_hint, - size_t child_size_hint, - Args&&... args) - { - assert(offset_hint == count() - 1); - assert(child_size_hint == size(offset_hint)); - auto child = node_->inner()[offset_hint]; - auto is_leaf = shift_ == BL; - return is_leaf - ? make_leaf_sub_pos(child, child_size_hint).visit(v, args...) - : visit_maybe_relaxed_sub( - child, shift_ - B, child_size_hint, v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) last_sub(Visitor v, Args&&... args) - { - auto offset = relaxed_->d.count - 1; - auto child = node_->inner()[offset]; - auto child_size = size(offset); - auto is_leaf = shift_ == BL; - return is_leaf ? make_leaf_sub_pos(child, child_size).visit(v, args...) - : visit_maybe_relaxed_sub( - child, shift_ - B, child_size, v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) first_sub(Visitor v, Args&&... args) - { - auto child = node_->inner()[0]; - auto child_size = relaxed_->d.sizes[0]; - auto is_leaf = shift_ == BL; - return is_leaf ? make_leaf_sub_pos(child, child_size).visit(v, args...) - : visit_maybe_relaxed_sub( - child, shift_ - B, child_size, v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) first_sub_leaf(Visitor v, Args&&... args) - { - assert(shift_ == BL); - auto child = node_->inner()[0]; - auto child_size = relaxed_->d.sizes[0]; - return make_leaf_sub_pos(child, child_size).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) first_sub_inner(Visitor v, Args&&... args) - { - assert(shift_ > BL); - auto child = node_->inner()[0]; - auto child_size = relaxed_->d.sizes[0]; - return visit_maybe_relaxed_sub( - child, shift_ - B, child_size, v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) nth_sub(count_t offset, Visitor v, Args&&... args) - { - auto child = node_->inner()[offset]; - auto child_size = size(offset); - auto is_leaf = shift_ == BL; - return is_leaf ? make_leaf_sub_pos(child, child_size).visit(v, args...) - : visit_maybe_relaxed_sub( - child, shift_ - B, child_size, v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) nth_sub_leaf(count_t offset, Visitor v, Args&&... args) - { - assert(shift_ == BL); - auto child = node_->inner()[offset]; - auto child_size = size(offset); - return make_leaf_sub_pos(child, child_size).visit(v, args...); - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_relaxed(*this, std::forward<Args>(args)...); - } -}; - -template <typename Pos> -using is_relaxed = std::is_same<relaxed_pos<typename std::decay_t<Pos>::node_t>, - std::decay_t<Pos>>; - -template <typename Pos> -constexpr auto is_relaxed_v = is_relaxed<Pos>::value; - -template <typename NodeT> -relaxed_pos<NodeT> -make_relaxed_pos(NodeT* node, shift_t shift, typename NodeT::relaxed_t* relaxed) -{ - assert(node); - assert(relaxed); - assert(shift >= NodeT::bits_leaf); - return {node, shift, relaxed}; -} - -template <typename NodeT, typename Visitor, typename... Args> -decltype(auto) visit_maybe_relaxed_sub( - NodeT* node, shift_t shift, size_t size, Visitor v, Args&&... args) -{ - assert(node); - auto relaxed = node->relaxed(); - if (relaxed) { - assert(size == relaxed->d.sizes[relaxed->d.count - 1]); - return make_relaxed_pos(node, shift, relaxed) - .visit(v, std::forward<Args>(args)...); - } else { - return make_regular_sub_pos(node, shift, size) - .visit(v, std::forward<Args>(args)...); - } -} - -template <typename NodeT, - shift_t Shift, - bits_t B = NodeT::bits, - bits_t BL = NodeT::bits_leaf> -struct relaxed_descent_pos -{ - static_assert(Shift > 0, "not leaf..."); - - using node_t = NodeT; - using relaxed_t = typename NodeT::relaxed_t; - node_t* node_; - relaxed_t* relaxed_; - - count_t count() const { return relaxed_->d.count; } - node_t* node() const { return node_; } - shift_t shift() const { return Shift; } - size_t size() const { return relaxed_->d.sizes[relaxed_->d.count - 1]; } - - count_t index(size_t idx) const - { - // make gcc happy -#if !defined(_MSC_VER) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wshift-count-overflow" -#endif - auto offset = idx >> Shift; -#if !defined(_MSC_VER) -#pragma GCC diagnostic pop -#endif - while (relaxed_->d.sizes[offset] <= idx) - ++offset; - return offset; - } - - template <typename Visitor> - decltype(auto) descend(Visitor v, size_t idx) - { - auto offset = index(idx); - auto child = node_->inner()[offset]; - auto left_size = offset ? relaxed_->d.sizes[offset - 1] : 0; - auto next_idx = idx - left_size; - auto r = child->relaxed(); - return r ? relaxed_descent_pos<NodeT, Shift - B>{child, r}.visit( - v, next_idx) - : regular_descent_pos<NodeT, Shift - B>{child}.visit(v, - next_idx); - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_relaxed(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT, bits_t B, bits_t BL> -struct relaxed_descent_pos<NodeT, BL, B, BL> -{ - using node_t = NodeT; - using relaxed_t = typename NodeT::relaxed_t; - node_t* node_; - relaxed_t* relaxed_; - - count_t count() const { return relaxed_->d.count; } - node_t* node() const { return node_; } - shift_t shift() const { return BL; } - size_t size() const { return relaxed_->d.sizes[relaxed_->d.count - 1]; } - - count_t index(size_t idx) const - { - auto offset = (idx >> BL) & mask<B>; - while (relaxed_->d.sizes[offset] <= idx) - ++offset; - return offset; - } - - template <typename Visitor> - decltype(auto) descend(Visitor v, size_t idx) - { - auto offset = index(idx); - auto child = node_->inner()[offset]; - auto left_size = offset ? relaxed_->d.sizes[offset - 1] : 0; - auto next_idx = idx - left_size; - return leaf_descent_pos<NodeT>{child}.visit(v, next_idx); - } - - template <typename Visitor, typename... Args> - decltype(auto) visit(Visitor v, Args&&... args) - { - return Visitor::visit_relaxed(*this, std::forward<Args>(args)...); - } -}; - -template <typename NodeT, typename Visitor, typename... Args> -decltype(auto) -visit_maybe_relaxed_descent(NodeT* node, shift_t shift, Visitor v, size_t idx) -{ - constexpr auto B = NodeT::bits; - constexpr auto BL = NodeT::bits_leaf; - assert(node); - assert(shift >= BL); - auto r = node->relaxed(); - if (r) { - switch (shift) { - case BL + B * 0: - return relaxed_descent_pos<NodeT, BL + B * 0>{node, r}.visit(v, - idx); - case BL + B * 1: - return relaxed_descent_pos<NodeT, BL + B * 1>{node, r}.visit(v, - idx); - case BL + B * 2: - return relaxed_descent_pos<NodeT, BL + B * 2>{node, r}.visit(v, - idx); - case BL + B * 3: - return relaxed_descent_pos<NodeT, BL + B * 3>{node, r}.visit(v, - idx); - case BL + B * 4: - return relaxed_descent_pos<NodeT, BL + B * 4>{node, r}.visit(v, - idx); - case BL + B * 5: - return relaxed_descent_pos<NodeT, BL + B * 5>{node, r}.visit(v, - idx); -#if IMMER_DESCENT_DEEP - default: - for (auto level = shift; level != endshift<B, BL>; level -= B) { - auto r = node->relaxed(); - if (r) { - auto node_idx = (idx >> level) & mask<B>; - while (r->d.sizes[node_idx] <= idx) - ++node_idx; - if (node_idx) - idx -= r->d.sizes[node_idx - 1]; - node = node->inner()[node_idx]; - } else { - do { - node = node->inner()[(idx >> level) & mask<B>]; - } while ((level -= B) != endshift<B, BL>); - return make_leaf_descent_pos(node).visit(v, idx); - } - } - return make_leaf_descent_pos(node).visit(v, idx); -#endif // IMMER_DESCENT_DEEP - } - IMMER_UNREACHABLE; - } else { - return visit_regular_descent(node, shift, v, idx); - } -} - -} // namespace rbts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/rbts/rbtree.hpp b/third_party/immer/immer/detail/rbts/rbtree.hpp deleted file mode 100644 index b31f5e9b0788..000000000000 --- a/third_party/immer/immer/detail/rbts/rbtree.hpp +++ /dev/null @@ -1,509 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/rbts/node.hpp> -#include <immer/detail/rbts/operations.hpp> -#include <immer/detail/rbts/position.hpp> - -#include <immer/detail/type_traits.hpp> - -#include <cassert> -#include <memory> -#include <numeric> - -namespace immer { -namespace detail { -namespace rbts { - -template <typename T, typename MemoryPolicy, bits_t B, bits_t BL> -struct rbtree -{ - using node_t = node<T, MemoryPolicy, B, BL>; - using edit_t = typename node_t::edit_t; - using owner_t = typename MemoryPolicy::transience_t::owner; - - size_t size; - shift_t shift; - node_t* root; - node_t* tail; - - static const rbtree& empty() - { - static const rbtree empty_{ - 0, BL, node_t::make_inner_n(0u), node_t::make_leaf_n(0u)}; - return empty_; - } - - template <typename U> - static auto from_initializer_list(std::initializer_list<U> values) - { - auto e = owner_t{}; - auto result = rbtree{empty()}; - for (auto&& v : values) - result.push_back_mut(e, v); - return result; - } - - template <typename Iter, - typename Sent, - std::enable_if_t<compatible_sentinel_v<Iter, Sent>, bool> = true> - static auto from_range(Iter first, Sent last) - { - auto e = owner_t{}; - auto result = rbtree{empty()}; - for (; first != last; ++first) - result.push_back_mut(e, *first); - return result; - } - - static auto from_fill(size_t n, T v) - { - auto e = owner_t{}; - auto result = rbtree{empty()}; - while (n-- > 0) - result.push_back_mut(e, v); - return result; - } - - rbtree(size_t sz, shift_t sh, node_t* r, node_t* t) - : size{sz} - , shift{sh} - , root{r} - , tail{t} - { - assert(check_tree()); - } - - rbtree(const rbtree& other) - : rbtree{other.size, other.shift, other.root, other.tail} - { - inc(); - } - - rbtree(rbtree&& other) - : rbtree{empty()} - { - swap(*this, other); - } - - rbtree& operator=(const rbtree& other) - { - auto next = other; - swap(*this, next); - return *this; - } - - rbtree& operator=(rbtree&& other) - { - swap(*this, other); - return *this; - } - - friend void swap(rbtree& x, rbtree& y) - { - using std::swap; - swap(x.size, y.size); - swap(x.shift, y.shift); - swap(x.root, y.root); - swap(x.tail, y.tail); - } - - ~rbtree() { dec(); } - - void inc() const - { - root->inc(); - tail->inc(); - } - - void dec() const { traverse(dec_visitor()); } - - auto tail_size() const { return size ? ((size - 1) & mask<BL>) +1 : 0; } - - auto tail_offset() const { return size ? (size - 1) & ~mask<BL> : 0; } - - template <typename Visitor, typename... Args> - void traverse(Visitor v, Args&&... args) const - { - auto tail_off = tail_offset(); - auto tail_size = size - tail_off; - - if (tail_off) - make_regular_sub_pos(root, shift, tail_off).visit(v, args...); - else - make_empty_regular_pos(root).visit(v, args...); - - make_leaf_sub_pos(tail, tail_size).visit(v, args...); - } - - template <typename Visitor, typename... Args> - void traverse(Visitor v, size_t first, size_t last, Args&&... args) const - { - auto tail_off = tail_offset(); - auto tail_size = size - tail_off; - - if (first < tail_off) - make_regular_sub_pos(root, shift, tail_off) - .visit(v, first, last < tail_off ? last : tail_off, args...); - if (last > tail_off) - make_leaf_sub_pos(tail, tail_size) - .visit(v, - first > tail_off ? first - tail_off : 0, - last - tail_off, - args...); - } - - template <typename Visitor, typename... Args> - bool traverse_p(Visitor v, Args&&... args) const - { - auto tail_off = tail_offset(); - auto tail_size = size - tail_off; - return (tail_off ? make_regular_sub_pos(root, shift, tail_off) - .visit(v, args...) - : make_empty_regular_pos(root).visit(v, args...)) && - make_leaf_sub_pos(tail, tail_size).visit(v, args...); - } - - template <typename Visitor, typename... Args> - bool traverse_p(Visitor v, size_t first, size_t last, Args&&... args) const - { - auto tail_off = tail_offset(); - auto tail_size = size - tail_off; - - return (first < tail_off ? make_regular_sub_pos(root, shift, tail_off) - .visit(v, - first, - last < tail_off ? last : tail_off, - args...) - : true) && - (last > tail_off - ? make_leaf_sub_pos(tail, tail_size) - .visit(v, - first > tail_off ? first - tail_off : 0, - last - tail_off, - args...) - : true); - } - - template <typename Visitor> - decltype(auto) descend(Visitor v, size_t idx) const - { - auto tail_off = tail_offset(); - return idx >= tail_off ? make_leaf_descent_pos(tail).visit(v, idx) - : visit_regular_descent(root, shift, v, idx); - } - - template <typename Fn> - void for_each_chunk(Fn&& fn) const - { - traverse(for_each_chunk_visitor{}, std::forward<Fn>(fn)); - } - - template <typename Fn> - void for_each_chunk(size_t first, size_t last, Fn&& fn) const - { - traverse(for_each_chunk_i_visitor{}, first, last, std::forward<Fn>(fn)); - } - - template <typename Fn> - bool for_each_chunk_p(Fn&& fn) const - { - return traverse_p(for_each_chunk_p_visitor{}, std::forward<Fn>(fn)); - } - - template <typename Fn> - bool for_each_chunk_p(size_t first, size_t last, Fn&& fn) const - { - return traverse_p( - for_each_chunk_p_i_visitor{}, first, last, std::forward<Fn>(fn)); - } - - bool equals(const rbtree& other) const - { - if (size != other.size) - return false; - if (size == 0) - return true; - return (size <= branches<BL> || - make_regular_sub_pos(root, shift, tail_offset()) - .visit(equals_visitor{}, other.root)) && - make_leaf_sub_pos(tail, tail_size()) - .visit(equals_visitor{}, other.tail); - } - - void ensure_mutable_tail(edit_t e, count_t n) - { - if (!tail->can_mutate(e)) { - auto new_tail = node_t::copy_leaf_e(e, tail, n); - dec_leaf(tail, n); - tail = new_tail; - } - } - - void push_back_mut(edit_t e, T value) - { - auto tail_off = tail_offset(); - auto ts = size - tail_off; - if (ts < branches<BL>) { - ensure_mutable_tail(e, ts); - new (&tail->leaf()[ts]) T{std::move(value)}; - } else { - auto new_tail = node_t::make_leaf_e(e, std::move(value)); - try { - if (tail_off == size_t{branches<B>} << shift) { - auto new_root = node_t::make_inner_e(e); - try { - auto path = node_t::make_path_e(e, shift, tail); - new_root->inner()[0] = root; - new_root->inner()[1] = path; - root = new_root; - tail = new_tail; - shift += B; - } catch (...) { - node_t::delete_inner_e(new_root); - throw; - } - } else if (tail_off) { - auto new_root = - make_regular_sub_pos(root, shift, tail_off) - .visit(push_tail_mut_visitor<node_t>{}, e, tail); - root = new_root; - tail = new_tail; - } else { - auto new_root = node_t::make_path_e(e, shift, tail); - assert(tail_off == 0); - dec_empty_regular(root); - root = new_root; - tail = new_tail; - } - } catch (...) { - node_t::delete_leaf(new_tail, 1); - throw; - } - } - ++size; - } - - rbtree push_back(T value) const - { - auto tail_off = tail_offset(); - auto ts = size - tail_off; - if (ts < branches<BL>) { - auto new_tail = - node_t::copy_leaf_emplace(tail, ts, std::move(value)); - return {size + 1, shift, root->inc(), new_tail}; - } else { - auto new_tail = node_t::make_leaf_n(1, std::move(value)); - try { - if (tail_off == size_t{branches<B>} << shift) { - auto new_root = node_t::make_inner_n(2); - try { - auto path = node_t::make_path(shift, tail); - new_root->inner()[0] = root; - new_root->inner()[1] = path; - root->inc(); - tail->inc(); - return {size + 1, shift + B, new_root, new_tail}; - } catch (...) { - node_t::delete_inner(new_root, 2); - throw; - } - } else if (tail_off) { - auto new_root = - make_regular_sub_pos(root, shift, tail_off) - .visit(push_tail_visitor<node_t>{}, tail); - tail->inc(); - return {size + 1, shift, new_root, new_tail}; - } else { - auto new_root = node_t::make_path(shift, tail); - tail->inc(); - return {size + 1, shift, new_root, new_tail}; - } - } catch (...) { - node_t::delete_leaf(new_tail, 1); - throw; - } - } - } - - const T* array_for(size_t index) const - { - return descend(array_for_visitor<T>(), index); - } - - T& get_mut(edit_t e, size_t idx) - { - auto tail_off = tail_offset(); - if (idx >= tail_off) { - ensure_mutable_tail(e, size - tail_off); - return tail->leaf()[idx & mask<BL>]; - } else { - return make_regular_sub_pos(root, shift, tail_off) - .visit(get_mut_visitor<node_t>{}, idx, e, &root); - } - } - - const T& get(size_t index) const - { - return descend(get_visitor<T>(), index); - } - - const T& get_check(size_t index) const - { - if (index >= size) - throw std::out_of_range{"index out of range"}; - return descend(get_visitor<T>(), index); - } - - const T& front() const { return get(0); } - - const T& back() const { return tail->leaf()[(size - 1) & mask<BL>]; } - - template <typename FnT> - void update_mut(edit_t e, size_t idx, FnT&& fn) - { - auto& elem = get_mut(e, idx); - elem = std::forward<FnT>(fn)(std::move(elem)); - } - - template <typename FnT> - rbtree update(size_t idx, FnT&& fn) const - { - auto tail_off = tail_offset(); - if (idx >= tail_off) { - auto tail_size = size - tail_off; - auto new_tail = - make_leaf_sub_pos(tail, tail_size) - .visit(update_visitor<node_t>{}, idx - tail_off, fn); - return {size, shift, root->inc(), new_tail}; - } else { - auto new_root = make_regular_sub_pos(root, shift, tail_off) - .visit(update_visitor<node_t>{}, idx, fn); - return {size, shift, new_root, tail->inc()}; - } - } - - void assoc_mut(edit_t e, size_t idx, T value) - { - update_mut(e, idx, [&](auto&&) { return std::move(value); }); - } - - rbtree assoc(size_t idx, T value) const - { - return update(idx, [&](auto&&) { return std::move(value); }); - } - - rbtree take(size_t new_size) const - { - auto tail_off = tail_offset(); - if (new_size == 0) { - return empty(); - } else if (new_size >= size) { - return *this; - } else if (new_size > tail_off) { - auto new_tail = node_t::copy_leaf(tail, new_size - tail_off); - return {new_size, shift, root->inc(), new_tail}; - } else { - using std::get; - auto l = new_size - 1; - auto v = slice_right_visitor<node_t>(); - auto r = make_regular_sub_pos(root, shift, tail_off).visit(v, l); - auto new_shift = get<0>(r); - auto new_root = get<1>(r); - auto new_tail = get<3>(r); - if (new_root) { - IMMER_ASSERT_TAGGED(new_root->compute_shift() == get<0>(r)); - assert(new_root->check(new_shift, new_size - get<2>(r))); - return {new_size, new_shift, new_root, new_tail}; - } else { - return {new_size, BL, empty().root->inc(), new_tail}; - } - } - } - - void take_mut(edit_t e, size_t new_size) - { - auto tail_off = tail_offset(); - if (new_size == 0) { - // todo: more efficient? - *this = empty(); - } else if (new_size >= size) { - return; - } else if (new_size > tail_off) { - auto ts = size - tail_off; - auto newts = new_size - tail_off; - if (tail->can_mutate(e)) { - destroy_n(tail->leaf() + newts, ts - newts); - } else { - auto new_tail = node_t::copy_leaf_e(e, tail, newts); - dec_leaf(tail, ts); - tail = new_tail; - } - size = new_size; - return; - } else { - using std::get; - auto l = new_size - 1; - auto v = slice_right_mut_visitor<node_t>(); - auto r = make_regular_sub_pos(root, shift, tail_off).visit(v, l, e); - auto new_shift = get<0>(r); - auto new_root = get<1>(r); - auto new_tail = get<3>(r); - if (new_root) { - root = new_root; - shift = new_shift; - } else { - root = empty().root->inc(); - shift = BL; - } - dec_leaf(tail, size - tail_off); - size = new_size; - tail = new_tail; - return; - } - } - - bool check_tree() const - { -#if IMMER_DEBUG_DEEP_CHECK - assert(shift >= BL); - assert(tail_offset() <= size); - assert(check_root()); - assert(check_tail()); -#endif - return true; - } - - bool check_tail() const - { -#if IMMER_DEBUG_DEEP_CHECK - if (tail_size() > 0) - assert(tail->check(0, tail_size())); -#endif - return true; - } - - bool check_root() const - { -#if IMMER_DEBUG_DEEP_CHECK - if (tail_offset() > 0) - assert(root->check(shift, tail_offset())); - else { - IMMER_ASSERT_TAGGED(root->kind() == node_t::kind_t::inner); - assert(shift == BL); - } -#endif - return true; - } -}; - -} // namespace rbts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/rbts/rbtree_iterator.hpp b/third_party/immer/immer/detail/rbts/rbtree_iterator.hpp deleted file mode 100644 index 90613b10b98e..000000000000 --- a/third_party/immer/immer/detail/rbts/rbtree_iterator.hpp +++ /dev/null @@ -1,99 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/iterator_facade.hpp> -#include <immer/detail/rbts/rbtree.hpp> - -namespace immer { -namespace detail { -namespace rbts { - -template <typename T, typename MP, bits_t B, bits_t BL> -struct rbtree_iterator - : iterator_facade<rbtree_iterator<T, MP, B, BL>, - std::random_access_iterator_tag, - T, - const T&, - std::ptrdiff_t, - const T*> -{ - using tree_t = rbtree<T, MP, B, BL>; - - struct end_t - {}; - - rbtree_iterator() = default; - - rbtree_iterator(const tree_t& v) - : v_{&v} - , i_{0} - , base_{~size_t{}} - , curr_{nullptr} - {} - - rbtree_iterator(const tree_t& v, end_t) - : v_{&v} - , i_{v.size} - , base_{~size_t{}} - , curr_{nullptr} - {} - - const tree_t& impl() const { return *v_; } - size_t index() const { return i_; } - -private: - friend iterator_core_access; - - const tree_t* v_; - size_t i_; - mutable size_t base_; - mutable const T* curr_ = nullptr; - - void increment() - { - assert(i_ < v_->size); - ++i_; - } - - void decrement() - { - assert(i_ > 0); - --i_; - } - - void advance(std::ptrdiff_t n) - { - assert(n <= 0 || i_ + static_cast<size_t>(n) <= v_->size); - assert(n >= 0 || static_cast<size_t>(-n) <= i_); - i_ += n; - } - - bool equal(const rbtree_iterator& other) const { return i_ == other.i_; } - - std::ptrdiff_t distance_to(const rbtree_iterator& other) const - { - return other.i_ > i_ ? static_cast<std::ptrdiff_t>(other.i_ - i_) - : -static_cast<std::ptrdiff_t>(i_ - other.i_); - } - - const T& dereference() const - { - auto base = i_ & ~mask<BL>; - if (base_ != base) { - base_ = base; - curr_ = v_->array_for(i_); - } - return curr_[i_ & mask<BL>]; - } -}; - -} // namespace rbts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/rbts/rrbtree.hpp b/third_party/immer/immer/detail/rbts/rrbtree.hpp deleted file mode 100644 index 7bf59e6e92b1..000000000000 --- a/third_party/immer/immer/detail/rbts/rrbtree.hpp +++ /dev/null @@ -1,1396 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/config.hpp> -#include <immer/detail/rbts/node.hpp> -#include <immer/detail/rbts/operations.hpp> -#include <immer/detail/rbts/position.hpp> - -#include <immer/detail/type_traits.hpp> - -#include <cassert> -#include <memory> -#include <numeric> - -namespace immer { -namespace detail { -namespace rbts { - -template <typename T, typename MemoryPolicy, bits_t B, bits_t BL> -struct rrbtree_iterator; - -template <typename T, typename MemoryPolicy, bits_t B, bits_t BL> -struct rrbtree -{ - using node_t = node<T, MemoryPolicy, B, BL>; - using edit_t = typename node_t::edit_t; - using owner_t = typename MemoryPolicy::transience_t::owner; - - size_t size; - shift_t shift; - node_t* root; - node_t* tail; - - static const rrbtree& empty() - { - static const rrbtree empty_{ - 0, BL, node_t::make_inner_n(0u), node_t::make_leaf_n(0u)}; - return empty_; - } - - template <typename U> - static auto from_initializer_list(std::initializer_list<U> values) - { - auto e = owner_t{}; - auto result = rrbtree{empty()}; - for (auto&& v : values) - result.push_back_mut(e, v); - return result; - } - - template <typename Iter, - typename Sent, - std::enable_if_t<compatible_sentinel_v<Iter, Sent>, bool> = true> - static auto from_range(Iter first, Sent last) - { - auto e = owner_t{}; - auto result = rrbtree{empty()}; - for (; first != last; ++first) - result.push_back_mut(e, *first); - return result; - } - - static auto from_fill(size_t n, T v) - { - auto e = owner_t{}; - auto result = rrbtree{empty()}; - while (n-- > 0) - result.push_back_mut(e, v); - return result; - } - - rrbtree(size_t sz, shift_t sh, node_t* r, node_t* t) - : size{sz} - , shift{sh} - , root{r} - , tail{t} - { - assert(check_tree()); - } - - rrbtree(const rrbtree& other) - : rrbtree{other.size, other.shift, other.root, other.tail} - { - inc(); - } - - rrbtree(rrbtree&& other) - : rrbtree{empty()} - { - swap(*this, other); - } - - rrbtree& operator=(const rrbtree& other) - { - auto next{other}; - swap(*this, next); - return *this; - } - - rrbtree& operator=(rrbtree&& other) - { - swap(*this, other); - return *this; - } - - friend void swap(rrbtree& x, rrbtree& y) - { - using std::swap; - swap(x.size, y.size); - swap(x.shift, y.shift); - swap(x.root, y.root); - swap(x.tail, y.tail); - } - - ~rrbtree() { dec(); } - - void inc() const - { - root->inc(); - tail->inc(); - } - - void dec() const { traverse(dec_visitor()); } - - auto tail_size() const { return size - tail_offset(); } - - auto tail_offset() const - { - auto r = root->relaxed(); - assert(r == nullptr || r->d.count); - return r ? r->d.sizes[r->d.count - 1] - : size ? (size - 1) & ~mask<BL> - /* otherwise */ : 0; - } - - template <typename Visitor, typename... Args> - void traverse(Visitor v, Args&&... args) const - { - auto tail_off = tail_offset(); - auto tail_size = size - tail_off; - - if (tail_off) - visit_maybe_relaxed_sub(root, shift, tail_off, v, args...); - else - make_empty_regular_pos(root).visit(v, args...); - - if (tail_size) - make_leaf_sub_pos(tail, tail_size).visit(v, args...); - else - make_empty_leaf_pos(tail).visit(v, args...); - } - - template <typename Visitor, typename... Args> - void traverse(Visitor v, size_t first, size_t last, Args&&... args) const - { - auto tail_off = tail_offset(); - auto tail_size = size - tail_off; - - if (first < tail_off) - visit_maybe_relaxed_sub(root, - shift, - tail_off, - v, - first, - last < tail_off ? last : tail_off, - args...); - if (last > tail_off) - make_leaf_sub_pos(tail, tail_size) - .visit(v, - first > tail_off ? first - tail_off : 0, - last - tail_off, - args...); - } - - template <typename Visitor, typename... Args> - bool traverse_p(Visitor v, Args&&... args) const - { - auto tail_off = tail_offset(); - auto tail_size = size - tail_off; - return (tail_off - ? visit_maybe_relaxed_sub(root, shift, tail_off, v, args...) - : make_empty_regular_pos(root).visit(v, args...)) && - (tail_size ? make_leaf_sub_pos(tail, tail_size).visit(v, args...) - : make_empty_leaf_pos(tail).visit(v, args...)); - } - - template <typename Visitor, typename... Args> - bool traverse_p(Visitor v, size_t first, size_t last, Args&&... args) const - { - auto tail_off = tail_offset(); - auto tail_size = size - tail_off; - return (first < tail_off - ? visit_maybe_relaxed_sub(root, - shift, - tail_off, - v, - first, - last < tail_off ? last : tail_off, - args...) - : true) && - (last > tail_off - ? make_leaf_sub_pos(tail, tail_size) - .visit(v, - first > tail_off ? first - tail_off : 0, - last - tail_off, - args...) - : true); - } - - template <typename Visitor> - decltype(auto) descend(Visitor v, size_t idx) const - { - auto tail_off = tail_offset(); - return idx >= tail_off - ? make_leaf_descent_pos(tail).visit(v, idx - tail_off) - : visit_maybe_relaxed_descent(root, shift, v, idx); - } - - template <typename Fn> - void for_each_chunk(Fn&& fn) const - { - traverse(for_each_chunk_visitor{}, std::forward<Fn>(fn)); - } - - template <typename Fn> - void for_each_chunk(size_t first, size_t last, Fn&& fn) const - { - traverse(for_each_chunk_i_visitor{}, first, last, std::forward<Fn>(fn)); - } - - template <typename Fn> - bool for_each_chunk_p(Fn&& fn) const - { - return traverse_p(for_each_chunk_p_visitor{}, std::forward<Fn>(fn)); - } - - template <typename Fn> - bool for_each_chunk_p(size_t first, size_t last, Fn&& fn) const - { - return traverse_p( - for_each_chunk_p_i_visitor{}, first, last, std::forward<Fn>(fn)); - } - - bool equals(const rrbtree& other) const - { - using iter_t = rrbtree_iterator<T, MemoryPolicy, B, BL>; - if (size != other.size) - return false; - if (size == 0) - return true; - auto tail_off = tail_offset(); - auto tail_off_other = other.tail_offset(); - // compare trees - if (tail_off > 0 && tail_off_other > 0) { - // other.shift != shift is a theoretical possibility for - // relaxed trees that sadly we haven't managed to exercise - // in tests yet... - if (other.shift >= shift) { - if (!visit_maybe_relaxed_sub(other.root, - other.shift, - tail_off_other, - equals_visitor::rrb{}, - iter_t{other}, - root, - shift, - tail_off)) - return false; - } else { - if (!visit_maybe_relaxed_sub(root, - shift, - tail_off, - equals_visitor::rrb{}, - iter_t{*this}, - other.root, - other.shift, - tail_off_other)) - return false; - } - } - return tail_off == tail_off_other - ? make_leaf_sub_pos(tail, tail_size()) - .visit(equals_visitor{}, other.tail) - : tail_off > tail_off_other - ? std::equal(tail->leaf(), - tail->leaf() + (size - tail_off), - other.tail->leaf() + - (tail_off - tail_off_other)) - /* otherwise */ - : std::equal(tail->leaf(), - tail->leaf() + (size - tail_off), - iter_t{other} + tail_off); - } - - std::tuple<shift_t, node_t*> push_tail(node_t* root, - shift_t shift, - size_t size, - node_t* tail, - count_t tail_size) const - { - if (auto r = root->relaxed()) { - auto new_root = - make_relaxed_pos(root, shift, r) - .visit(push_tail_visitor<node_t>{}, tail, tail_size); - if (new_root) - return std::make_tuple(shift, new_root); - else { - auto new_root = node_t::make_inner_r_n(2); - try { - auto new_path = node_t::make_path(shift, tail); - new_root->inner()[0] = root->inc(); - new_root->inner()[1] = new_path; - new_root->relaxed()->d.sizes[0] = size; - new_root->relaxed()->d.sizes[1] = size + tail_size; - new_root->relaxed()->d.count = 2u; - } catch (...) { - node_t::delete_inner_r(new_root, 2); - throw; - } - return std::make_tuple(shift + B, new_root); - } - } else if (size == size_t{branches<B>} << shift) { - auto new_root = node_t::make_inner_n(2); - try { - auto new_path = node_t::make_path(shift, tail); - new_root->inner()[0] = root->inc(); - new_root->inner()[1] = new_path; - } catch (...) { - node_t::delete_inner(new_root, 2); - throw; - } - return std::make_tuple(shift + B, new_root); - } else if (size) { - auto new_root = make_regular_sub_pos(root, shift, size) - .visit(push_tail_visitor<node_t>{}, tail); - return std::make_tuple(shift, new_root); - } else { - return std::make_tuple(shift, node_t::make_path(shift, tail)); - } - } - - void - push_tail_mut(edit_t e, size_t tail_off, node_t* tail, count_t tail_size) - { - if (auto r = root->relaxed()) { - auto new_root = - make_relaxed_pos(root, shift, r) - .visit(push_tail_mut_visitor<node_t>{}, e, tail, tail_size); - if (new_root) { - root = new_root; - } else { - auto new_root = node_t::make_inner_r_e(e); - try { - auto new_path = node_t::make_path_e(e, shift, tail); - new_root->inner()[0] = root; - new_root->inner()[1] = new_path; - new_root->relaxed()->d.sizes[0] = tail_off; - new_root->relaxed()->d.sizes[1] = tail_off + tail_size; - new_root->relaxed()->d.count = 2u; - root = new_root; - shift += B; - } catch (...) { - node_t::delete_inner_r_e(new_root); - throw; - } - } - } else if (tail_off == size_t{branches<B>} << shift) { - auto new_root = node_t::make_inner_e(e); - try { - auto new_path = node_t::make_path_e(e, shift, tail); - new_root->inner()[0] = root; - new_root->inner()[1] = new_path; - root = new_root; - shift += B; - } catch (...) { - node_t::delete_inner_e(new_root); - throw; - } - } else if (tail_off) { - auto new_root = - make_regular_sub_pos(root, shift, tail_off) - .visit(push_tail_mut_visitor<node_t>{}, e, tail); - root = new_root; - } else { - auto new_root = node_t::make_path_e(e, shift, tail); - dec_empty_regular(root); - root = new_root; - } - } - - void ensure_mutable_tail(edit_t e, count_t n) - { - if (!tail->can_mutate(e)) { - auto new_tail = node_t::copy_leaf_e(e, tail, n); - dec_leaf(tail, n); - tail = new_tail; - } - } - - void push_back_mut(edit_t e, T value) - { - auto ts = tail_size(); - if (ts < branches<BL>) { - ensure_mutable_tail(e, ts); - new (&tail->leaf()[ts]) T{std::move(value)}; - } else { - using std::get; - auto new_tail = node_t::make_leaf_e(e, std::move(value)); - auto tail_off = tail_offset(); - try { - push_tail_mut(e, tail_off, tail, ts); - tail = new_tail; - } catch (...) { - node_t::delete_leaf(new_tail, 1u); - throw; - } - } - ++size; - } - - rrbtree push_back(T value) const - { - auto ts = tail_size(); - if (ts < branches<BL>) { - auto new_tail = - node_t::copy_leaf_emplace(tail, ts, std::move(value)); - return {size + 1, shift, root->inc(), new_tail}; - } else { - using std::get; - auto new_tail = node_t::make_leaf_n(1u, std::move(value)); - auto tail_off = tail_offset(); - try { - auto new_root = - push_tail(root, shift, tail_off, tail, size - tail_off); - tail->inc(); - return {size + 1, get<0>(new_root), get<1>(new_root), new_tail}; - } catch (...) { - node_t::delete_leaf(new_tail, 1u); - throw; - } - } - } - - std::tuple<const T*, size_t, size_t> region_for(size_t idx) const - { - using std::get; - auto tail_off = tail_offset(); - if (idx >= tail_off) { - return std::make_tuple(tail->leaf(), tail_off, size); - } else { - auto subs = visit_maybe_relaxed_sub( - root, shift, tail_off, region_for_visitor<T>(), idx); - auto first = idx - get<1>(subs); - auto end = first + get<2>(subs); - return std::make_tuple(get<0>(subs), first, end); - } - } - - T& get_mut(edit_t e, size_t idx) - { - auto tail_off = tail_offset(); - if (idx >= tail_off) { - ensure_mutable_tail(e, size - tail_off); - return tail->leaf()[(idx - tail_off) & mask<BL>]; - } else { - return visit_maybe_relaxed_sub(root, - shift, - tail_off, - get_mut_visitor<node_t>{}, - idx, - e, - &root); - } - } - - const T& get(size_t index) const - { - return descend(get_visitor<T>(), index); - } - - const T& get_check(size_t index) const - { - if (index >= size) - throw std::out_of_range{"out of range"}; - return descend(get_visitor<T>(), index); - } - - const T& front() const { return get(0); } - - const T& back() const { return get(size - 1); } - - template <typename FnT> - void update_mut(edit_t e, size_t idx, FnT&& fn) - { - auto& elem = get_mut(e, idx); - elem = std::forward<FnT>(fn)(std::move(elem)); - } - - template <typename FnT> - rrbtree update(size_t idx, FnT&& fn) const - { - auto tail_off = tail_offset(); - if (idx >= tail_off) { - auto tail_size = size - tail_off; - auto new_tail = - make_leaf_sub_pos(tail, tail_size) - .visit(update_visitor<node_t>{}, idx - tail_off, fn); - return {size, shift, root->inc(), new_tail}; - } else { - auto new_root = visit_maybe_relaxed_sub( - root, shift, tail_off, update_visitor<node_t>{}, idx, fn); - return {size, shift, new_root, tail->inc()}; - } - } - - void assoc_mut(edit_t e, size_t idx, T value) - { - update_mut(e, idx, [&](auto&&) { return std::move(value); }); - } - - rrbtree assoc(size_t idx, T value) const - { - return update(idx, [&](auto&&) { return std::move(value); }); - } - - void take_mut(edit_t e, size_t new_size) - { - auto tail_off = tail_offset(); - if (new_size == 0) { - *this = empty(); - } else if (new_size >= size) { - return; - } else if (new_size > tail_off) { - auto ts = size - tail_off; - auto newts = new_size - tail_off; - if (tail->can_mutate(e)) { - destroy_n(tail->leaf() + newts, ts - newts); - } else { - auto new_tail = node_t::copy_leaf_e(e, tail, newts); - dec_leaf(tail, ts); - tail = new_tail; - } - size = new_size; - return; - } else { - using std::get; - auto l = new_size - 1; - auto v = slice_right_mut_visitor<node_t>(); - auto r = visit_maybe_relaxed_sub(root, shift, tail_off, v, l, e); - auto new_shift = get<0>(r); - auto new_root = get<1>(r); - auto new_tail = get<3>(r); - if (new_root) { - root = new_root; - shift = new_shift; - } else { - root = empty().root->inc(); - shift = BL; - } - dec_leaf(tail, size - tail_off); - size = new_size; - tail = new_tail; - return; - } - } - - rrbtree take(size_t new_size) const - { - auto tail_off = tail_offset(); - if (new_size == 0) { - return empty(); - } else if (new_size >= size) { - return *this; - } else if (new_size > tail_off) { - auto new_tail = node_t::copy_leaf(tail, new_size - tail_off); - return {new_size, shift, root->inc(), new_tail}; - } else { - using std::get; - auto l = new_size - 1; - auto v = slice_right_visitor<node_t>(); - auto r = visit_maybe_relaxed_sub(root, shift, tail_off, v, l); - auto new_shift = get<0>(r); - auto new_root = get<1>(r); - auto new_tail = get<3>(r); - if (new_root) { - IMMER_ASSERT_TAGGED(new_root->compute_shift() == get<0>(r)); - assert(new_root->check(new_shift, new_size - get<2>(r))); - return {new_size, new_shift, new_root, new_tail}; - } else { - return {new_size, BL, empty().root->inc(), new_tail}; - } - } - } - - void drop_mut(edit_t e, size_t elems) - { - using std::get; - auto tail_off = tail_offset(); - if (elems == 0) { - return; - } else if (elems >= size) { - *this = empty(); - } else if (elems == tail_off) { - dec_inner(root, shift, tail_off); - shift = BL; - root = empty().root->inc(); - size -= elems; - return; - } else if (elems > tail_off) { - auto v = slice_left_mut_visitor<node_t>(); - tail = get<1>(make_leaf_sub_pos(tail, size - tail_off) - .visit(v, elems - tail_off, e)); - if (root != empty().root) { - dec_inner(root, shift, tail_off); - shift = BL; - root = empty().root->inc(); - } - size -= elems; - return; - } else { - auto v = slice_left_mut_visitor<node_t>(); - auto r = - visit_maybe_relaxed_sub(root, shift, tail_off, v, elems, e); - shift = get<0>(r); - root = get<1>(r); - size -= elems; - return; - } - } - - rrbtree drop(size_t elems) const - { - if (elems == 0) { - return *this; - } else if (elems >= size) { - return empty(); - } else if (elems == tail_offset()) { - return {size - elems, BL, empty().root->inc(), tail->inc()}; - } else if (elems > tail_offset()) { - auto tail_off = tail_offset(); - auto new_tail = - node_t::copy_leaf(tail, elems - tail_off, size - tail_off); - return {size - elems, BL, empty().root->inc(), new_tail}; - } else { - using std::get; - auto v = slice_left_visitor<node_t>(); - auto r = - visit_maybe_relaxed_sub(root, shift, tail_offset(), v, elems); - auto new_root = get<1>(r); - auto new_shift = get<0>(r); - return {size - elems, new_shift, new_root, tail->inc()}; - } - return *this; - } - - rrbtree concat(const rrbtree& r) const - { - assert(r.size < (std::numeric_limits<size_t>::max() - size)); - using std::get; - if (size == 0) - return r; - else if (r.size == 0) - return *this; - else if (r.tail_offset() == 0) { - // just concat the tail, similar to push_back - auto tail_offst = tail_offset(); - auto tail_size = size - tail_offst; - if (tail_size == branches<BL>) { - auto new_root = - push_tail(root, shift, tail_offst, tail, tail_size); - tail->inc(); - return {size + r.size, - get<0>(new_root), - get<1>(new_root), - r.tail->inc()}; - } else if (tail_size + r.size <= branches<BL>) { - auto new_tail = - node_t::copy_leaf(tail, tail_size, r.tail, r.size); - return {size + r.size, shift, root->inc(), new_tail}; - } else { - auto remaining = branches<BL> - tail_size; - auto add_tail = - node_t::copy_leaf(tail, tail_size, r.tail, remaining); - try { - auto new_tail = - node_t::copy_leaf(r.tail, remaining, r.size); - try { - auto new_root = push_tail( - root, shift, tail_offst, add_tail, branches<BL>); - return {size + r.size, - get<0>(new_root), - get<1>(new_root), - new_tail}; - } catch (...) { - node_t::delete_leaf(new_tail, r.size - remaining); - throw; - } - } catch (...) { - node_t::delete_leaf(add_tail, branches<BL>); - throw; - } - } - } else if (tail_offset() == 0) { - auto tail_offst = tail_offset(); - auto tail_size = size - tail_offst; - auto concated = - concat_trees(tail, tail_size, r.root, r.shift, r.tail_offset()); - auto new_shift = concated.shift(); - auto new_root = concated.node(); - IMMER_ASSERT_TAGGED(new_shift == new_root->compute_shift()); - assert(new_root->check(new_shift, size + r.tail_offset())); - return {size + r.size, new_shift, new_root, r.tail->inc()}; - } else { - auto tail_offst = tail_offset(); - auto tail_size = size - tail_offst; - auto concated = concat_trees(root, - shift, - tail_offst, - tail, - tail_size, - r.root, - r.shift, - r.tail_offset()); - auto new_shift = concated.shift(); - auto new_root = concated.node(); - IMMER_ASSERT_TAGGED(new_shift == new_root->compute_shift()); - assert(new_root->check(new_shift, size + r.tail_offset())); - return {size + r.size, new_shift, new_root, r.tail->inc()}; - } - } - - constexpr static bool supports_transient_concat = - !std::is_empty<edit_t>::value; - - friend void concat_mut_l(rrbtree& l, edit_t el, const rrbtree& r) - { - assert(&l != &r); - assert(r.size < (std::numeric_limits<size_t>::max() - l.size)); - using std::get; - if (l.size == 0) - l = r; - else if (r.size == 0) - return; - else if (r.tail_offset() == 0) { - // just concat the tail, similar to push_back - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - if (tail_size == branches<BL>) { - l.push_tail_mut(el, tail_offst, l.tail, tail_size); - l.tail = r.tail->inc(); - l.size += r.size; - return; - } else if (tail_size + r.size <= branches<BL>) { - l.ensure_mutable_tail(el, tail_size); - std::uninitialized_copy(r.tail->leaf(), - r.tail->leaf() + r.size, - l.tail->leaf() + tail_size); - l.size += r.size; - return; - } else { - auto remaining = branches<BL> - tail_size; - l.ensure_mutable_tail(el, tail_size); - std::uninitialized_copy(r.tail->leaf(), - r.tail->leaf() + remaining, - l.tail->leaf() + tail_size); - try { - auto new_tail = - node_t::copy_leaf_e(el, r.tail, remaining, r.size); - try { - l.push_tail_mut(el, tail_offst, l.tail, branches<BL>); - l.tail = new_tail; - l.size += r.size; - return; - } catch (...) { - node_t::delete_leaf(new_tail, r.size - remaining); - throw; - } - } catch (...) { - destroy_n(r.tail->leaf() + tail_size, remaining); - throw; - } - } - } else if (l.tail_offset() == 0) { - if (supports_transient_concat) { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = - concat_trees_mut(el, - el, - l.tail, - tail_size, - MemoryPolicy::transience_t::noone, - r.root, - r.shift, - r.tail_offset()); - IMMER_ASSERT_TAGGED(concated.shift() == - concated.node()->compute_shift()); - assert(concated.node()->check(concated.shift(), - l.size + r.tail_offset())); - l.size += r.size; - l.shift = concated.shift(); - l.root = concated.node(); - l.tail = r.tail; - } else { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees( - l.tail, tail_size, r.root, r.shift, r.tail_offset()); - l = {l.size + r.size, - concated.shift(), - concated.node(), - r.tail->inc()}; - return; - } - } else { - if (supports_transient_concat) { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = - concat_trees_mut(el, - el, - l.root, - l.shift, - tail_offst, - l.tail, - tail_size, - MemoryPolicy::transience_t::noone, - r.root, - r.shift, - r.tail_offset()); - IMMER_ASSERT_TAGGED(concated.shift() == - concated.node()->compute_shift()); - assert(concated.node()->check(concated.shift(), - l.size + r.tail_offset())); - l.size += r.size; - l.shift = concated.shift(); - l.root = concated.node(); - l.tail = r.tail; - } else { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees(l.root, - l.shift, - tail_offst, - l.tail, - tail_size, - r.root, - r.shift, - r.tail_offset()); - l = {l.size + r.size, - concated.shift(), - concated.node(), - r.tail->inc()}; - } - } - } - - friend void concat_mut_r(const rrbtree& l, rrbtree& r, edit_t er) - { - assert(&l != &r); - assert(r.size < (std::numeric_limits<size_t>::max() - l.size)); - using std::get; - if (r.size == 0) - r = std::move(l); - else if (l.size == 0) - return; - else if (r.tail_offset() == 0) { - // just concat the tail, similar to push_back - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - if (tail_size == branches<BL>) { - // this could be improved by making sure that the - // newly created nodes as part of the `push_tail()` - // are tagged with `er` - auto res = - l.push_tail(l.root, l.shift, tail_offst, l.tail, tail_size); - l.tail->inc(); // note: leak if mutably concatenated - // with itself, but this is forbidden - // by the interface - r = {l.size + r.size, get<0>(res), get<1>(res), r.tail->inc()}; - return; - } else if (tail_size + r.size <= branches<BL>) { - // doing this in a exception way mutating way is very - // tricky while potential performance gains are - // minimal (we need to move every element of the right - // tail anyways to make space for the left tail) - // - // we could however improve this by at least moving the - // elements of the right tail... - auto new_tail = - node_t::copy_leaf(l.tail, tail_size, r.tail, r.size); - r = {l.size + r.size, l.shift, l.root->inc(), new_tail}; - return; - } else { - // like the immutable version - auto remaining = branches<BL> - tail_size; - auto add_tail = node_t::copy_leaf_e( - er, l.tail, tail_size, r.tail, remaining); - try { - auto new_tail = - node_t::copy_leaf_e(er, r.tail, remaining, r.size); - try { - // this could be improved by making sure that the - // newly created nodes as part of the `push_tail()` - // are tagged with `er` - auto new_root = l.push_tail(l.root, - l.shift, - tail_offst, - add_tail, - branches<BL>); - r = {l.size + r.size, - get<0>(new_root), - get<1>(new_root), - new_tail}; - return; - } catch (...) { - node_t::delete_leaf(new_tail, r.size - remaining); - throw; - } - } catch (...) { - node_t::delete_leaf(add_tail, branches<BL>); - throw; - } - return; - } - } else if (l.tail_offset() == 0) { - if (supports_transient_concat) { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = - concat_trees_mut(er, - MemoryPolicy::transience_t::noone, - l.tail, - tail_size, - er, - r.root, - r.shift, - r.tail_offset()); - IMMER_ASSERT_TAGGED(concated.shift() == - concated.node()->compute_shift()); - assert(concated.node()->check(concated.shift(), - l.size + r.tail_offset())); - r.size += l.size; - r.shift = concated.shift(); - r.root = concated.node(); - } else { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees( - l.tail, tail_size, r.root, r.shift, r.tail_offset()); - r = {l.size + r.size, - concated.shift(), - concated.node(), - r.tail->inc()}; - return; - } - } else { - if (supports_transient_concat) { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = - concat_trees_mut(er, - MemoryPolicy::transience_t::noone, - l.root, - l.shift, - tail_offst, - l.tail, - tail_size, - er, - r.root, - r.shift, - r.tail_offset()); - IMMER_ASSERT_TAGGED(concated.shift() == - concated.node()->compute_shift()); - assert(concated.node()->check(concated.shift(), - l.size + r.tail_offset())); - r.size += l.size; - r.shift = concated.shift(); - r.root = concated.node(); - return; - } else { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees(l.root, - l.shift, - tail_offst, - l.tail, - tail_size, - r.root, - r.shift, - r.tail_offset()); - r = {l.size + r.size, - concated.shift(), - concated.node(), - r.tail->inc()}; - return; - } - } - } - - friend void concat_mut_lr_l(rrbtree& l, edit_t el, rrbtree& r, edit_t er) - { - assert(&l != &r); - assert(r.size < (std::numeric_limits<size_t>::max() - l.size)); - using std::get; - if (l.size == 0) - l = r; - else if (r.size == 0) - return; - else if (r.tail_offset() == 0) { - // just concat the tail, similar to push_back - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - if (tail_size == branches<BL>) { - l.push_tail_mut(el, tail_offst, l.tail, tail_size); - l.tail = r.tail->inc(); - l.size += r.size; - return; - } else if (tail_size + r.size <= branches<BL>) { - l.ensure_mutable_tail(el, tail_size); - if (r.tail->can_mutate(er)) - detail::uninitialized_move(r.tail->leaf(), - r.tail->leaf() + r.size, - l.tail->leaf() + tail_size); - else - std::uninitialized_copy(r.tail->leaf(), - r.tail->leaf() + r.size, - l.tail->leaf() + tail_size); - l.size += r.size; - return; - } else { - auto remaining = branches<BL> - tail_size; - l.ensure_mutable_tail(el, tail_size); - if (r.tail->can_mutate(er)) - detail::uninitialized_move(r.tail->leaf(), - r.tail->leaf() + remaining, - l.tail->leaf() + tail_size); - else - std::uninitialized_copy(r.tail->leaf(), - r.tail->leaf() + remaining, - l.tail->leaf() + tail_size); - try { - auto new_tail = - node_t::copy_leaf_e(el, r.tail, remaining, r.size); - try { - l.push_tail_mut(el, tail_offst, l.tail, branches<BL>); - l.tail = new_tail; - l.size += r.size; - return; - } catch (...) { - node_t::delete_leaf(new_tail, r.size - remaining); - throw; - } - } catch (...) { - destroy_n(r.tail->leaf() + tail_size, remaining); - throw; - } - } - } else if (l.tail_offset() == 0) { - if (supports_transient_concat) { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees_mut(el, - el, - l.tail, - tail_size, - er, - r.root, - r.shift, - r.tail_offset()); - IMMER_ASSERT_TAGGED(concated.shift() == - concated.node()->compute_shift()); - assert(concated.node()->check(concated.shift(), - l.size + r.tail_offset())); - l.size += r.size; - l.shift = concated.shift(); - l.root = concated.node(); - l.tail = r.tail; - r.hard_reset(); - } else { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees( - l.tail, tail_size, r.root, r.shift, r.tail_offset()); - l = {l.size + r.size, - concated.shift(), - concated.node(), - r.tail->inc()}; - return; - } - } else { - if (supports_transient_concat) { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees_mut(el, - el, - l.root, - l.shift, - tail_offst, - l.tail, - tail_size, - er, - r.root, - r.shift, - r.tail_offset()); - IMMER_ASSERT_TAGGED(concated.shift() == - concated.node()->compute_shift()); - assert(concated.node()->check(concated.shift(), - l.size + r.tail_offset())); - l.size += r.size; - l.shift = concated.shift(); - l.root = concated.node(); - l.tail = r.tail; - r.hard_reset(); - } else { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees(l.root, - l.shift, - tail_offst, - l.tail, - tail_size, - r.root, - r.shift, - r.tail_offset()); - l = {l.size + r.size, - concated.shift(), - concated.node(), - r.tail->inc()}; - } - } - } - - friend void concat_mut_lr_r(rrbtree& l, edit_t el, rrbtree& r, edit_t er) - { - assert(&l != &r); - assert(r.size < (std::numeric_limits<size_t>::max() - l.size)); - using std::get; - if (r.size == 0) - r = l; - else if (l.size == 0) - return; - else if (r.tail_offset() == 0) { - // just concat the tail, similar to push_back - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - if (tail_size == branches<BL>) { - // this could be improved by making sure that the - // newly created nodes as part of the `push_tail()` - // are tagged with `er` - auto res = - l.push_tail(l.root, l.shift, tail_offst, l.tail, tail_size); - r = {l.size + r.size, get<0>(res), get<1>(res), r.tail->inc()}; - return; - } else if (tail_size + r.size <= branches<BL>) { - // doing this in a exception way mutating way is very - // tricky while potential performance gains are - // minimal (we need to move every element of the right - // tail anyways to make space for the left tail) - // - // we could however improve this by at least moving the - // elements of the mutable tails... - auto new_tail = - node_t::copy_leaf(l.tail, tail_size, r.tail, r.size); - r = {l.size + r.size, l.shift, l.root->inc(), new_tail}; - return; - } else { - // like the immutable version. - // we could improve this also by moving elements - // instead of just copying them - auto remaining = branches<BL> - tail_size; - auto add_tail = node_t::copy_leaf_e( - er, l.tail, tail_size, r.tail, remaining); - try { - auto new_tail = - node_t::copy_leaf_e(er, r.tail, remaining, r.size); - try { - // this could be improved by making sure that the - // newly created nodes as part of the `push_tail()` - // are tagged with `er` - auto new_root = l.push_tail(l.root, - l.shift, - tail_offst, - add_tail, - branches<BL>); - r = {l.size + r.size, - get<0>(new_root), - get<1>(new_root), - new_tail}; - return; - } catch (...) { - node_t::delete_leaf(new_tail, r.size - remaining); - throw; - } - } catch (...) { - node_t::delete_leaf(add_tail, branches<BL>); - throw; - } - return; - } - } else if (l.tail_offset() == 0) { - if (supports_transient_concat) { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees_mut(er, - el, - l.tail, - tail_size, - er, - r.root, - r.shift, - r.tail_offset()); - IMMER_ASSERT_TAGGED(concated.shift() == - concated.node()->compute_shift()); - assert(concated.node()->check(concated.shift(), - l.size + r.tail_offset())); - r.size += l.size; - r.shift = concated.shift(); - r.root = concated.node(); - l.hard_reset(); - } else { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees( - l.tail, tail_size, r.root, r.shift, r.tail_offset()); - r = {l.size + r.size, - concated.shift(), - concated.node(), - r.tail->inc()}; - return; - } - } else { - if (supports_transient_concat) { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees_mut(er, - el, - l.root, - l.shift, - tail_offst, - l.tail, - tail_size, - er, - r.root, - r.shift, - r.tail_offset()); - IMMER_ASSERT_TAGGED(concated.shift() == - concated.node()->compute_shift()); - assert(concated.node()->check(concated.shift(), - l.size + r.tail_offset())); - r.size += l.size; - r.shift = concated.shift(); - r.root = concated.node(); - l.hard_reset(); - } else { - auto tail_offst = l.tail_offset(); - auto tail_size = l.size - tail_offst; - auto concated = concat_trees(l.root, - l.shift, - tail_offst, - l.tail, - tail_size, - r.root, - r.shift, - r.tail_offset()); - r = {l.size + r.size, - concated.shift(), - concated.node(), - r.tail->inc()}; - } - } - } - - void hard_reset() - { - assert(supports_transient_concat); - auto&& empty_ = empty(); - size = empty_.size; - shift = empty_.shift; - root = empty_.root; - tail = empty_.tail; - } - - bool check_tree() const - { - assert(shift <= sizeof(size_t) * 8 - BL); - assert(shift >= BL); - assert(tail_offset() <= size); - assert(tail_size() <= branches<BL>); -#if IMMER_DEBUG_DEEP_CHECK - assert(check_root()); - assert(check_tail()); -#endif - return true; - } - - bool check_tail() const - { -#if IMMER_DEBUG_DEEP_CHECK - if (tail_size() > 0) - assert(tail->check(endshift<B, BL>, tail_size())); -#endif - return true; - } - - bool check_root() const - { -#if IMMER_DEBUG_DEEP_CHECK - if (tail_offset() > 0) - assert(root->check(shift, tail_offset())); - else { - IMMER_ASSERT_TAGGED(root->kind() == node_t::kind_t::inner); - assert(shift == BL); - } -#endif - return true; - } - -#if IMMER_DEBUG_PRINT - void debug_print(std::ostream& out) const - { - out << "--" << std::endl - << "{" << std::endl - << " size = " << size << std::endl - << " shift = " << shift << std::endl - << " root = " << std::endl; - debug_print_node(out, root, shift, tail_offset()); - out << " tail = " << std::endl; - debug_print_node(out, tail, endshift<B, BL>, tail_size()); - out << "}" << std::endl; - } - - void debug_print_indent(std::ostream& out, unsigned indent) const - { - while (indent-- > 0) - out << ' '; - } - - void debug_print_node(std::ostream& out, - node_t* node, - shift_t shift, - size_t size, - unsigned indent = 8) const - { - const auto indent_step = 4; - - if (shift == endshift<B, BL>) { - debug_print_indent(out, indent); - out << "- {" << size << "} " - << pretty_print_array(node->leaf(), size) << std::endl; - } else if (auto r = node->relaxed()) { - auto count = r->d.count; - debug_print_indent(out, indent); - out << "# {" << size << "} " - << pretty_print_array(r->d.sizes, r->d.count) << std::endl; - auto last_size = size_t{}; - for (auto i = count_t{}; i < count; ++i) { - debug_print_node(out, - node->inner()[i], - shift - B, - r->d.sizes[i] - last_size, - indent + indent_step); - last_size = r->d.sizes[i]; - } - } else { - debug_print_indent(out, indent); - out << "+ {" << size << "}" << std::endl; - auto count = - (size >> shift) + (size - ((size >> shift) << shift) > 0); - if (count) { - for (auto i = count_t{}; i < count - 1; ++i) - debug_print_node(out, - node->inner()[i], - shift - B, - 1 << shift, - indent + indent_step); - debug_print_node(out, - node->inner()[count - 1], - shift - B, - size - ((count - 1) << shift), - indent + indent_step); - } - } - } -#endif // IMMER_DEBUG_PRINT -}; - -} // namespace rbts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/rbts/rrbtree_iterator.hpp b/third_party/immer/immer/detail/rbts/rrbtree_iterator.hpp deleted file mode 100644 index af967774e7ef..000000000000 --- a/third_party/immer/immer/detail/rbts/rrbtree_iterator.hpp +++ /dev/null @@ -1,98 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/iterator_facade.hpp> -#include <immer/detail/rbts/rrbtree.hpp> - -namespace immer { -namespace detail { -namespace rbts { - -template <typename T, typename MP, bits_t B, bits_t BL> -struct rrbtree_iterator - : iterator_facade<rrbtree_iterator<T, MP, B, BL>, - std::random_access_iterator_tag, - T, - const T&, - std::ptrdiff_t, - const T*> -{ - using tree_t = rrbtree<T, MP, B, BL>; - using region_t = std::tuple<const T*, size_t, size_t>; - - struct end_t - {}; - - const tree_t& impl() const { return *v_; } - size_t index() const { return i_; } - - rrbtree_iterator() = default; - - rrbtree_iterator(const tree_t& v) - : v_{&v} - , i_{0} - , curr_{nullptr, ~size_t{}, ~size_t{}} - {} - - rrbtree_iterator(const tree_t& v, end_t) - : v_{&v} - , i_{v.size} - , curr_{nullptr, ~size_t{}, ~size_t{}} - {} - -private: - friend iterator_core_access; - - const tree_t* v_; - size_t i_; - mutable region_t curr_; - - void increment() - { - using std::get; - assert(i_ < v_->size); - ++i_; - } - - void decrement() - { - using std::get; - assert(i_ > 0); - --i_; - } - - void advance(std::ptrdiff_t n) - { - using std::get; - assert(n <= 0 || i_ + static_cast<size_t>(n) <= v_->size); - assert(n >= 0 || static_cast<size_t>(-n) <= i_); - i_ += n; - } - - bool equal(const rrbtree_iterator& other) const { return i_ == other.i_; } - - std::ptrdiff_t distance_to(const rrbtree_iterator& other) const - { - return other.i_ > i_ ? static_cast<std::ptrdiff_t>(other.i_ - i_) - : -static_cast<std::ptrdiff_t>(i_ - other.i_); - } - - const T& dereference() const - { - using std::get; - if (i_ < get<1>(curr_) || i_ >= get<2>(curr_)) - curr_ = v_->region_for(i_); - return get<0>(curr_)[i_ - get<1>(curr_)]; - } -}; - -} // namespace rbts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/rbts/visitor.hpp b/third_party/immer/immer/detail/rbts/visitor.hpp deleted file mode 100644 index 38cd030c4a9f..000000000000 --- a/third_party/immer/immer/detail/rbts/visitor.hpp +++ /dev/null @@ -1,56 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/config.hpp> - -#include <tuple> -#include <utility> - -namespace immer { -namespace detail { -namespace rbts { - -template <typename Deriv> -struct visitor_base -{ - template <typename... Args> - static decltype(auto) visit_node(Args&&... args) - { - IMMER_UNREACHABLE; - } - - template <typename... Args> - static decltype(auto) visit_relaxed(Args&&... args) - { - return Deriv::visit_inner(std::forward<Args>(args)...); - } - - template <typename... Args> - static decltype(auto) visit_regular(Args&&... args) - { - return Deriv::visit_inner(std::forward<Args>(args)...); - } - - template <typename... Args> - static decltype(auto) visit_inner(Args&&... args) - { - return Deriv::visit_node(std::forward<Args>(args)...); - } - - template <typename... Args> - static decltype(auto) visit_leaf(Args&&... args) - { - return Deriv::visit_node(std::forward<Args>(args)...); - } -}; - -} // namespace rbts -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/ref_count_base.hpp b/third_party/immer/immer/detail/ref_count_base.hpp deleted file mode 100644 index 28f2e46a99f9..000000000000 --- a/third_party/immer/immer/detail/ref_count_base.hpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <atomic> - -namespace immer { -namespace detail { - -template <typename Deriv> -struct ref_count_base -{ - mutable std::atomic<int> ref_count{0}; - - friend void intrusive_ptr_add_ref(const Deriv* x) - { - x->ref_count.fetch_add(1, std::memory_order_relaxed); - } - - friend void intrusive_ptr_release(const Deriv* x) - { - if (x->ref_count.fetch_sub(1, std::memory_order_release) == 1) { - std::atomic_thread_fence(std::memory_order_acquire); - delete x; - } - } -}; - -} /* namespace detail */ -} /* namespace immer */ diff --git a/third_party/immer/immer/detail/type_traits.hpp b/third_party/immer/immer/detail/type_traits.hpp deleted file mode 100644 index afb2652c55a8..000000000000 --- a/third_party/immer/immer/detail/type_traits.hpp +++ /dev/null @@ -1,223 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <algorithm> -#include <iterator> -#include <memory> -#include <type_traits> -#include <utility> - -namespace immer { -namespace detail { - -template <typename... Ts> -struct make_void -{ - using type = void; -}; - -template <typename... Ts> -using void_t = typename make_void<Ts...>::type; - -template <typename T, typename = void> -struct is_dereferenceable : std::false_type -{}; - -template <typename T> -struct is_dereferenceable<T, void_t<decltype(*(std::declval<T&>()))>> - : std::true_type -{}; - -template <typename T> -constexpr bool is_dereferenceable_v = is_dereferenceable<T>::value; - -template <typename T, typename U = T, typename = void> -struct is_equality_comparable : std::false_type -{}; - -template <typename T, typename U> -struct is_equality_comparable< - T, - U, - std::enable_if_t<std::is_same<bool, - decltype(std::declval<T&>() == - std::declval<U&>())>::value>> - : std::true_type -{}; - -template <typename T, typename U = T> -constexpr bool is_equality_comparable_v = is_equality_comparable<T, U>::value; - -template <typename T, typename U = T, typename = void> -struct is_inequality_comparable : std::false_type -{}; - -template <typename T, typename U> -struct is_inequality_comparable< - T, - U, - std::enable_if_t<std::is_same<bool, - decltype(std::declval<T&>() != - std::declval<U&>())>::value>> - : std::true_type -{}; - -template <typename T, typename U = T> -constexpr bool is_inequality_comparable_v = - is_inequality_comparable<T, U>::value; - -template <typename T, typename = void> -struct is_preincrementable : std::false_type -{}; - -template <typename T> -struct is_preincrementable< - T, - std::enable_if_t<std::is_same<T&, decltype(++(std::declval<T&>()))>::value>> - : std::true_type -{}; - -template <typename T> -constexpr bool is_preincrementable_v = is_preincrementable<T>::value; - -template <typename T, typename U = T, typename = void> -struct is_subtractable : std::false_type -{}; - -template <typename T, typename U> -struct is_subtractable< - T, - U, - void_t<decltype(std::declval<T&>() - std::declval<U&>())>> : std::true_type -{}; - -template <typename T, typename U = T> -constexpr bool is_subtractable_v = is_subtractable<T, U>::value; - -namespace swappable { - -using std::swap; - -template <typename T, typename U, typename = void> -struct with : std::false_type -{}; - -// Does not account for non-referenceable types -template <typename T, typename U> -struct with<T, - U, - void_t<decltype(swap(std::declval<T&>(), std::declval<U&>())), - decltype(swap(std::declval<U&>(), std::declval<T&>()))>> - : std::true_type -{}; - -} // namespace swappable - -template <typename T, typename U> -using is_swappable_with = swappable::with<T, U>; - -template <typename T> -using is_swappable = is_swappable_with<T, T>; - -template <typename T> -constexpr bool is_swappable_v = is_swappable_with<T&, T&>::value; - -template <typename T, typename = void> -struct is_iterator : std::false_type -{}; - -// See http://en.cppreference.com/w/cpp/concept/Iterator -template <typename T> -struct is_iterator< - T, - void_t< - std::enable_if_t<is_preincrementable_v<T> && - is_dereferenceable_v<T> - // accounts for non-referenceable types - && std::is_copy_constructible<T>::value && - std::is_copy_assignable<T>::value && - std::is_destructible<T>::value && is_swappable_v<T>>, - typename std::iterator_traits<T>::value_type, - typename std::iterator_traits<T>::difference_type, - typename std::iterator_traits<T>::reference, - typename std::iterator_traits<T>::pointer, - typename std::iterator_traits<T>::iterator_category>> : std::true_type -{}; - -template <typename T> -constexpr bool is_iterator_v = is_iterator<T>::value; - -template <typename T, typename U, typename = void> -struct compatible_sentinel : std::false_type -{}; - -template <typename T, typename U> -struct compatible_sentinel< - T, - U, - std::enable_if_t<is_iterator_v<T> && is_equality_comparable_v<T, U> && - is_inequality_comparable_v<T, U>>> : std::true_type -{}; - -template <typename T, typename U> -constexpr bool compatible_sentinel_v = compatible_sentinel<T, U>::value; - -template <typename T, typename = void> -struct is_forward_iterator : std::false_type -{}; - -template <typename T> -struct is_forward_iterator< - T, - std::enable_if_t<is_iterator_v<T> && - std::is_base_of<std::forward_iterator_tag, - typename std::iterator_traits< - T>::iterator_category>::value>> - : std::true_type -{}; - -template <typename T> -constexpr bool is_forward_iterator_v = is_forward_iterator<T>::value; - -template <typename T, typename U, typename = void> -struct std_distance_supports : std::false_type -{}; - -template <typename T, typename U> -struct std_distance_supports< - T, - U, - void_t<decltype(std::distance(std::declval<T>(), std::declval<U>()))>> - : std::true_type -{}; - -template <typename T, typename U> -constexpr bool std_distance_supports_v = std_distance_supports<T, U>::value; - -template <typename T, typename U, typename V, typename = void> -struct std_uninitialized_copy_supports : std::false_type -{}; - -template <typename T, typename U, typename V> -struct std_uninitialized_copy_supports< - T, - U, - V, - void_t<decltype(std::uninitialized_copy( - std::declval<T>(), std::declval<U>(), std::declval<V>()))>> - : std::true_type -{}; - -template <typename T, typename U, typename V> -constexpr bool std_uninitialized_copy_supports_v = - std_uninitialized_copy_supports<T, U, V>::value; - -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/detail/util.hpp b/third_party/immer/immer/detail/util.hpp deleted file mode 100644 index fb2a520fc78f..000000000000 --- a/third_party/immer/immer/detail/util.hpp +++ /dev/null @@ -1,258 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/config.hpp> - -#include <cstddef> -#include <memory> -#include <new> -#include <type_traits> - -#include <immer/detail/type_traits.hpp> - -#if defined(_MSC_VER) -#include <intrin.h> // for __lzcnt* -#endif - -namespace immer { -namespace detail { - -template <typename T> -using aligned_storage_for = - typename std::aligned_storage<sizeof(T), alignof(T)>::type; - -template <typename T> -T& auto_const_cast(const T& x) -{ - return const_cast<T&>(x); -} -template <typename T> -T&& auto_const_cast(const T&& x) -{ - return const_cast<T&&>(std::move(x)); -} - -template <typename Iter1, typename Iter2> -auto uninitialized_move(Iter1 in1, Iter1 in2, Iter2 out) -{ - return std::uninitialized_copy( - std::make_move_iterator(in1), std::make_move_iterator(in2), out); -} - -template <class T> -void destroy(T* first, T* last) -{ - for (; first != last; ++first) - first->~T(); -} - -template <class T, class Size> -void destroy_n(T* p, Size n) -{ - auto e = p + n; - for (; p != e; ++p) - p->~T(); -} - -template <typename Heap, typename T, typename... Args> -T* make(Args&&... args) -{ - auto ptr = Heap::allocate(sizeof(T)); - try { - return new (ptr) T{std::forward<Args>(args)...}; - } catch (...) { - Heap::deallocate(sizeof(T), ptr); - throw; - } -} - -struct not_supported_t -{}; -struct empty_t -{}; - -template <typename T> -struct exact_t -{ - T value; - exact_t(T v) - : value{v} {}; -}; - -template <typename T> -inline constexpr auto clz_(T) -> not_supported_t -{ - IMMER_UNREACHABLE; - return {}; -} -#if defined(_MSC_VER) -// inline auto clz_(unsigned short x) { return __lzcnt16(x); } -// inline auto clz_(unsigned int x) { return __lzcnt(x); } -// inline auto clz_(unsigned __int64 x) { return __lzcnt64(x); } -#else -inline constexpr auto clz_(unsigned int x) { return __builtin_clz(x); } -inline constexpr auto clz_(unsigned long x) { return __builtin_clzl(x); } -inline constexpr auto clz_(unsigned long long x) { return __builtin_clzll(x); } -#endif - -template <typename T> -inline constexpr T log2_aux(T x, T r = 0) -{ - return x <= 1 ? r : log2_aux(x >> 1, r + 1); -} - -template <typename T> -inline constexpr auto log2(T x) -> std:: - enable_if_t<!std::is_same<decltype(clz_(x)), not_supported_t>::value, T> -{ - return x == 0 ? 0 : sizeof(std::size_t) * 8 - 1 - clz_(x); -} - -template <typename T> -inline constexpr auto log2(T x) - -> std::enable_if_t<std::is_same<decltype(clz_(x)), not_supported_t>::value, - T> -{ - return log2_aux(x); -} - -template <bool b, typename F> -auto static_if(F&& f) -> std::enable_if_t<b> -{ - std::forward<F>(f)(empty_t{}); -} -template <bool b, typename F> -auto static_if(F&& f) -> std::enable_if_t<!b> -{} - -template <bool b, typename R = void, typename F1, typename F2> -auto static_if(F1&& f1, F2&& f2) -> std::enable_if_t<b, R> -{ - return std::forward<F1>(f1)(empty_t{}); -} -template <bool b, typename R = void, typename F1, typename F2> -auto static_if(F1&& f1, F2&& f2) -> std::enable_if_t<!b, R> -{ - return std::forward<F2>(f2)(empty_t{}); -} - -template <typename T, T value> -struct constantly -{ - template <typename... Args> - T operator()(Args&&...) const - { - return value; - } -}; - -/*! - * An alias to `std::distance` - */ -template <typename Iterator, - typename Sentinel, - std::enable_if_t<detail::std_distance_supports_v<Iterator, Sentinel>, - bool> = true> -typename std::iterator_traits<Iterator>::difference_type -distance(Iterator first, Sentinel last) -{ - return std::distance(first, last); -} - -/*! - * Equivalent of the `std::distance` applied to the sentinel-delimited - * forward range @f$ [first, last) @f$ - */ -template <typename Iterator, - typename Sentinel, - std::enable_if_t< - (!detail::std_distance_supports_v<Iterator, Sentinel>) &&detail:: - is_forward_iterator_v<Iterator> && - detail::compatible_sentinel_v<Iterator, Sentinel> && - (!detail::is_subtractable_v<Sentinel, Iterator>), - bool> = true> -typename std::iterator_traits<Iterator>::difference_type -distance(Iterator first, Sentinel last) -{ - std::size_t result = 0; - while (first != last) { - ++first; - ++result; - } - return result; -} - -/*! - * Equivalent of the `std::distance` applied to the sentinel-delimited - * random access range @f$ [first, last) @f$ - */ -template <typename Iterator, - typename Sentinel, - std::enable_if_t< - (!detail::std_distance_supports_v<Iterator, Sentinel>) &&detail:: - is_forward_iterator_v<Iterator> && - detail::compatible_sentinel_v<Iterator, Sentinel> && - detail::is_subtractable_v<Sentinel, Iterator>, - bool> = true> -typename std::iterator_traits<Iterator>::difference_type -distance(Iterator first, Sentinel last) -{ - return last - first; -} - -/*! - * An alias to `std::uninitialized_copy` - */ -template < - typename Iterator, - typename Sentinel, - typename SinkIter, - std::enable_if_t< - detail::std_uninitialized_copy_supports_v<Iterator, Sentinel, SinkIter>, - bool> = true> -SinkIter uninitialized_copy(Iterator first, Sentinel last, SinkIter d_first) -{ - return std::uninitialized_copy(first, last, d_first); -} - -/*! - * Equivalent of the `std::uninitialized_copy` applied to the - * sentinel-delimited forward range @f$ [first, last) @f$ - */ -template <typename SourceIter, - typename Sent, - typename SinkIter, - std::enable_if_t< - (!detail::std_uninitialized_copy_supports_v<SourceIter, - Sent, - SinkIter>) &&detail:: - compatible_sentinel_v<SourceIter, Sent> && - detail::is_forward_iterator_v<SinkIter>, - bool> = true> -SinkIter uninitialized_copy(SourceIter first, Sent last, SinkIter d_first) -{ - auto current = d_first; - try { - while (first != last) { - *current++ = *first; - ++first; - } - } catch (...) { - using Value = typename std::iterator_traits<SinkIter>::value_type; - for (; d_first != current; ++d_first) { - d_first->~Value(); - } - throw; - } - return current; -} - -} // namespace detail -} // namespace immer diff --git a/third_party/immer/immer/experimental/detail/dvektor_impl.hpp b/third_party/immer/immer/experimental/detail/dvektor_impl.hpp deleted file mode 100644 index 81dbbc59f5f3..000000000000 --- a/third_party/immer/immer/experimental/detail/dvektor_impl.hpp +++ /dev/null @@ -1,498 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/heap/heap_policy.hpp> -#include <immer/refcount/enable_intrusive_ptr.hpp> -#include <immer/refcount/refcount_policy.hpp> - -#include <boost/intrusive_ptr.hpp> -#include <boost/iterator/iterator_facade.hpp> -#include <boost/smart_ptr/intrusive_ref_counter.hpp> - -#include <cassert> -#include <limits> - -namespace immer { -namespace detail { -namespace dvektor { - -constexpr auto fast_log2(std::size_t x) -{ - return x == 0 ? 0 : sizeof(std::size_t) * 8 - 1 - __builtin_clzl(x); -} - -template <int B, typename T = std::size_t> -constexpr T branches = T{1} << B; - -template <int B, typename T = std::size_t> -constexpr T mask = branches<B, T> - 1; - -template <int B, typename T = std::size_t> -constexpr auto - max_depth = fast_log2(std::numeric_limits<std::size_t>::max()) / B; - -template <typename T, int B, typename MP> -struct node; - -template <typename T, int B, typename MP> -using node_ptr = boost::intrusive_ptr<node<T, B, MP>>; - -template <typename T, int B> -using leaf_node = std::array<T, 1 << B>; - -template <typename T, int B, typename MP> -using inner_node = std::array<node_ptr<T, B, MP>, 1 << B>; - -template <typename T, int B, typename MP> -struct node - : enable_intrusive_ptr<node<T, B, MP>, typename MP::refcount> - , enable_optimized_heap_policy<node<T, B, MP>, typename MP::heap> -{ - using leaf_node_t = leaf_node<T, B>; - using inner_node_t = inner_node<T, B, MP>; - - enum - { - leaf_kind, - inner_kind - } kind; - - union data_t - { - leaf_node_t leaf; - inner_node_t inner; - data_t(leaf_node_t n) - : leaf(std::move(n)) - {} - data_t(inner_node_t n) - : inner(std::move(n)) - {} - ~data_t() {} - } data; - - ~node() - { - switch (kind) { - case leaf_kind: - data.leaf.~leaf_node_t(); - break; - case inner_kind: - data.inner.~inner_node_t(); - break; - } - } - - node(leaf_node<T, B> n) - : kind{leaf_kind} - , data{std::move(n)} - {} - - node(inner_node<T, B, MP> n) - : kind{inner_kind} - , data{std::move(n)} - {} - - inner_node_t& inner() & - { - assert(kind == inner_kind); - return data.inner; - } - const inner_node_t& inner() const& - { - assert(kind == inner_kind); - return data.inner; - } - inner_node_t&& inner() && - { - assert(kind == inner_kind); - return std::move(data.inner); - } - - leaf_node_t& leaf() & - { - assert(kind == leaf_kind); - return data.leaf; - } - const leaf_node_t& leaf() const& - { - assert(kind == leaf_kind); - return data.leaf; - } - leaf_node_t&& leaf() && - { - assert(kind == leaf_kind); - return std::move(data.leaf); - } -}; - -template <typename T, int B, typename MP, typename... Ts> -auto make_node(Ts&&... xs) -> boost::intrusive_ptr<node<T, B, MP>> -{ - return new node<T, B, MP>(std::forward<Ts>(xs)...); -} - -template <typename T, int B, typename MP> -struct ref -{ - using inner_t = inner_node<T, B, MP>; - using leaf_t = leaf_node<T, B>; - using node_t = node<T, B, MP>; - using node_ptr_t = node_ptr<T, B, MP>; - - unsigned depth; - std::array<node_ptr_t, max_depth<B>> display; - - template <typename... Ts> - static auto make_node(Ts&&... xs) - { - return dvektor::make_node<T, B, MP>(std::forward<Ts>(xs)...); - } - - const T& get_elem(std::size_t index, std::size_t xr) const - { - auto display_idx = fast_log2(xr) / B; - auto node = display[display_idx].get(); - auto shift = display_idx * B; - while (display_idx--) { - node = node->inner()[(index >> shift) & mask<B>].get(); - shift -= B; - } - return node->leaf()[index & mask<B>]; - } - - node_ptr_t null_slot_and_copy_inner(node_ptr_t& node, std::size_t idx) - { - auto& n = node->inner(); - auto x = node_ptr_t{}; - x.swap(n[idx]); - return copy_of_inner(x); - } - - node_ptr_t null_slot_and_copy_leaf(node_ptr_t& node, std::size_t idx) - { - auto& n = node->inner(); - auto x = node_ptr_t{}; - x.swap(n[idx]); - return copy_of_leaf(x); - } - - node_ptr_t copy_of_inner(const node_ptr_t& n) - { - return make_node(n->inner()); - } - - node_ptr_t copy_of_leaf(const node_ptr_t& n) - { - return make_node(n->leaf()); - } - - void stabilize(std::size_t index) - { - auto shift = B; - for (auto i = 1u; i < depth; ++i) { - display[i] = copy_of_inner(display[i]); - display[i]->inner()[(index >> shift) & mask<B>] = display[i - 1]; - shift += B; - } - } - - void goto_pos_writable_from_clean(std::size_t old_index, - std::size_t index, - std::size_t xr) - { - assert(depth); - auto d = depth - 1; - if (d == 0) { - display[0] = copy_of_leaf(display[0]); - } else { - IMMER_UNREACHABLE; - display[d] = copy_of_inner(display[d]); - auto shift = B * d; - while (--d) { - display[d] = null_slot_and_copy_inner( - display[d + 1], (index >> shift) & mask<B>); - shift -= B; - } - display[0] = - null_slot_and_copy_leaf(display[1], (index >> B) & mask<B>); - } - } - - void goto_pos_writable_from_dirty(std::size_t old_index, - std::size_t new_index, - std::size_t xr) - { - assert(depth); - if (xr < (1 << B)) { - display[0] = copy_of_leaf(display[0]); - } else { - auto display_idx = fast_log2(xr) / B; - auto shift = B; - for (auto i = 1u; i <= display_idx; ++i) { - display[i] = copy_of_inner(display[i]); - display[i]->inner()[(old_index >> shift) & mask<B>] = - display[i - 1]; - shift += B; - } - for (auto i = display_idx - 1; i > 0; --i) { - shift -= B; - display[i] = null_slot_and_copy_inner( - display[i + 1], (new_index >> shift) & mask<B>); - } - display[0] = - null_slot_and_copy_leaf(display[1], (new_index >> B) & mask<B>); - } - } - - void goto_fresh_pos_writable_from_clean(std::size_t old_index, - std::size_t new_index, - std::size_t xr) - { - auto display_idx = fast_log2(xr) / B; - if (display_idx > 0) { - auto shift = display_idx * B; - if (display_idx == depth) { - display[display_idx] = make_node(inner_t{}); - display[display_idx]->inner()[(old_index >> shift) & mask<B>] = - display[display_idx - 1]; - ++depth; - } - while (--display_idx) { - auto node = display[display_idx + 1] - ->inner()[(new_index >> shift) & mask<B>]; - display[display_idx] = - node ? std::move(node) : make_node(inner_t{}); - } - display[0] = make_node(leaf_t{}); - } - } - - void goto_fresh_pos_writable_from_dirty(std::size_t old_index, - std::size_t new_index, - std::size_t xr) - { - stabilize(old_index); - goto_fresh_pos_writable_from_clean(old_index, new_index, xr); - } - - void goto_next_block_start(std::size_t index, std::size_t xr) - { - auto display_idx = fast_log2(xr) / B; - auto shift = display_idx * B; - if (display_idx > 0) { - display[display_idx - 1] = - display[display_idx]->inner()[(index >> shift) & mask<B>]; - while (--display_idx) - display[display_idx - 1] = display[display_idx]->inner()[0]; - } - } - - void goto_pos(std::size_t index, std::size_t xr) - { - auto display_idx = fast_log2(xr) / B; - auto shift = display_idx * B; - if (display_idx) { - do { - display[display_idx - 1] = - display[display_idx]->inner()[(index >> shift) & mask<B>]; - shift -= B; - } while (--display_idx); - } - } -}; - -template <typename T, int B, typename MP> -struct impl -{ - using inner_t = inner_node<T, B, MP>; - using leaf_t = leaf_node<T, B>; - using node_t = node<T, B, MP>; - using node_ptr_t = node_ptr<T, B, MP>; - using ref_t = ref<T, B, MP>; - - std::size_t size; - std::size_t focus; - bool dirty; - ref_t p; - - template <typename... Ts> - static auto make_node(Ts&&... xs) - { - return dvektor::make_node<T, B, MP>(std::forward<Ts>(xs)...); - } - - void goto_pos_writable(std::size_t old_index, - std::size_t new_index, - std::size_t xr) - { - if (dirty) { - p.goto_pos_writable_from_dirty(old_index, new_index, xr); - } else { - p.goto_pos_writable_from_clean(old_index, new_index, xr); - dirty = true; - } - } - - void goto_fresh_pos_writable(std::size_t old_index, - std::size_t new_index, - std::size_t xr) - { - if (dirty) { - p.goto_fresh_pos_writable_from_dirty(old_index, new_index, xr); - } else { - p.goto_fresh_pos_writable_from_clean(old_index, new_index, xr); - dirty = true; - } - } - - impl push_back(T value) const - { - if (size) { - auto block_index = size & ~mask<B>; - auto lo = size & mask<B>; - if (size != block_index) { - auto s = impl{size + 1, block_index, dirty, p}; - s.goto_pos_writable(focus, block_index, focus ^ block_index); - s.p.display[0]->leaf()[lo] = std::move(value); - return s; - } else { - auto s = impl{size + 1, block_index, dirty, p}; - s.goto_fresh_pos_writable( - focus, block_index, focus ^ block_index); - s.p.display[0]->leaf()[lo] = std::move(value); - return s; - } - } else { - return impl{ - 1, 0, false, {1, {{make_node(leaf_t{{std::move(value)}})}}}}; - } - } - - const T& get(std::size_t index) const - { - return p.get_elem(index, index ^ focus); - } - - template <typename FnT> - impl update(std::size_t idx, FnT&& fn) const - { - auto s = impl{size, idx, dirty, p}; - s.goto_pos_writable(focus, idx, focus ^ idx); - auto& v = s.p.display[0]->leaf()[idx & mask<B>]; - v = fn(std::move(v)); - return s; - } - - impl assoc(std::size_t idx, T value) const - { - return update(idx, [&](auto&&) { return std::move(value); }); - } -}; - -template <typename T, int B, typename MP> -const impl<T, B, MP> empty = {0, 0, false, ref<T, B, MP>{1, {}}}; - -template <typename T, int B, typename MP> -struct iterator - : boost::iterator_facade<iterator<T, B, MP>, - T, - boost::random_access_traversal_tag, - const T&> -{ - struct end_t - {}; - - iterator() = default; - - iterator(const impl<T, B, MP>& v) - : p_{v.p} - , i_{0} - , base_{0} - { - if (v.dirty) - p_.stabilize(v.focus); - p_.goto_pos(0, 0 ^ v.focus); - curr_ = p_.display[0]->leaf().begin(); - } - - iterator(const impl<T, B, MP>& v, end_t) - : p_{v.p} - , i_{v.size} - , base_{(v.size - 1) & ~mask<B>} - { - if (v.dirty) - p_.stabilize(v.focus); - p_.goto_pos(base_, base_ ^ v.focus); - curr_ = p_.display[0]->leaf().begin() + (i_ - base_); - } - -private: - friend class boost::iterator_core_access; - using leaf_iterator = typename leaf_node<T, B>::const_iterator; - - ref<T, B, MP> p_; - std::size_t i_; - std::size_t base_; - leaf_iterator curr_; - - void increment() - { - ++i_; - if (i_ - base_ < branches<B>) { - ++curr_; - } else { - auto new_base = base_ + branches<B>; - p_.goto_next_block_start(new_base, base_ ^ new_base); - base_ = new_base; - curr_ = p_.display[0]->leaf().begin(); - } - } - - void decrement() - { - assert(i_ > 0); - --i_; - if (i_ >= base_) { - --curr_; - } else { - auto new_base = base_ - branches<B>; - p_.goto_pos(new_base, base_ ^ new_base); - base_ = new_base; - curr_ = std::prev(p_.display[0]->leaf().end()); - } - } - - void advance(std::ptrdiff_t n) - { - i_ += n; - if (i_ <= base_ && i_ - base_ < branches<B>) { - curr_ += n; - } else { - auto new_base = i_ & ~mask<B>; - p_.goto_pos(new_base, base_ ^ new_base); - base_ = new_base; - curr_ = p_.display[0]->leaf().begin() + (i_ - base_); - } - } - - bool equal(const iterator& other) const { return i_ == other.i_; } - - std::ptrdiff_t distance_to(const iterator& other) const - { - return other.i_ > i_ ? static_cast<std::ptrdiff_t>(other.i_ - i_) - : -static_cast<std::ptrdiff_t>(i_ - other.i_); - } - - const T& dereference() const { return *curr_; } -}; - -} /* namespace dvektor */ -} /* namespace detail */ -} /* namespace immer */ diff --git a/third_party/immer/immer/experimental/dvektor.hpp b/third_party/immer/immer/experimental/dvektor.hpp deleted file mode 100644 index e809e749d5df..000000000000 --- a/third_party/immer/immer/experimental/dvektor.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/experimental/detail/dvektor_impl.hpp> - -#include <immer/memory_policy.hpp> - -namespace immer { - -template <typename T, int B = 5, typename MemoryPolicy = default_memory_policy> -class dvektor -{ - using impl_t = detail::dvektor::impl<T, B, MemoryPolicy>; - -public: - using value_type = T; - using reference = const T&; - using size_type = std::size_t; - using difference_type = std::ptrdiff_t; - using const_reference = const T&; - - using iterator = detail::dvektor::iterator<T, B, MemoryPolicy>; - using const_iterator = iterator; - using reverse_iterator = std::reverse_iterator<iterator>; - - dvektor() = default; - - iterator begin() const { return {impl_}; } - iterator end() const { return {impl_, typename iterator::end_t{}}; } - - reverse_iterator rbegin() const { return reverse_iterator{end()}; } - reverse_iterator rend() const { return reverse_iterator{begin()}; } - - std::size_t size() const { return impl_.size; } - bool empty() const { return impl_.size == 0; } - - reference operator[](size_type index) const { return impl_.get(index); } - - dvektor push_back(value_type value) const - { - return {impl_.push_back(std::move(value))}; - } - - dvektor assoc(std::size_t idx, value_type value) const - { - return {impl_.assoc(idx, std::move(value))}; - } - - template <typename FnT> - dvektor update(std::size_t idx, FnT&& fn) const - { - return {impl_.update(idx, std::forward<FnT>(fn))}; - } - -private: - dvektor(impl_t impl) - : impl_(std::move(impl)) - {} - impl_t impl_ = detail::dvektor::empty<T, B, MemoryPolicy>; -}; - -} // namespace immer diff --git a/third_party/immer/immer/flex_vector.hpp b/third_party/immer/immer/flex_vector.hpp deleted file mode 100644 index d03c3f7e4585..000000000000 --- a/third_party/immer/immer/flex_vector.hpp +++ /dev/null @@ -1,608 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/rbts/rrbtree.hpp> -#include <immer/detail/rbts/rrbtree_iterator.hpp> -#include <immer/memory_policy.hpp> - -namespace immer { - -template <typename T, - typename MP, - detail::rbts::bits_t B, - detail::rbts::bits_t BL> -class vector; - -template <typename T, - typename MP, - detail::rbts::bits_t B, - detail::rbts::bits_t BL> -class flex_vector_transient; - -/*! - * Immutable sequential container supporting both random access, - * structural sharing and efficient concatenation and slicing. - * - * @tparam T The type of the values to be stored in the container. - * @tparam MemoryPolicy Memory management policy. See @ref - * memory_policy. - * - * @rst - * - * This container is very similar to `vector`_ but also supports - * :math:`O(log(size))` *concatenation*, *slicing* and *insertion* at - * any point. Its performance characteristics are almost identical - * until one of these operations is performed. After that, - * performance is degraded by a constant factor that usually oscilates - * in the range :math:`[1, 2)` depending on the operation and the - * amount of flexible operations that have been performed. - * - * .. tip:: A `vector`_ can be converted to a `flex_vector`_ in - * constant time without any allocation. This is so because the - * internal structure of a *vector* is a strict subset of the - * internal structure of a *flexible vector*. You can take - * advantage of this property by creating normal vectors as long as - * the flexible operations are not needed, and convert later in - * your processing pipeline once and if these are needed. - * - * @endrst - */ -template <typename T, - typename MemoryPolicy = default_memory_policy, - detail::rbts::bits_t B = default_bits, - detail::rbts::bits_t BL = - detail::rbts::derive_bits_leaf<T, MemoryPolicy, B>> -class flex_vector -{ - using impl_t = detail::rbts::rrbtree<T, MemoryPolicy, B, BL>; - - using move_t = - std::integral_constant<bool, MemoryPolicy::use_transient_rvalues>; - -public: - static constexpr auto bits = B; - static constexpr auto bits_leaf = BL; - using memory_policy = MemoryPolicy; - - using value_type = T; - using reference = const T&; - using size_type = detail::rbts::size_t; - using difference_type = std::ptrdiff_t; - using const_reference = const T&; - - using iterator = detail::rbts::rrbtree_iterator<T, MemoryPolicy, B, BL>; - using const_iterator = iterator; - using reverse_iterator = std::reverse_iterator<iterator>; - - using transient_type = flex_vector_transient<T, MemoryPolicy, B, BL>; - - /*! - * Default constructor. It creates a flex_vector of `size() == 0`. - * It does not allocate memory and its complexity is @f$ O(1) @f$. - */ - flex_vector() = default; - - /*! - * Constructs a flex_vector containing the elements in `values`. - */ - flex_vector(std::initializer_list<T> values) - : impl_{impl_t::from_initializer_list(values)} - {} - - /*! - * Constructs a flex_vector containing the elements in the range - * defined by the input iterator `first` and range sentinel `last`. - */ - template <typename Iter, - typename Sent, - std::enable_if_t<detail::compatible_sentinel_v<Iter, Sent>, - bool> = true> - flex_vector(Iter first, Sent last) - : impl_{impl_t::from_range(first, last)} - {} - - /*! - * Constructs a vector containing the element `val` repeated `n` - * times. - */ - flex_vector(size_type n, T v = {}) - : impl_{impl_t::from_fill(n, v)} - {} - - /*! - * Default constructor. It creates a flex_vector with the same - * contents as `v`. It does not allocate memory and is - * @f$ O(1) @f$. - */ - flex_vector(vector<T, MemoryPolicy, B, BL> v) - : impl_{v.impl_.size, - v.impl_.shift, - v.impl_.root->inc(), - v.impl_.tail->inc()} - {} - - /*! - * Returns an iterator pointing at the first element of the - * collection. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator begin() const { return {impl_}; } - - /*! - * Returns an iterator pointing just after the last element of the - * collection. It does not allocate and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator end() const - { - return {impl_, typename iterator::end_t{}}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing at the first element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rbegin() const - { - return reverse_iterator{end()}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing after the last element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rend() const - { - return reverse_iterator{begin()}; - } - - /*! - * Returns the number of elements in the container. It does - * not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD size_type size() const { return impl_.size; } - - /*! - * Returns `true` if there are no elements in the container. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD bool empty() const { return impl_.size == 0; } - - /*! - * Access the last element. - */ - IMMER_NODISCARD const T& back() const { return impl_.back(); } - - /*! - * Access the first element. - */ - IMMER_NODISCARD const T& front() const { return impl_.front(); } - - /*! - * Returns a `const` reference to the element at position `index`. - * It is undefined when @f$ 0 index \geq size() @f$. It does not - * allocate memory and its complexity is *effectively* @f$ O(1) - * @f$. - */ - IMMER_NODISCARD reference operator[](size_type index) const - { - return impl_.get(index); - } - - /*! - * Returns a `const` reference to the element at position - * `index`. It throws an `std::out_of_range` exception when @f$ - * index \geq size() @f$. It does not allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - reference at(size_type index) const { return impl_.get_check(index); } - - /*! - * Returns whether the vectors are equal. - */ - IMMER_NODISCARD bool operator==(const flex_vector& other) const - { - return impl_.equals(other.impl_); - } - IMMER_NODISCARD bool operator!=(const flex_vector& other) const - { - return !(*this == other); - } - - /*! - * Returns a flex_vector with `value` inserted at the end. It may - * allocate memory and its complexity is *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/flex-vector/flex-vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: push-back/start - * :end-before: push-back/end - * - * @endrst - */ - IMMER_NODISCARD flex_vector push_back(value_type value) const& - { - return impl_.push_back(std::move(value)); - } - - IMMER_NODISCARD decltype(auto) push_back(value_type value) && - { - return push_back_move(move_t{}, std::move(value)); - } - - /*! - * Returns a flex_vector with `value` inserted at the frony. It may - * allocate memory and its complexity is @f$ O(log(size)) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/flex-vector/flex-vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: push-front/start - * :end-before: push-front/end - * - * @endrst - */ - IMMER_NODISCARD flex_vector push_front(value_type value) const - { - return flex_vector{}.push_back(value) + *this; - } - - /*! - * Returns a flex_vector containing value `value` at position `index`. - * Undefined for `index >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/flex-vector/flex-vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: set/start - * :end-before: set/end - * - * @endrst - */ - IMMER_NODISCARD flex_vector set(size_type index, value_type value) const& - { - return impl_.assoc(index, std::move(value)); - } - - IMMER_NODISCARD decltype(auto) set(size_type index, value_type value) && - { - return set_move(move_t{}, index, std::move(value)); - } - - /*! - * Returns a vector containing the result of the expression - * `fn((*this)[idx])` at position `idx`. - * Undefined for `index >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/flex-vector/flex-vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: update/start - * :end-before: update/end - * - * @endrst - - */ - template <typename FnT> - IMMER_NODISCARD flex_vector update(size_type index, FnT&& fn) const& - { - return impl_.update(index, std::forward<FnT>(fn)); - } - - template <typename FnT> - IMMER_NODISCARD decltype(auto) update(size_type index, FnT&& fn) && - { - return update_move(move_t{}, index, std::forward<FnT>(fn)); - } - - /*! - * Returns a vector containing only the first `min(elems, size())` - * elements. It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/flex-vector/flex-vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: take/start - * :end-before: take/end - * - * @endrst - */ - IMMER_NODISCARD flex_vector take(size_type elems) const& - { - return impl_.take(elems); - } - - IMMER_NODISCARD decltype(auto) take(size_type elems) && - { - return take_move(move_t{}, elems); - } - - /*! - * Returns a vector without the first `min(elems, size())` - * elements. It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/flex-vector/flex-vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: drop/start - * :end-before: drop/end - * - * @endrst - */ - IMMER_NODISCARD flex_vector drop(size_type elems) const& - { - return impl_.drop(elems); - } - - IMMER_NODISCARD decltype(auto) drop(size_type elems) && - { - return drop_move(move_t{}, elems); - } - - /*! - * Concatenation operator. Returns a flex_vector with the contents - * of `l` followed by those of `r`. It may allocate memory - * and its complexity is @f$ O(log(max(size_r, size_l))) @f$ - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/flex-vector/flex-vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: concat/start - * :end-before: concat/end - * - * @endrst - */ - IMMER_NODISCARD friend flex_vector operator+(const flex_vector& l, - const flex_vector& r) - { - return l.impl_.concat(r.impl_); - } - - IMMER_NODISCARD friend decltype(auto) operator+(flex_vector&& l, - const flex_vector& r) - { - return concat_move(move_t{}, std::move(l), r); - } - - IMMER_NODISCARD friend decltype(auto) operator+(const flex_vector& l, - flex_vector&& r) - { - return concat_move(move_t{}, l, std::move(r)); - } - - IMMER_NODISCARD friend decltype(auto) operator+(flex_vector&& l, - flex_vector&& r) - { - return concat_move(move_t{}, std::move(l), std::move(r)); - } - - /*! - * Returns a flex_vector with the `value` inserted at index - * `pos`. It may allocate memory and its complexity is @f$ - * O(log(size)) @f$ - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/flex-vector/flex-vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: insert/start - * :end-before: insert/end - * - * @endrst - */ - IMMER_NODISCARD flex_vector insert(size_type pos, T value) const& - { - return take(pos).push_back(std::move(value)) + drop(pos); - } - IMMER_NODISCARD decltype(auto) insert(size_type pos, T value) && - { - using std::move; - auto rs = drop(pos); - return std::move(*this).take(pos).push_back(std::move(value)) + - std::move(rs); - } - - IMMER_NODISCARD flex_vector insert(size_type pos, flex_vector value) const& - { - return take(pos) + std::move(value) + drop(pos); - } - IMMER_NODISCARD decltype(auto) insert(size_type pos, flex_vector value) && - { - using std::move; - auto rs = drop(pos); - return std::move(*this).take(pos) + std::move(value) + std::move(rs); - } - - /*! - * Returns a flex_vector without the element at index `pos`. It - * may allocate memory and its complexity is @f$ O(log(size)) @f$ - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/flex-vector/flex-vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: erase/start - * :end-before: erase/end - * - * @endrst - */ - IMMER_NODISCARD flex_vector erase(size_type pos) const& - { - return take(pos) + drop(pos + 1); - } - IMMER_NODISCARD decltype(auto) erase(size_type pos) && - { - auto rs = drop(pos + 1); - return std::move(*this).take(pos) + std::move(rs); - } - - IMMER_NODISCARD flex_vector erase(size_type pos, size_type lpos) const& - { - return lpos > pos ? take(pos) + drop(lpos) : *this; - } - IMMER_NODISCARD decltype(auto) erase(size_type pos, size_type lpos) && - { - if (lpos > pos) { - auto rs = drop(lpos); - return std::move(*this).take(pos) + std::move(rs); - } else { - return std::move(*this); - } - } - - /*! - * Returns an @a transient form of this container, an - * `immer::flex_vector_transient`. - */ - IMMER_NODISCARD transient_type transient() const& - { - return transient_type{impl_}; - } - IMMER_NODISCARD transient_type transient() && - { - return transient_type{std::move(impl_)}; - } - - // Semi-private - const impl_t& impl() const { return impl_; } - -#if IMMER_DEBUG_PRINT - void debug_print(std::ostream& out = std::cerr) const - { - impl_.debug_print(out); - } -#endif - -private: - friend transient_type; - - flex_vector(impl_t impl) - : impl_(std::move(impl)) - { -#if IMMER_DEBUG_PRINT - // force the compiler to generate debug_print, so we can call - // it from a debugger - [](volatile auto) {}(&flex_vector::debug_print); -#endif - } - - flex_vector&& push_back_move(std::true_type, value_type value) - { - impl_.push_back_mut({}, std::move(value)); - return std::move(*this); - } - flex_vector push_back_move(std::false_type, value_type value) - { - return impl_.push_back(std::move(value)); - } - - flex_vector&& set_move(std::true_type, size_type index, value_type value) - { - impl_.assoc_mut({}, index, std::move(value)); - return std::move(*this); - } - flex_vector set_move(std::false_type, size_type index, value_type value) - { - return impl_.assoc(index, std::move(value)); - } - - template <typename Fn> - flex_vector&& update_move(std::true_type, size_type index, Fn&& fn) - { - impl_.update_mut({}, index, std::forward<Fn>(fn)); - return std::move(*this); - } - template <typename Fn> - flex_vector update_move(std::false_type, size_type index, Fn&& fn) - { - return impl_.update(index, std::forward<Fn>(fn)); - } - - flex_vector&& take_move(std::true_type, size_type elems) - { - impl_.take_mut({}, elems); - return std::move(*this); - } - flex_vector take_move(std::false_type, size_type elems) - { - return impl_.take(elems); - } - - flex_vector&& drop_move(std::true_type, size_type elems) - { - impl_.drop_mut({}, elems); - return std::move(*this); - } - flex_vector drop_move(std::false_type, size_type elems) - { - return impl_.drop(elems); - } - - static flex_vector&& - concat_move(std::true_type, flex_vector&& l, const flex_vector& r) - { - concat_mut_l(l.impl_, {}, r.impl_); - return std::move(l); - } - static flex_vector&& - concat_move(std::true_type, const flex_vector& l, flex_vector&& r) - { - concat_mut_r(l.impl_, r.impl_, {}); - return std::move(r); - } - static flex_vector&& - concat_move(std::true_type, flex_vector&& l, flex_vector&& r) - { - concat_mut_lr_l(l.impl_, {}, r.impl_, {}); - return std::move(l); - } - static flex_vector - concat_move(std::false_type, const flex_vector& l, const flex_vector& r) - { - return l.impl_.concat(r.impl_); - } - - impl_t impl_ = impl_t::empty(); -}; - -} // namespace immer diff --git a/third_party/immer/immer/flex_vector_transient.hpp b/third_party/immer/immer/flex_vector_transient.hpp deleted file mode 100644 index fe0a6a534e10..000000000000 --- a/third_party/immer/immer/flex_vector_transient.hpp +++ /dev/null @@ -1,251 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/rbts/rrbtree.hpp> -#include <immer/detail/rbts/rrbtree_iterator.hpp> -#include <immer/memory_policy.hpp> - -namespace immer { - -template <typename T, - typename MemoryPolicy, - detail::rbts::bits_t B, - detail::rbts::bits_t BL> -class flex_vector; - -template <typename T, - typename MemoryPolicy, - detail::rbts::bits_t B, - detail::rbts::bits_t BL> -class vector_transient; - -/*! - * Mutable version of `immer::flex_vector`. - * - * @rst - * - * Refer to :doc:`transients` to learn more about when and how to use - * the mutable versions of immutable containers. - * - * @endrst - */ -template <typename T, - typename MemoryPolicy = default_memory_policy, - detail::rbts::bits_t B = default_bits, - detail::rbts::bits_t BL = - detail::rbts::derive_bits_leaf<T, MemoryPolicy, B>> -class flex_vector_transient : MemoryPolicy::transience_t::owner -{ - using impl_t = detail::rbts::rrbtree<T, MemoryPolicy, B, BL>; - using base_t = typename MemoryPolicy::transience_t::owner; - using owner_t = typename MemoryPolicy::transience_t::owner; - -public: - static constexpr auto bits = B; - static constexpr auto bits_leaf = BL; - using memory_policy = MemoryPolicy; - - using value_type = T; - using reference = const T&; - using size_type = detail::rbts::size_t; - using difference_type = std::ptrdiff_t; - using const_reference = const T&; - - using iterator = detail::rbts::rrbtree_iterator<T, MemoryPolicy, B, BL>; - using const_iterator = iterator; - using reverse_iterator = std::reverse_iterator<iterator>; - - using persistent_type = flex_vector<T, MemoryPolicy, B, BL>; - - /*! - * Default constructor. It creates a flex_vector of `size() == 0`. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - flex_vector_transient() = default; - - /*! - * Default constructor. It creates a flex_vector with the same - * contents as `v`. It does not allocate memory and is - * @f$ O(1) @f$. - */ - flex_vector_transient(vector_transient<T, MemoryPolicy, B, BL> v) - : base_t{std::move(static_cast<base_t&>(v))} - , impl_{v.impl_.size, - v.impl_.shift, - v.impl_.root->inc(), - v.impl_.tail->inc()} - {} - - /*! - * Returns an iterator pointing at the first element of the - * collection. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator begin() const { return {impl_}; } - - /*! - * Returns an iterator pointing just after the last element of the - * collection. It does not allocate and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator end() const - { - return {impl_, typename iterator::end_t{}}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing at the first element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rbegin() const - { - return reverse_iterator{end()}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing after the last element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rend() const - { - return reverse_iterator{begin()}; - } - - /*! - * Returns the number of elements in the container. It does - * not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD size_type size() const { return impl_.size; } - - /*! - * Returns `true` if there are no elements in the container. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD bool empty() const { return impl_.size == 0; } - - /*! - * Returns a `const` reference to the element at position `index`. - * It is undefined when @f$ 0 index \geq size() @f$. It does not - * allocate memory and its complexity is *effectively* @f$ O(1) - * @f$. - */ - reference operator[](size_type index) const { return impl_.get(index); } - - /*! - * Returns a `const` reference to the element at position - * `index`. It throws an `std::out_of_range` exception when @f$ - * index \geq size() @f$. It does not allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - reference at(size_type index) const { return impl_.get_check(index); } - - /*! - * Inserts `value` at the end. It may allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - void push_back(value_type value) - { - impl_.push_back_mut(*this, std::move(value)); - } - - /*! - * Sets to the value `value` at position `idx`. - * Undefined for `index >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - void set(size_type index, value_type value) - { - impl_.assoc_mut(*this, index, std::move(value)); - } - - /*! - * Updates the vector to contain the result of the expression - * `fn((*this)[idx])` at position `idx`. - * Undefined for `0 >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - template <typename FnT> - void update(size_type index, FnT&& fn) - { - impl_.update_mut(*this, index, std::forward<FnT>(fn)); - } - - /*! - * Resizes the vector to only contain the first `min(elems, size())` - * elements. It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - void take(size_type elems) { impl_.take_mut(*this, elems); } - - /*! - * Removes the first the first `min(elems, size())` - * elements. It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - void drop(size_type elems) { impl_.drop_mut(*this, elems); } - - /*! - * Appends the contents of the `r` at the end. It may allocate - * memory and its complexity is: - * @f$ O(log(max(size_r, size_l))) @f$ - */ - void append(flex_vector_transient& r) - { - r.owner_t::operator=(owner_t{}); - concat_mut_l(impl_, *this, r.impl_); - } - void append(flex_vector_transient&& r) - { - concat_mut_lr_l(impl_, *this, r.impl_, r); - } - - /*! - * Prepends the contents of the `l` at the beginning. It may - * allocate memory and its complexity is: - * @f$ O(log(max(size_r, size_l))) @f$ - */ - void prepend(flex_vector_transient& l) - { - l.owner_t::operator=(owner_t{}); - concat_mut_r(l.impl_, impl_, *this); - } - void prepend(flex_vector_transient&& l) - { - concat_mut_lr_r(l.impl_, l, impl_, *this); - } - - /*! - * Returns an @a immutable form of this container, an - * `immer::flex_vector`. - */ - IMMER_NODISCARD persistent_type persistent() & - { - this->owner_t::operator=(owner_t{}); - return persistent_type{impl_}; - } - IMMER_NODISCARD persistent_type persistent() && - { - return persistent_type{std::move(impl_)}; - } - -private: - friend persistent_type; - - flex_vector_transient(impl_t impl) - : impl_(std::move(impl)) - {} - - impl_t impl_ = impl_t::empty(); -}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/cpp_heap.hpp b/third_party/immer/immer/heap/cpp_heap.hpp deleted file mode 100644 index cd129b406bea..000000000000 --- a/third_party/immer/immer/heap/cpp_heap.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <memory> - -namespace immer { - -/*! - * A heap that uses `operator new` and `operator delete`. - */ -struct cpp_heap -{ - /*! - * Returns a pointer to a memory region of size `size`, if the - * allocation was successful, and throws otherwise. - */ - template <typename... Tags> - static void* allocate(std::size_t size, Tags...) - { - return ::operator new(size); - } - - /*! - * Releases a memory region `data` that was previously returned by - * `allocate`. One must not use nor deallocate again a memory - * region that once it has been deallocated. - */ - static void deallocate(std::size_t size, void* data) - { - ::operator delete(data); - } -}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/debug_size_heap.hpp b/third_party/immer/immer/heap/debug_size_heap.hpp deleted file mode 100644 index d5288c646f8d..000000000000 --- a/third_party/immer/immer/heap/debug_size_heap.hpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/config.hpp> -#include <immer/heap/identity_heap.hpp> - -#include <cassert> -#include <cstddef> -#include <type_traits> -#include <memory> - -namespace immer { - -#if IMMER_ENABLE_DEBUG_SIZE_HEAP - -/*! - * A heap that in debug mode ensures that the sizes for allocation and - * deallocation do match. - */ -template <typename Base> -struct debug_size_heap -{ -#if defined(__MINGW32__) && !defined(__MINGW64__) - // There is a bug in MinGW 32bit: - // https://sourceforge.net/p/mingw-w64/bugs/778/ It causes different - // versions of std::max_align_t to be defined, depending on inclusion order - // of stddef.h and stdint.h. As we have no control over the inclusion order - // here (as it might be set in stone by the outside world), we can't easily - // pin it to one of both versions of std::max_align_t. This means, we have - // to hardcode extra_size for MinGW 32bit builds until the mentioned bug is - // fixed. - constexpr static auto extra_size = 8; -#else - constexpr static auto extra_size = sizeof( - std::aligned_storage_t<sizeof(std::size_t), alignof(std::max_align_t)>); -#endif - - template <typename... Tags> - static void* allocate(std::size_t size, Tags... tags) - { - auto p = (std::size_t*) Base::allocate(size + extra_size, tags...); - new (p) std::size_t{size}; - return ((char*) p) + extra_size; - } - - template <typename... Tags> - static void deallocate(std::size_t size, void* data, Tags... tags) - { - auto p = (std::size_t*) (((char*) data) - extra_size); - assert(*p == size); - Base::deallocate(size + extra_size, p, tags...); - } -}; - -#else // IMMER_ENABLE_DEBUG_SIZE_HEAP - -template <typename Base> -using debug_size_heap = identity_heap<Base>; - -#endif // !IMMER_ENABLE_DEBUG_SIZE_HEAP - -} // namespace immer diff --git a/third_party/immer/immer/heap/free_list_heap.hpp b/third_party/immer/immer/heap/free_list_heap.hpp deleted file mode 100644 index dc25b10184a1..000000000000 --- a/third_party/immer/immer/heap/free_list_heap.hpp +++ /dev/null @@ -1,83 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/heap/free_list_node.hpp> -#include <immer/heap/with_data.hpp> - -#include <atomic> -#include <cassert> - -namespace immer { - -/*! - * Adaptor that does not release the memory to the parent heap but - * instead it keeps the memory in a thread-safe global free list. Must - * be preceded by a `with_data<free_list_node, ...>` heap adaptor. - * - * @tparam Size Maximum size of the objects to be allocated. - * @tparam Base Type of the parent heap. - */ -template <std::size_t Size, std::size_t Limit, typename Base> -struct free_list_heap : Base -{ - using base_t = Base; - - template <typename... Tags> - static void* allocate(std::size_t size, Tags...) - { - assert(size <= sizeof(free_list_node) + Size); - assert(size >= sizeof(free_list_node)); - - free_list_node* n; - do { - n = head().data; - if (!n) { - auto p = base_t::allocate(Size + sizeof(free_list_node)); - return static_cast<free_list_node*>(p); - } - } while (!head().data.compare_exchange_weak(n, n->next)); - head().count.fetch_sub(1u, std::memory_order_relaxed); - return n; - } - - template <typename... Tags> - static void deallocate(std::size_t size, void* data, Tags...) - { - assert(size <= sizeof(free_list_node) + Size); - assert(size >= sizeof(free_list_node)); - - // we use relaxed, because we are fine with temporarily having - // a few more/less buffers in free list - if (head().count.load(std::memory_order_relaxed) >= Limit) { - base_t::deallocate(Size + sizeof(free_list_node), data); - } else { - auto n = static_cast<free_list_node*>(data); - do { - n->next = head().data; - } while (!head().data.compare_exchange_weak(n->next, n)); - head().count.fetch_add(1u, std::memory_order_relaxed); - } - } - -private: - struct head_t - { - std::atomic<free_list_node*> data; - std::atomic<std::size_t> count; - }; - - static head_t& head() - { - static head_t head_{{nullptr}, {0}}; - return head_; - } -}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/free_list_node.hpp b/third_party/immer/immer/heap/free_list_node.hpp deleted file mode 100644 index acab4779aa43..000000000000 --- a/third_party/immer/immer/heap/free_list_node.hpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/heap/with_data.hpp> - -namespace immer { - -struct free_list_node -{ - free_list_node* next; -}; - -template <typename Base> -struct with_free_list_node : with_data<free_list_node, Base> -{}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/gc_heap.hpp b/third_party/immer/immer/heap/gc_heap.hpp deleted file mode 100644 index 8494bd26694f..000000000000 --- a/third_party/immer/immer/heap/gc_heap.hpp +++ /dev/null @@ -1,127 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/config.hpp> -#include <immer/heap/tags.hpp> - -#if IMMER_HAS_LIBGC -#include <gc/gc.h> -#else -#error "Using garbage collection requires libgc" -#endif - -#include <cstdlib> -#include <memory> - -namespace immer { - -#ifdef __APPLE__ -#define IMMER_GC_REQUIRE_INIT 1 -#else -#define IMMER_GC_REQUIRE_INIT 0 -#endif - -#if IMMER_GC_REQUIRE_INIT - -namespace detail { - -template <int Dummy = 0> -struct gc_initializer -{ - gc_initializer() { GC_init(); } - static gc_initializer init; -}; - -template <int D> -gc_initializer<D> gc_initializer<D>::init{}; - -inline void gc_initializer_guard() -{ - static gc_initializer<> init_ = gc_initializer<>::init; - (void) init_; -} - -} // namespace detail - -#define IMMER_GC_INIT_GUARD_ ::immer::detail::gc_initializer_guard() - -#else - -#define IMMER_GC_INIT_GUARD_ - -#endif // IMMER_GC_REQUIRE_INIT - -/*! - * Heap that uses a tracing garbage collector. - * - * @rst - * - * This heap uses the `Boehm's conservative garbage collector`_ under - * the hood. This is a tracing garbage collector that automatically - * reclaims unused memory. Thus, it is not needed to call - * ``deallocate()`` in order to release memory. - * - * .. admonition:: Dependencies - * :class: tip - * - * In order to use this header file, you need to make sure that - * Boehm's ``libgc`` is your include path and link to its binary - * library. - * - * .. caution:: Memory that is allocated with the standard ``malloc`` - * and ``free`` is not visible to ``libgc`` when it is looking for - * references. This means that if, let's say, you store a - * :cpp:class:`immer::vector` using a ``gc_heap`` inside a - * ``std::vector`` that uses a standard allocator, the memory of - * the former might be released automatically at unexpected times - * causing crashes. - * - * .. caution:: When using a ``gc_heap`` in combination with immutable - * containers, the destructors of the contained objects will never - * be called. It is ok to store containers inside containers as - * long as all of them use a ``gc_heap`` consistently, but storing - * other kinds of objects with relevant destructors - * (e.g. containers with reference counting or other kinds of - * *resource handles*) might cause memory leaks and other problems. - * - * .. _boehm's conservative garbage collector: https://github.com/ivmai/bdwgc - * - * @endrst - */ -class gc_heap -{ -public: - static void* allocate(std::size_t n) - { - IMMER_GC_INIT_GUARD_; - auto p = GC_malloc(n); - if (IMMER_UNLIKELY(!p)) - throw std::bad_alloc{}; - return p; - } - - static void* allocate(std::size_t n, norefs_tag) - { - IMMER_GC_INIT_GUARD_; - auto p = GC_malloc_atomic(n); - if (IMMER_UNLIKELY(!p)) - throw std::bad_alloc{}; - return p; - } - - static void deallocate(std::size_t, void* data) { GC_free(data); } - - static void deallocate(std::size_t, void* data, norefs_tag) - { - GC_free(data); - } -}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/heap_policy.hpp b/third_party/immer/immer/heap/heap_policy.hpp deleted file mode 100644 index 582c113f334f..000000000000 --- a/third_party/immer/immer/heap/heap_policy.hpp +++ /dev/null @@ -1,141 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/config.hpp> -#include <immer/heap/debug_size_heap.hpp> -#include <immer/heap/free_list_heap.hpp> -#include <immer/heap/split_heap.hpp> -#include <immer/heap/thread_local_free_list_heap.hpp> - -#include <algorithm> -#include <cstdlib> - -namespace immer { - -/*! - * Heap policy that unconditionally uses its `Heap` argument. - */ -template <typename Heap> -struct heap_policy -{ - using type = Heap; - - template <std::size_t> - struct optimized - { - using type = Heap; - }; -}; - -template <typename Deriv, typename HeapPolicy> -struct enable_optimized_heap_policy -{ - static void* operator new(std::size_t size) - { - using heap_type = - typename HeapPolicy ::template optimized<sizeof(Deriv)>::type; - - return heap_type::allocate(size); - } - - static void operator delete(void* data, std::size_t size) - { - using heap_type = - typename HeapPolicy ::template optimized<sizeof(Deriv)>::type; - - heap_type::deallocate(size, data); - } -}; - -/*! - * Heap policy that returns a heap with a free list of objects - * of `max_size = max(Sizes...)` on top an underlying `Heap`. Note - * these two properties of the resulting heap: - * - * - Allocating an object that is bigger than `max_size` may trigger - * *undefined behavior*. - * - * - Allocating an object of size less than `max_size` still - * returns an object of `max_size`. - * - * Basically, this heap will always return objects of `max_size`. - * When an object is freed, it does not directly invoke `std::free`, - * but it keeps the object in a global linked list instead. When a - * new object is requested, it does not need to call `std::malloc` but - * it can directly pop and return the other object from the global - * list, a much faster operation. - * - * This actually creates a hierarchy with two free lists: - * - * - A `thread_local` free list is used first. It does not need any - * kind of synchronization and is very fast. When the thread - * finishes, its contents are returned to the next free list. - * - * - A global free list using lock-free access via atomics. - * - * @tparam Heap Heap to be used when the free list is empty. - * - * @rst - * - * .. tip:: For many applications that use immutable data structures - * significantly, this is actually the best heap policy, and it - * might become the default in the future. - * - * Note that most our data structures internally use trees with the - * same big branching factors. This means that all *vectors*, - * *maps*, etc. can just allocate elements from the same free-list - * optimized heap. Not only does this lowers the allocation time, - * but also makes up for more efficient *cache utilization*. When - * a new node is needed, there are high chances the allocator will - * return a node that was just accessed. When batches of immutable - * updates are made, this can make a significant difference. - * - * @endrst - */ -template <typename Heap, std::size_t Limit = default_free_list_size> -struct free_list_heap_policy -{ - using type = debug_size_heap<Heap>; - - template <std::size_t Size> - struct optimized - { - using type = - split_heap<Size, - with_free_list_node<thread_local_free_list_heap< - Size, - Limit, - free_list_heap<Size, Limit, debug_size_heap<Heap>>>>, - debug_size_heap<Heap>>; - }; -}; - -/*! - * Similar to @ref free_list_heap_policy, but it assumes no - * multi-threading, so a single global free list with no concurrency - * checks is used. - */ -template <typename Heap, std::size_t Limit = default_free_list_size> -struct unsafe_free_list_heap_policy -{ - using type = Heap; - - template <std::size_t Size> - struct optimized - { - using type = split_heap< - Size, - with_free_list_node< - unsafe_free_list_heap<Size, Limit, debug_size_heap<Heap>>>, - debug_size_heap<Heap>>; - }; -}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/identity_heap.hpp b/third_party/immer/immer/heap/identity_heap.hpp deleted file mode 100644 index 032cb3f221d0..000000000000 --- a/third_party/immer/immer/heap/identity_heap.hpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <cstdlib> - -namespace immer { - -/*! - * A heap that simply passes on to the parent heap. - */ -template <typename Base> -struct identity_heap : Base -{ - template <typename... Tags> - static void* allocate(std::size_t size, Tags... tags) - { - return Base::allocate(size, tags...); - } - - template <typename... Tags> - static void deallocate(std::size_t size, void* data, Tags... tags) - { - Base::deallocate(size, data, tags...); - } -}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/malloc_heap.hpp b/third_party/immer/immer/heap/malloc_heap.hpp deleted file mode 100644 index a0074d17c0fb..000000000000 --- a/third_party/immer/immer/heap/malloc_heap.hpp +++ /dev/null @@ -1,44 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/config.hpp> - -#include <cstdlib> -#include <memory> - -namespace immer { - -/*! - * A heap that uses `std::malloc` and `std::free` to manage memory. - */ -struct malloc_heap -{ - /*! - * Returns a pointer to a memory region of size `size`, if the - * allocation was successful and throws `std::bad_alloc` otherwise. - */ - template <typename... Tags> - static void* allocate(std::size_t size, Tags...) - { - auto p = std::malloc(size); - if (IMMER_UNLIKELY(!p)) - throw std::bad_alloc{}; - return p; - } - - /*! - * Releases a memory region `data` that was previously returned by - * `allocate`. One must not use nor deallocate again a memory - * region that once it has been deallocated. - */ - static void deallocate(std::size_t, void* data) { std::free(data); } -}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/split_heap.hpp b/third_party/immer/immer/heap/split_heap.hpp deleted file mode 100644 index 37272d30ecc1..000000000000 --- a/third_party/immer/immer/heap/split_heap.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <atomic> -#include <cassert> - -namespace immer { - -/*! - * Adaptor that uses `SmallHeap` for allocations that are smaller or - * equal to `Size` and `BigHeap` otherwise. - */ -template <std::size_t Size, typename SmallHeap, typename BigHeap> -struct split_heap -{ - template <typename... Tags> - static void* allocate(std::size_t size, Tags... tags) - { - return size <= Size ? SmallHeap::allocate(size, tags...) - : BigHeap::allocate(size, tags...); - } - - template <typename... Tags> - static void deallocate(std::size_t size, void* data, Tags... tags) - { - if (size <= Size) - SmallHeap::deallocate(size, data, tags...); - else - BigHeap::deallocate(size, data, tags...); - } -}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/tags.hpp b/third_party/immer/immer/heap/tags.hpp deleted file mode 100644 index d1ce48d05c89..000000000000 --- a/third_party/immer/immer/heap/tags.hpp +++ /dev/null @@ -1,16 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -namespace immer { - -struct norefs_tag -{}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/thread_local_free_list_heap.hpp b/third_party/immer/immer/heap/thread_local_free_list_heap.hpp deleted file mode 100644 index 9f7f48f43f6c..000000000000 --- a/third_party/immer/immer/heap/thread_local_free_list_heap.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/heap/unsafe_free_list_heap.hpp> - -namespace immer { -namespace detail { - -template <typename Heap> -struct thread_local_free_list_storage -{ - struct head_t - { - free_list_node* data; - std::size_t count; - - ~head_t() { Heap::clear(); } - }; - - static head_t& head() - { - thread_local static head_t head_{nullptr, 0}; - return head_; - } -}; - -} // namespace detail - -/*! - * Adaptor that does not release the memory to the parent heap but - * instead it keeps the memory in a `thread_local` global free - * list. Must be preceded by a `with_data<free_list_node, ...>` heap - * adaptor. When the current thread finishes, the memory is returned - * to the parent heap. - * - * @tparam Size Maximum size of the objects to be allocated. - * @tparam Limit Maximum number of elements to keep in the free list. - * @tparam Base Type of the parent heap. - */ -template <std::size_t Size, std::size_t Limit, typename Base> -struct thread_local_free_list_heap - : detail::unsafe_free_list_heap_impl<detail::thread_local_free_list_storage, - Size, - Limit, - Base> -{}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/unsafe_free_list_heap.hpp b/third_party/immer/immer/heap/unsafe_free_list_heap.hpp deleted file mode 100644 index 942f07802476..000000000000 --- a/third_party/immer/immer/heap/unsafe_free_list_heap.hpp +++ /dev/null @@ -1,109 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <cassert> -#include <immer/config.hpp> -#include <immer/heap/free_list_node.hpp> - -namespace immer { -namespace detail { - -template <typename Heap> -struct unsafe_free_list_storage -{ - struct head_t - { - free_list_node* data; - std::size_t count; - }; - - static head_t& head() - { - static head_t head_{nullptr, 0}; - return head_; - } -}; - -template <template <class> class Storage, - std::size_t Size, - std::size_t Limit, - typename Base> -class unsafe_free_list_heap_impl : Base -{ - using storage = Storage<unsafe_free_list_heap_impl>; - -public: - using base_t = Base; - - template <typename... Tags> - static void* allocate(std::size_t size, Tags...) - { - assert(size <= sizeof(free_list_node) + Size); - assert(size >= sizeof(free_list_node)); - - auto n = storage::head().data; - if (!n) { - auto p = base_t::allocate(Size + sizeof(free_list_node)); - return static_cast<free_list_node*>(p); - } - --storage::head().count; - storage::head().data = n->next; - return n; - } - - template <typename... Tags> - static void deallocate(std::size_t size, void* data, Tags...) - { - assert(size <= sizeof(free_list_node) + Size); - assert(size >= sizeof(free_list_node)); - - if (storage::head().count >= Limit) - base_t::deallocate(Size + sizeof(free_list_node), data); - else { - auto n = static_cast<free_list_node*>(data); - n->next = storage::head().data; - storage::head().data = n; - ++storage::head().count; - } - } - - static void clear() - { - while (storage::head().data) { - auto n = storage::head().data->next; - base_t::deallocate(Size + sizeof(free_list_node), - storage::head().data); - storage::head().data = n; - --storage::head().count; - } - } -}; - -} // namespace detail - -/*! - * Adaptor that does not release the memory to the parent heap but - * instead it keeps the memory in a global free list that **is not - * thread-safe**. Must be preceded by a `with_data<free_list_node, - * ...>` heap adaptor. - * - * @tparam Size Maximum size of the objects to be allocated. - * @tparam Limit Maximum number of elements to keep in the free list. - * @tparam Base Type of the parent heap. - */ -template <std::size_t Size, std::size_t Limit, typename Base> -struct unsafe_free_list_heap - : detail::unsafe_free_list_heap_impl<detail::unsafe_free_list_storage, - Size, - Limit, - Base> -{}; - -} // namespace immer diff --git a/third_party/immer/immer/heap/with_data.hpp b/third_party/immer/immer/heap/with_data.hpp deleted file mode 100644 index 1e8c2abb082e..000000000000 --- a/third_party/immer/immer/heap/with_data.hpp +++ /dev/null @@ -1,43 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <cstdio> - -namespace immer { - -/*! - * Appends a default constructed extra object of type `T` at the - * *before* the requested region. - * - * @tparam T Type of the appended data. - * @tparam Base Type of the parent heap. - */ -template <typename T, typename Base> -struct with_data : Base -{ - using base_t = Base; - - template <typename... Tags> - static void* allocate(std::size_t size, Tags... tags) - { - auto p = base_t::allocate(size + sizeof(T), tags...); - return new (p) T{} + 1; - } - - template <typename... Tags> - static void deallocate(std::size_t size, void* p, Tags... tags) - { - auto dp = static_cast<T*>(p) - 1; - dp->~T(); - base_t::deallocate(size + sizeof(T), dp, tags...); - } -}; - -} // namespace immer diff --git a/third_party/immer/immer/map.hpp b/third_party/immer/immer/map.hpp deleted file mode 100644 index 58a84d2de939..000000000000 --- a/third_party/immer/immer/map.hpp +++ /dev/null @@ -1,342 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/hamts/champ.hpp> -#include <immer/detail/hamts/champ_iterator.hpp> -#include <immer/memory_policy.hpp> - -#include <functional> - -namespace immer { - -template <typename K, - typename T, - typename Hash, - typename Equal, - typename MemoryPolicy, - detail::hamts::bits_t B> -class map_transient; - -/*! - * Immutable unordered mapping of values from type `K` to type `T`. - * - * @tparam K The type of the keys. - * @tparam T The type of the values to be stored in the container. - * @tparam Hash The type of a function object capable of hashing - * values of type `T`. - * @tparam Equal The type of a function object capable of comparing - * values of type `T`. - * @tparam MemoryPolicy Memory management policy. See @ref - * memory_policy. - * - * @rst - * - * This cotainer provides a good trade-off between cache locality, - * search, update performance and structural sharing. It does so by - * storing the data in contiguous chunks of :math:`2^{B}` elements. - * When storing big objects, the size of these contiguous chunks can - * become too big, damaging performance. If this is measured to be - * problematic for a specific use-case, it can be solved by using a - * `immer::box` to wrap the type `T`. - * - * **Example** - * .. literalinclude:: ../example/map/intro.cpp - * :language: c++ - * :start-after: intro/start - * :end-before: intro/end - * - * @endrst - * - */ -template <typename K, - typename T, - typename Hash = std::hash<K>, - typename Equal = std::equal_to<K>, - typename MemoryPolicy = default_memory_policy, - detail::hamts::bits_t B = default_bits> -class map -{ - using value_t = std::pair<K, T>; - - struct project_value - { - const T& operator()(const value_t& v) const noexcept - { - return v.second; - } - }; - - struct project_value_ptr - { - const T* operator()(const value_t& v) const noexcept - { - return &v.second; - } - }; - - struct combine_value - { - template <typename Kf, typename Tf> - value_t operator()(Kf&& k, Tf&& v) const - { - return {std::forward<Kf>(k), std::forward<Tf>(v)}; - } - }; - - struct default_value - { - const T& operator()() const - { - static T v{}; - return v; - } - }; - - struct error_value - { - const T& operator()() const - { - throw std::out_of_range{"key not found"}; - } - }; - - struct hash_key - { - auto operator()(const value_t& v) { return Hash{}(v.first); } - - auto operator()(const K& v) { return Hash{}(v); } - }; - - struct equal_key - { - auto operator()(const value_t& a, const value_t& b) - { - return Equal{}(a.first, b.first); - } - - auto operator()(const value_t& a, const K& b) - { - return Equal{}(a.first, b); - } - }; - - struct equal_value - { - auto operator()(const value_t& a, const value_t& b) - { - return Equal{}(a.first, b.first) && a.second == b.second; - } - }; - - using impl_t = - detail::hamts::champ<value_t, hash_key, equal_key, MemoryPolicy, B>; - -public: - using key_type = K; - using mapped_type = T; - using value_type = std::pair<K, T>; - using size_type = detail::hamts::size_t; - using diference_type = std::ptrdiff_t; - using hasher = Hash; - using key_equal = Equal; - using reference = const value_type&; - using const_reference = const value_type&; - - using iterator = detail::hamts:: - champ_iterator<value_t, hash_key, equal_key, MemoryPolicy, B>; - using const_iterator = iterator; - - using transient_type = map_transient<K, T, Hash, Equal, MemoryPolicy, B>; - - /*! - * Default constructor. It creates a set of `size() == 0`. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - map() = default; - - /*! - * Returns an iterator pointing at the first element of the - * collection. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator begin() const { return {impl_}; } - - /*! - * Returns an iterator pointing just after the last element of the - * collection. It does not allocate and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator end() const - { - return {impl_, typename iterator::end_t{}}; - } - - /*! - * Returns the number of elements in the container. It does - * not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD size_type size() const { return impl_.size; } - - /*! - * Returns `true` if there are no elements in the container. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD bool empty() const { return impl_.size == 0; } - - /*! - * Returns `1` when the key `k` is contained in the map or `0` - * otherwise. It won't allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - IMMER_NODISCARD size_type count(const K& k) const - { - return impl_.template get<detail::constantly<size_type, 1>, - detail::constantly<size_type, 0>>(k); - } - - /*! - * Returns a `const` reference to the values associated to the key - * `k`. If the key is not contained in the map, it returns a - * default constructed value. It does not allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - IMMER_NODISCARD const T& operator[](const K& k) const - { - return impl_.template get<project_value, default_value>(k); - } - - /*! - * Returns a `const` reference to the values associated to the key - * `k`. If the key is not contained in the map, throws an - * `std::out_of_range` error. It does not allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - const T& at(const K& k) const - { - return impl_.template get<project_value, error_value>(k); - } - - /*! - * Returns a pointer to the value associated with the key `k`. If - * the key is not contained in the map, a `nullptr` is returned. - * It does not allocate memory and its complexity is *effectively* - * @f$ O(1) @f$. - * - * @rst - * - * .. admonition:: Why doesn't this function return an iterator? - * - * Associative containers from the C++ standard library provide a - * ``find`` method that returns an iterator pointing to the - * element in the container or ``end()`` when the key is missing. - * In the case of an unordered container, the only meaningful - * thing one may do with it is to compare it with the end, to - * test if the find was succesfull, and dereference it. This - * comparison is cumbersome compared to testing for a non-empty - * optional value. Furthermore, for an immutable container, - * returning an iterator would have some additional performance - * cost, with no benefits otherwise. - * - * In our opinion, this function should return a - * ``std::optional<const T&>`` but this construction is not valid - * in any current standard. As a compromise we return a - * pointer, which has similar syntactic properties yet it is - * unfortunatelly unnecessarily unrestricted. - * - * @endrst - */ - IMMER_NODISCARD const T* find(const K& k) const - { - return impl_.template get<project_value_ptr, - detail::constantly<const T*, nullptr>>(k); - } - - /*! - * Returns whether the sets are equal. - */ - IMMER_NODISCARD bool operator==(const map& other) const - { - return impl_.template equals<equal_value>(other.impl_); - } - IMMER_NODISCARD bool operator!=(const map& other) const - { - return !(*this == other); - } - - /*! - * Returns a map containing the association `value`. If the key is - * already in the map, it replaces its association in the map. - * It may allocate memory and its complexity is *effectively* @f$ - * O(1) @f$. - */ - IMMER_NODISCARD map insert(value_type value) const - { - return impl_.add(std::move(value)); - } - - /*! - * Returns a map containing the association `(k, v)`. If the key - * is already in the map, it replaces its association in the map. - * It may allocate memory and its complexity is *effectively* @f$ - * O(1) @f$. - */ - IMMER_NODISCARD map set(key_type k, mapped_type v) const - { - return impl_.add({std::move(k), std::move(v)}); - } - - /*! - * Returns a map replacing the association `(k, v)` by the - * association new association `(k, fn(v))`, where `v` is the - * currently associated value for `k` in the map or a default - * constructed value otherwise. It may allocate memory - * and its complexity is *effectively* @f$ O(1) @f$. - */ - template <typename Fn> - IMMER_NODISCARD map update(key_type k, Fn&& fn) const - { - return impl_ - .template update<project_value, default_value, combine_value>( - std::move(k), std::forward<Fn>(fn)); - } - - /*! - * Returns a map without the key `k`. If the key is not - * associated in the map it returns the same map. It may allocate - * memory and its complexity is *effectively* @f$ O(1) @f$. - */ - IMMER_NODISCARD map erase(const K& k) const { return impl_.sub(k); } - - /*! - * Returns an @a transient form of this container, a - * `immer::map_transient`. - */ - IMMER_NODISCARD transient_type transient() const& - { - return transient_type{impl_}; - } - IMMER_NODISCARD transient_type transient() && - { - return transient_type{std::move(impl_)}; - } - - // Semi-private - const impl_t& impl() const { return impl_; } - -private: - friend transient_type; - - map(impl_t impl) - : impl_(std::move(impl)) - {} - - impl_t impl_ = impl_t::empty(); -}; - -} // namespace immer diff --git a/third_party/immer/immer/map_transient.hpp b/third_party/immer/immer/map_transient.hpp deleted file mode 100644 index 8821c5d12b56..000000000000 --- a/third_party/immer/immer/map_transient.hpp +++ /dev/null @@ -1,41 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/hamts/champ.hpp> -#include <immer/memory_policy.hpp> - -#include <functional> - -namespace immer { - -/*! - * @rst - * - * .. admonition:: Become a sponsor! - * :class: danger - * - * This component is planned but it has **not been implemented yet**. - * - * Transiens can critically improve the performance of applications - * intensively using ``set`` and ``map``. If you are working for an - * organization using the library in a commercial project, please consider - * **sponsoring this work**: juanpe@sinusoid.al - * - * @endrst - */ -template <typename K, - typename T, - typename Hash = std::hash<K>, - typename Equal = std::equal_to<K>, - typename MemoryPolicy = default_memory_policy, - detail::hamts::bits_t B = default_bits> -class map_transient; - -} // namespace immer diff --git a/third_party/immer/immer/memory_policy.hpp b/third_party/immer/immer/memory_policy.hpp deleted file mode 100644 index b4f665bf621c..000000000000 --- a/third_party/immer/immer/memory_policy.hpp +++ /dev/null @@ -1,135 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/heap/cpp_heap.hpp> -#include <immer/heap/heap_policy.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/refcount/refcount_policy.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> -#include <immer/transience/gc_transience_policy.hpp> -#include <immer/transience/no_transience_policy.hpp> -#include <type_traits> - -namespace immer { - -/*! - * Metafunction that returns the best *transience policy* to use for a - * given *refcount policy*. - */ -template <typename RefcountPolicy> -struct get_transience_policy - : std::conditional<std::is_same<RefcountPolicy, no_refcount_policy>::value, - gc_transience_policy, - no_transience_policy> -{}; - -template <typename T> -using get_transience_policy_t = typename get_transience_policy<T>::type; - -/*! - * Metafunction that returns wether to *prefer fewer bigger objects* - * to use for a given *heap policy*. - */ -template <typename HeapPolicy> -struct get_prefer_fewer_bigger_objects - : std::integral_constant< - bool, - std::is_same<HeapPolicy, heap_policy<cpp_heap>>::value> -{}; - -template <typename T> -constexpr auto get_prefer_fewer_bigger_objects_v = - get_prefer_fewer_bigger_objects<T>::value; - -/*! - * Metafunction that returns wether to use *transient R-Values* - * for a given *refcount policy*. - */ -template <typename RefcountPolicy> -struct get_use_transient_rvalues - : std::integral_constant< - bool, - !std::is_same<RefcountPolicy, no_refcount_policy>::value> -{}; - -template <typename T> -constexpr auto get_use_transient_rvalues_v = - get_use_transient_rvalues<T>::value; - -/*! - * This is a default implementation of a *memory policy*. A memory - * policy is just a bag of other policies plus some flags with hints - * to the user about the best way to use these strategies. - * - * @tparam HeapPolicy A *heap policy*, for example, @ref heap_policy. - * @tparam RefcountPolicy A *reference counting policy*, for example, - * @ref refcount_policy. - * @tparam TransiencePolicy A *transience policy*, for example, - * @ref no_transience_policy. - * @tparam PreferFewerBiggerObjects Boolean flag indicating whether - * the user should prefer to allocate memory in bigger chungs - * --e.g. by putting various objects in the same memory - * region-- or not. - * @tparam UseTransientRValues Boolean flag indicating whether - * immutable containers should try to modify contents in-place - * when manipulating an r-value reference. - */ -template <typename HeapPolicy, - typename RefcountPolicy, - typename TransiencePolicy = get_transience_policy_t<RefcountPolicy>, - bool PreferFewerBiggerObjects = - get_prefer_fewer_bigger_objects_v<HeapPolicy>, - bool UseTransientRValues = - get_use_transient_rvalues_v<RefcountPolicy>> -struct memory_policy -{ - using heap = HeapPolicy; - using refcount = RefcountPolicy; - using transience = TransiencePolicy; - - static constexpr bool prefer_fewer_bigger_objects = - PreferFewerBiggerObjects; - - static constexpr bool use_transient_rvalues = UseTransientRValues; - - using transience_t = typename transience::template apply<heap>::type; -}; - -/*! - * The default *heap policy* just uses the standard heap with a - * @ref free_list_heap_policy. If `IMMER_NO_FREE_LIST` is defined to `1` - * then it just uses the standard heap. - */ -#if IMMER_NO_FREE_LIST -using default_heap_policy = heap_policy<debug_size_heap<cpp_heap>>; -#else -#if IMMER_NO_THREAD_SAFETY -using default_heap_policy = unsafe_free_list_heap_policy<cpp_heap>; -#else -using default_heap_policy = free_list_heap_policy<cpp_heap>; -#endif -#endif - -/*! - * By default we use thread safe reference counting. - */ -#if IMMER_NO_THREAD_SAFETY -using default_refcount_policy = unsafe_refcount_policy; -#else -using default_refcount_policy = refcount_policy; -#endif - -/*! - * The default memory policy. - */ -using default_memory_policy = - memory_policy<default_heap_policy, default_refcount_policy>; - -} // namespace immer diff --git a/third_party/immer/immer/refcount/enable_intrusive_ptr.hpp b/third_party/immer/immer/refcount/enable_intrusive_ptr.hpp deleted file mode 100644 index 1185a219fd9b..000000000000 --- a/third_party/immer/immer/refcount/enable_intrusive_ptr.hpp +++ /dev/null @@ -1,37 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/refcount/no_refcount_policy.hpp> - -namespace immer { - -template <typename Deriv, typename RefcountPolicy> -class enable_intrusive_ptr -{ - mutable RefcountPolicy refcount_data_; - -public: - enable_intrusive_ptr() - : refcount_data_{disowned{}} - {} - - friend void intrusive_ptr_add_ref(const Deriv* x) - { - x->refcount_data_.inc(); - } - - friend void intrusive_ptr_release(const Deriv* x) - { - if (x->refcount_data_.dec()) - delete x; - } -}; - -} // namespace immer diff --git a/third_party/immer/immer/refcount/no_refcount_policy.hpp b/third_party/immer/immer/refcount/no_refcount_policy.hpp deleted file mode 100644 index 24f9d489f54d..000000000000 --- a/third_party/immer/immer/refcount/no_refcount_policy.hpp +++ /dev/null @@ -1,45 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -namespace immer { - -struct disowned -{}; - -struct no_spinlock -{ - bool try_lock() { return true; } - void lock() {} - void unlock() {} - - struct scoped_lock - { - scoped_lock(no_spinlock&) {} - }; -}; - -/*! - * Disables reference counting, to be used with an alternative garbage - * collection strategy like a `gc_heap`. - */ -struct no_refcount_policy -{ - using spinlock_type = no_spinlock; - - no_refcount_policy(){}; - no_refcount_policy(disowned) {} - - void inc() {} - bool dec() { return false; } - void dec_unsafe() {} - bool unique() { return false; } -}; - -} // namespace immer diff --git a/third_party/immer/immer/refcount/refcount_policy.hpp b/third_party/immer/immer/refcount/refcount_policy.hpp deleted file mode 100644 index a7a282cd13a7..000000000000 --- a/third_party/immer/immer/refcount/refcount_policy.hpp +++ /dev/null @@ -1,101 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/refcount/no_refcount_policy.hpp> - -#include <atomic> -#include <cassert> -#include <thread> -#include <utility> - -// This has been shamelessly copied from boost... -#if defined(_MSC_VER) && _MSC_VER >= 1310 && \ - (defined(_M_IX86) || defined(_M_X64)) && !defined(__c2__) -extern "C" void _mm_pause(); -#define IMMER_SMT_PAUSE _mm_pause() -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) -#define IMMER_SMT_PAUSE __asm__ __volatile__("rep; nop" : : : "memory") -#endif - -namespace immer { - -// This is an atomic spinlock similar to the one used by boost to provide -// "atomic" shared_ptr operations. It also does not differ much from the one -// from libc++ or libstdc++... -struct spinlock -{ - std::atomic_flag v_{}; - - bool try_lock() { return !v_.test_and_set(std::memory_order_acquire); } - - void lock() - { - for (auto k = 0u; !try_lock(); ++k) { - if (k < 4) - continue; -#ifdef IMMER_SMT_PAUSE - else if (k < 16) - IMMER_SMT_PAUSE; -#endif - else - std::this_thread::yield(); - } - } - - void unlock() { v_.clear(std::memory_order_release); } - - struct scoped_lock - { - scoped_lock(const scoped_lock&) = delete; - scoped_lock& operator=(const scoped_lock&) = delete; - - explicit scoped_lock(spinlock& sp) - : sp_{sp} - { - sp.lock(); - } - - ~scoped_lock() { sp_.unlock(); } - - private: - spinlock& sp_; - }; -}; - -/*! - * A reference counting policy implemented using an *atomic* `int` - * count. It is **thread-safe**. - */ -struct refcount_policy -{ - using spinlock_type = spinlock; - - mutable std::atomic<int> refcount; - - refcount_policy() - : refcount{1} {}; - refcount_policy(disowned) - : refcount{0} - {} - - void inc() { refcount.fetch_add(1, std::memory_order_relaxed); } - - bool dec() { return 1 == refcount.fetch_sub(1, std::memory_order_acq_rel); } - - void dec_unsafe() - { - assert(refcount.load() > 1); - refcount.fetch_sub(1, std::memory_order_relaxed); - } - - bool unique() { return refcount == 1; } -}; - -} // namespace immer diff --git a/third_party/immer/immer/refcount/unsafe_refcount_policy.hpp b/third_party/immer/immer/refcount/unsafe_refcount_policy.hpp deleted file mode 100644 index bcf24578de27..000000000000 --- a/third_party/immer/immer/refcount/unsafe_refcount_policy.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/refcount/no_refcount_policy.hpp> - -#include <atomic> -#include <utility> - -namespace immer { - -/*! - * A reference counting policy implemented using a raw `int` count. - * It is **not thread-safe**. - */ -struct unsafe_refcount_policy -{ - using spinlock_type = no_spinlock; - - mutable int refcount; - - unsafe_refcount_policy() - : refcount{1} {}; - unsafe_refcount_policy(disowned) - : refcount{0} - {} - - void inc() { ++refcount; } - bool dec() { return --refcount == 0; } - void dec_unsafe() { --refcount; } - bool unique() { return refcount == 1; } -}; - -} // namespace immer diff --git a/third_party/immer/immer/set.hpp b/third_party/immer/immer/set.hpp deleted file mode 100644 index a152ac955334..000000000000 --- a/third_party/immer/immer/set.hpp +++ /dev/null @@ -1,198 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/hamts/champ.hpp> -#include <immer/detail/hamts/champ_iterator.hpp> -#include <immer/memory_policy.hpp> - -#include <functional> - -namespace immer { - -template <typename T, - typename Hash, - typename Equal, - typename MemoryPolicy, - detail::hamts::bits_t B> -class set_transient; - -/*! - * Immutable set representing an unordered bag of values. - * - * @tparam T The type of the values to be stored in the container. - * @tparam Hash The type of a function object capable of hashing - * values of type `T`. - * @tparam Equal The type of a function object capable of comparing - * values of type `T`. - * @tparam MemoryPolicy Memory management policy. See @ref - * memory_policy. - * - * @rst - * - * This container provides a good trade-off between cache locality, - * membership checks, update performance and structural sharing. It - * does so by storing the data in contiguous chunks of :math:`2^{B}` - * elements. When storing big objects, the size of these contiguous - * chunks can become too big, damaging performance. If this is - * measured to be problematic for a specific use-case, it can be - * solved by using a `immer::box` to wrap the type `T`. - * - * **Example** - * .. literalinclude:: ../example/set/intro.cpp - * :language: c++ - * :start-after: intro/start - * :end-before: intro/end - * - * @endrst - * - */ -template <typename T, - typename Hash = std::hash<T>, - typename Equal = std::equal_to<T>, - typename MemoryPolicy = default_memory_policy, - detail::hamts::bits_t B = default_bits> -class set -{ - using impl_t = detail::hamts::champ<T, Hash, Equal, MemoryPolicy, B>; - - struct project_value_ptr - { - const T* operator()(const T& v) const noexcept { return &v; } - }; - -public: - using key_type = T; - using value_type = T; - using size_type = detail::hamts::size_t; - using diference_type = std::ptrdiff_t; - using hasher = Hash; - using key_equal = Equal; - using reference = const T&; - using const_reference = const T&; - - using iterator = - detail::hamts::champ_iterator<T, Hash, Equal, MemoryPolicy, B>; - using const_iterator = iterator; - - using transient_type = set_transient<T, Hash, Equal, MemoryPolicy, B>; - - /*! - * Default constructor. It creates a set of `size() == 0`. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - set() = default; - - /*! - * Returns an iterator pointing at the first element of the - * collection. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator begin() const { return {impl_}; } - - /*! - * Returns an iterator pointing just after the last element of the - * collection. It does not allocate and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator end() const - { - return {impl_, typename iterator::end_t{}}; - } - - /*! - * Returns the number of elements in the container. It does - * not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD size_type size() const { return impl_.size; } - - /*! - * Returns `true` if there are no elements in the container. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD bool empty() const { return impl_.size == 0; } - - /*! - * Returns `1` when `value` is contained in the set or `0` - * otherwise. It won't allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - IMMER_NODISCARD size_type count(const T& value) const - { - return impl_.template get<detail::constantly<size_type, 1>, - detail::constantly<size_type, 0>>(value); - } - - /*! - * Returns a pointer to the value if `value` is contained in the - * set, or nullptr otherwise. - * It does not allocate memory and its complexity is *effectively* - * @f$ O(1) @f$. - */ - IMMER_NODISCARD const T* find(const T& value) const - { - return impl_.template get<project_value_ptr, - detail::constantly<const T*, nullptr>>(value); - } - - /*! - * Returns whether the sets are equal. - */ - IMMER_NODISCARD bool operator==(const set& other) const - { - return impl_.equals(other.impl_); - } - IMMER_NODISCARD bool operator!=(const set& other) const - { - return !(*this == other); - } - - /*! - * Returns a set containing `value`. If the `value` is already in - * the set, it returns the same set. It may allocate memory and - * its complexity is *effectively* @f$ O(1) @f$. - */ - IMMER_NODISCARD set insert(T value) const - { - return impl_.add(std::move(value)); - } - - /*! - * Returns a set without `value`. If the `value` is not in the - * set it returns the same set. It may allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - IMMER_NODISCARD set erase(const T& value) const { return impl_.sub(value); } - - /*! - * Returns an @a transient form of this container, a - * `immer::set_transient`. - */ - IMMER_NODISCARD transient_type transient() const& - { - return transient_type{impl_}; - } - IMMER_NODISCARD transient_type transient() && - { - return transient_type{std::move(impl_)}; - } - - // Semi-private - const impl_t& impl() const { return impl_; } - -private: - friend transient_type; - - set(impl_t impl) - : impl_(std::move(impl)) - {} - - impl_t impl_ = impl_t::empty(); -}; - -} // namespace immer diff --git a/third_party/immer/immer/set_transient.hpp b/third_party/immer/immer/set_transient.hpp deleted file mode 100644 index cd0f652b95f6..000000000000 --- a/third_party/immer/immer/set_transient.hpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/hamts/champ.hpp> -#include <immer/memory_policy.hpp> - -#include <functional> - -namespace immer { - -/*! - * @rst - * - * .. admonition:: Become a sponsor! - * :class: danger - * - * This component is planned but it has **not been implemented yet**. - * - * Transiens can critically improve the performance of applications - * intensively using ``set`` and ``map``. If you are working for an - * organization using the library in a commercial project, please consider - * **sponsoring this work**: juanpe@sinusoid.al - * - * @endrst - */ -template <typename T, - typename Hash = std::hash<T>, - typename Equal = std::equal_to<T>, - typename MemoryPolicy = default_memory_policy, - detail::hamts::bits_t B = default_bits> -class set_transient; - -} // namespace immer diff --git a/third_party/immer/immer/transience/gc_transience_policy.hpp b/third_party/immer/immer/transience/gc_transience_policy.hpp deleted file mode 100644 index d3c30efa1cf7..000000000000 --- a/third_party/immer/immer/transience/gc_transience_policy.hpp +++ /dev/null @@ -1,110 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/heap/tags.hpp> - -#include <atomic> -#include <memory> -#include <utility> - -namespace immer { - -/*! - * Provides transience ownership tracking when a *tracing garbage - * collector* is used instead of reference counting. - * - * @rst - * - * .. warning:: Using this policy without an allocation scheme that - * includes automatic tracing garbage collection may cause memory - * leaks. - * - * @endrst - */ -struct gc_transience_policy -{ - template <typename HeapPolicy> - struct apply - { - struct type - { - using heap_ = typename HeapPolicy::type; - - struct edit - { - void* v; - edit() = delete; - bool operator==(edit x) const { return v == x.v; } - bool operator!=(edit x) const { return v != x.v; } - }; - - struct owner - { - void* make_token_() - { - return heap_::allocate(1, norefs_tag{}); - }; - - mutable std::atomic<void*> token_; - - operator edit() { return {token_}; } - - owner() - : token_{make_token_()} - {} - owner(const owner& o) - : token_{make_token_()} - { - o.token_ = make_token_(); - } - owner(owner&& o) noexcept - : token_{o.token_.load()} - {} - owner& operator=(const owner& o) - { - o.token_ = make_token_(); - token_ = make_token_(); - return *this; - } - owner& operator=(owner&& o) noexcept - { - token_ = o.token_.load(); - return *this; - } - }; - - struct ownee - { - edit token_{nullptr}; - - ownee& operator=(edit e) - { - assert(e != noone); - // This would be a nice safety plug but it sadly - // does not hold during transient concatenation. - // assert(token_ == e || token_ == edit{nullptr}); - token_ = e; - return *this; - } - - bool can_mutate(edit t) const { return token_ == t; } - bool owned() const { return token_ != edit{nullptr}; } - }; - - static owner noone; - }; - }; -}; - -template <typename HP> -typename gc_transience_policy::apply<HP>::type::owner - gc_transience_policy::apply<HP>::type::noone = {}; - -} // namespace immer diff --git a/third_party/immer/immer/transience/no_transience_policy.hpp b/third_party/immer/immer/transience/no_transience_policy.hpp deleted file mode 100644 index 2f87df7a39b0..000000000000 --- a/third_party/immer/immer/transience/no_transience_policy.hpp +++ /dev/null @@ -1,48 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -namespace immer { - -/*! - * Disables any special *transience* tracking. To be used when - * *reference counting* is available instead. - */ -struct no_transience_policy -{ - template <typename> - struct apply - { - struct type - { - struct edit - {}; - - struct owner - { - operator edit() const { return {}; } - }; - - struct ownee - { - ownee& operator=(edit) { return *this; }; - bool can_mutate(edit) const { return false; } - bool owned() const { return false; } - }; - - static owner noone; - }; - }; -}; - -template <typename HP> -typename no_transience_policy::apply<HP>::type::owner - no_transience_policy::apply<HP>::type::noone = {}; - -} // namespace immer diff --git a/third_party/immer/immer/vector.hpp b/third_party/immer/immer/vector.hpp deleted file mode 100644 index 4f1a148ccd00..000000000000 --- a/third_party/immer/immer/vector.hpp +++ /dev/null @@ -1,412 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/rbts/rbtree.hpp> -#include <immer/detail/rbts/rbtree_iterator.hpp> -#include <immer/memory_policy.hpp> - -#if IMMER_DEBUG_PRINT -#include <immer/flex_vector.hpp> -#endif - -namespace immer { - -template <typename T, - typename MemoryPolicy, - detail::rbts::bits_t B, - detail::rbts::bits_t BL> -class flex_vector; - -template <typename T, - typename MemoryPolicy, - detail::rbts::bits_t B, - detail::rbts::bits_t BL> -class vector_transient; - -/*! - * Immutable sequential container supporting both random access and - * structural sharing. - * - * @tparam T The type of the values to be stored in the container. - * @tparam MemoryPolicy Memory management policy. See @ref - * memory_policy. - * - * @rst - * - * This cotainer provides a good trade-off between cache locality, - * random access, update performance and structural sharing. It does - * so by storing the data in contiguous chunks of :math:`2^{BL}` - * elements. By default, when ``sizeof(T) == sizeof(void*)`` then - * :math:`B=BL=5`, such that data would be stored in contiguous - * chunks of :math:`32` elements. - * - * You may learn more about the meaning and implications of ``B`` and - * ``BL`` parameters in the :doc:`implementation` section. - * - * .. note:: In several methods we say that their complexity is - * *effectively* :math:`O(...)`. Do not confuse this with the word - * *amortized*, which has a very different meaning. In this - * context, *effective* means that while the - * mathematically rigurous - * complexity might be higher, for all practical matters the - * provided complexity is more useful to think about the actual - * cost of the operation. - * - * **Example** - * .. literalinclude:: ../example/vector/intro.cpp - * :language: c++ - * :start-after: intro/start - * :end-before: intro/end - * - * @endrst - */ -template <typename T, - typename MemoryPolicy = default_memory_policy, - detail::rbts::bits_t B = default_bits, - detail::rbts::bits_t BL = - detail::rbts::derive_bits_leaf<T, MemoryPolicy, B>> -class vector -{ - using impl_t = detail::rbts::rbtree<T, MemoryPolicy, B, BL>; - using flex_t = flex_vector<T, MemoryPolicy, B, BL>; - - using move_t = - std::integral_constant<bool, MemoryPolicy::use_transient_rvalues>; - -public: - static constexpr auto bits = B; - static constexpr auto bits_leaf = BL; - using memory_policy = MemoryPolicy; - - using value_type = T; - using reference = const T&; - using size_type = detail::rbts::size_t; - using difference_type = std::ptrdiff_t; - using const_reference = const T&; - - using iterator = detail::rbts::rbtree_iterator<T, MemoryPolicy, B, BL>; - using const_iterator = iterator; - using reverse_iterator = std::reverse_iterator<iterator>; - - using transient_type = vector_transient<T, MemoryPolicy, B, BL>; - - /*! - * Default constructor. It creates a vector of `size() == 0`. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - vector() = default; - - /*! - * Constructs a vector containing the elements in `values`. - */ - vector(std::initializer_list<T> values) - : impl_{impl_t::from_initializer_list(values)} - {} - - /*! - * Constructs a vector containing the elements in the range - * defined by the input iterator `first` and range sentinel `last`. - */ - template <typename Iter, - typename Sent, - std::enable_if_t<detail::compatible_sentinel_v<Iter, Sent>, - bool> = true> - vector(Iter first, Sent last) - : impl_{impl_t::from_range(first, last)} - {} - - /*! - * Constructs a vector containing the element `val` repeated `n` - * times. - */ - vector(size_type n, T v = {}) - : impl_{impl_t::from_fill(n, v)} - {} - - /*! - * Returns an iterator pointing at the first element of the - * collection. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator begin() const { return {impl_}; } - - /*! - * Returns an iterator pointing just after the last element of the - * collection. It does not allocate and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator end() const - { - return {impl_, typename iterator::end_t{}}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing at the first element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rbegin() const - { - return reverse_iterator{end()}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing after the last element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rend() const - { - return reverse_iterator{begin()}; - } - - /*! - * Returns the number of elements in the container. It does - * not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD size_type size() const { return impl_.size; } - - /*! - * Returns `true` if there are no elements in the container. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD bool empty() const { return impl_.size == 0; } - - /*! - * Access the last element. - */ - IMMER_NODISCARD const T& back() const { return impl_.back(); } - - /*! - * Access the first element. - */ - IMMER_NODISCARD const T& front() const { return impl_.front(); } - - /*! - * Returns a `const` reference to the element at position `index`. - * It is undefined when @f$ 0 index \geq size() @f$. It does not - * allocate memory and its complexity is *effectively* @f$ O(1) - * @f$. - */ - IMMER_NODISCARD reference operator[](size_type index) const - { - return impl_.get(index); - } - - /*! - * Returns a `const` reference to the element at position - * `index`. It throws an `std::out_of_range` exception when @f$ - * index \geq size() @f$. It does not allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - reference at(size_type index) const { return impl_.get_check(index); } - - /*! - * Returns whether the vectors are equal. - */ - IMMER_NODISCARD bool operator==(const vector& other) const - { - return impl_.equals(other.impl_); - } - IMMER_NODISCARD bool operator!=(const vector& other) const - { - return !(*this == other); - } - - /*! - * Returns a vector with `value` inserted at the end. It may - * allocate memory and its complexity is *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/vector/vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: push-back/start - * :end-before: push-back/end - * - * @endrst - */ - IMMER_NODISCARD vector push_back(value_type value) const& - { - return impl_.push_back(std::move(value)); - } - - IMMER_NODISCARD decltype(auto) push_back(value_type value) && - { - return push_back_move(move_t{}, std::move(value)); - } - - /*! - * Returns a vector containing value `value` at position `idx`. - * Undefined for `index >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/vector/vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: set/start - * :end-before: set/end - * - * @endrst - */ - IMMER_NODISCARD vector set(size_type index, value_type value) const& - { - return impl_.assoc(index, std::move(value)); - } - - IMMER_NODISCARD decltype(auto) set(size_type index, value_type value) && - { - return set_move(move_t{}, index, std::move(value)); - } - - /*! - * Returns a vector containing the result of the expression - * `fn((*this)[idx])` at position `idx`. - * Undefined for `0 >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/vector/vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: update/start - * :end-before: update/end - * - * @endrst - */ - template <typename FnT> - IMMER_NODISCARD vector update(size_type index, FnT&& fn) const& - { - return impl_.update(index, std::forward<FnT>(fn)); - } - - template <typename FnT> - IMMER_NODISCARD decltype(auto) update(size_type index, FnT&& fn) && - { - return update_move(move_t{}, index, std::forward<FnT>(fn)); - } - - /*! - * Returns a vector containing only the first `min(elems, size())` - * elements. It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - * - * @rst - * - * **Example** - * .. literalinclude:: ../example/vector/vector.cpp - * :language: c++ - * :dedent: 8 - * :start-after: take/start - * :end-before: take/end - * - * @endrst - */ - IMMER_NODISCARD vector take(size_type elems) const& - { - return impl_.take(elems); - } - - IMMER_NODISCARD decltype(auto) take(size_type elems) && - { - return take_move(move_t{}, elems); - } - - /*! - * Returns an @a transient form of this container, an - * `immer::vector_transient`. - */ - IMMER_NODISCARD transient_type transient() const& - { - return transient_type{impl_}; - } - IMMER_NODISCARD transient_type transient() && - { - return transient_type{std::move(impl_)}; - } - - // Semi-private - const impl_t& impl() const { return impl_; } - -#if IMMER_DEBUG_PRINT - void debug_print(std::ostream& out = std::cerr) const - { - flex_t{*this}.debug_print(out); - } -#endif - -private: - friend flex_t; - friend transient_type; - - vector(impl_t impl) - : impl_(std::move(impl)) - { -#if IMMER_DEBUG_PRINT - // force the compiler to generate debug_print, so we can call - // it from a debugger - [](volatile auto) {}(&vector::debug_print); -#endif - } - - vector&& push_back_move(std::true_type, value_type value) - { - impl_.push_back_mut({}, std::move(value)); - return std::move(*this); - } - vector push_back_move(std::false_type, value_type value) - { - return impl_.push_back(std::move(value)); - } - - vector&& set_move(std::true_type, size_type index, value_type value) - { - impl_.assoc_mut({}, index, std::move(value)); - return std::move(*this); - } - vector set_move(std::false_type, size_type index, value_type value) - { - return impl_.assoc(index, std::move(value)); - } - - template <typename Fn> - vector&& update_move(std::true_type, size_type index, Fn&& fn) - { - impl_.update_mut({}, index, std::forward<Fn>(fn)); - return std::move(*this); - } - template <typename Fn> - vector update_move(std::false_type, size_type index, Fn&& fn) - { - return impl_.update(index, std::forward<Fn>(fn)); - } - - vector&& take_move(std::true_type, size_type elems) - { - impl_.take_mut({}, elems); - return std::move(*this); - } - vector take_move(std::false_type, size_type elems) - { - return impl_.take(elems); - } - - impl_t impl_ = impl_t::empty(); -}; - -} // namespace immer diff --git a/third_party/immer/immer/vector_transient.hpp b/third_party/immer/immer/vector_transient.hpp deleted file mode 100644 index 4d648cab07db..000000000000 --- a/third_party/immer/immer/vector_transient.hpp +++ /dev/null @@ -1,203 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <immer/detail/rbts/rbtree.hpp> -#include <immer/detail/rbts/rbtree_iterator.hpp> -#include <immer/memory_policy.hpp> - -namespace immer { - -template <typename T, - typename MemoryPolicy, - detail::rbts::bits_t B, - detail::rbts::bits_t BL> -class vector; - -template <typename T, - typename MemoryPolicy, - detail::rbts::bits_t B, - detail::rbts::bits_t BL> -class flex_vector_transient; - -/*! - * Mutable version of `immer::vector`. - * - * @rst - * - * Refer to :doc:`transients` to learn more about when and how to use - * the mutable versions of immutable containers. - * - * @endrst - */ -template <typename T, - typename MemoryPolicy = default_memory_policy, - detail::rbts::bits_t B = default_bits, - detail::rbts::bits_t BL = - detail::rbts::derive_bits_leaf<T, MemoryPolicy, B>> -class vector_transient : MemoryPolicy::transience_t::owner -{ - using impl_t = detail::rbts::rbtree<T, MemoryPolicy, B, BL>; - using flex_t = flex_vector_transient<T, MemoryPolicy, B, BL>; - using owner_t = typename MemoryPolicy::transience_t::owner; - -public: - static constexpr auto bits = B; - static constexpr auto bits_leaf = BL; - using memory_policy = MemoryPolicy; - - using value_type = T; - using reference = const T&; - using size_type = detail::rbts::size_t; - using difference_type = std::ptrdiff_t; - using const_reference = const T&; - - using iterator = detail::rbts::rbtree_iterator<T, MemoryPolicy, B, BL>; - using const_iterator = iterator; - using reverse_iterator = std::reverse_iterator<iterator>; - - using persistent_type = vector<T, MemoryPolicy, B, BL>; - - /*! - * Default constructor. It creates a mutable vector of `size() == - * 0`. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - vector_transient() = default; - - /*! - * Returns an iterator pointing at the first element of the - * collection. It does not allocate memory and its complexity is - * @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator begin() const { return {impl_}; } - - /*! - * Returns an iterator pointing just after the last element of the - * collection. It does not allocate and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD iterator end() const - { - return {impl_, typename iterator::end_t{}}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing at the first element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rbegin() const - { - return reverse_iterator{end()}; - } - - /*! - * Returns an iterator that traverses the collection backwards, - * pointing after the last element of the reversed collection. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD reverse_iterator rend() const - { - return reverse_iterator{begin()}; - } - - /*! - * Returns the number of elements in the container. It does - * not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD size_type size() const { return impl_.size; } - - /*! - * Returns `true` if there are no elements in the container. It - * does not allocate memory and its complexity is @f$ O(1) @f$. - */ - IMMER_NODISCARD bool empty() const { return impl_.size == 0; } - - /*! - * Returns a `const` reference to the element at position `index`. - * It is undefined when @f$ 0 index \geq size() @f$. It does not - * allocate memory and its complexity is *effectively* @f$ O(1) - * @f$. - */ - reference operator[](size_type index) const { return impl_.get(index); } - - /*! - * Returns a `const` reference to the element at position - * `index`. It throws an `std::out_of_range` exception when @f$ - * index \geq size() @f$. It does not allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - reference at(size_type index) const { return impl_.get_check(index); } - - /*! - * Inserts `value` at the end. It may allocate memory and its - * complexity is *effectively* @f$ O(1) @f$. - */ - void push_back(value_type value) - { - impl_.push_back_mut(*this, std::move(value)); - } - - /*! - * Sets to the value `value` at position `idx`. - * Undefined for `index >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - void set(size_type index, value_type value) - { - impl_.assoc_mut(*this, index, std::move(value)); - } - - /*! - * Updates the vector to contain the result of the expression - * `fn((*this)[idx])` at position `idx`. - * Undefined for `0 >= size()`. - * It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - template <typename FnT> - void update(size_type index, FnT&& fn) - { - impl_.update_mut(*this, index, std::forward<FnT>(fn)); - } - - /*! - * Resizes the vector to only contain the first `min(elems, size())` - * elements. It may allocate memory and its complexity is - * *effectively* @f$ O(1) @f$. - */ - void take(size_type elems) { impl_.take_mut(*this, elems); } - - /*! - * Returns an @a immutable form of this container, an - * `immer::vector`. - */ - IMMER_NODISCARD persistent_type persistent() & - { - this->owner_t::operator=(owner_t{}); - return persistent_type{impl_}; - } - IMMER_NODISCARD persistent_type persistent() && - { - return persistent_type{std::move(impl_)}; - } - -private: - friend flex_t; - friend persistent_type; - - vector_transient(impl_t impl) - : impl_(std::move(impl)) - {} - - impl_t impl_ = impl_t::empty(); -}; - -} // namespace immer diff --git a/third_party/immer/nix/benchmarks.nix b/third_party/immer/nix/benchmarks.nix deleted file mode 100644 index 9eaa87e291d0..000000000000 --- a/third_party/immer/nix/benchmarks.nix +++ /dev/null @@ -1,100 +0,0 @@ -{ nixpkgs ? <nixpkgs>}: - -with import nixpkgs {}; - -rec { - c_rrb = stdenv.mkDerivation rec { - name = "c-rrb-${version}"; - version = "git-${commit}"; - commit = "d908617ff84515af90c454ff4d0f98675ae6b456"; - src = fetchFromGitHub { - owner = "hyPiRion"; - repo = "c-rrb"; - rev = commit; - sha256 = "0zmha3xi80vgdcwzb4vwdllf97dvggjpjfgahrpsb5f5qi3yshxa"; - }; - nativeBuildInputs = [ autoreconfHook ]; - propagatedBuildInputs = [ boehmgc ]; - meta = with stdenv.lib; { - homepage = "http://hypirion.com/thesis"; - description = "RRB-tree implemented as a library in C. "; - license = licenses.mit; - }; - }; - - steady = stdenv.mkDerivation rec { - name = "steady-${version}"; - version = "git-${commit}"; - commit = "aac65955f18d0de856e3421d8593378d5e1832c4"; - src = fetchFromGitHub { - owner = "marcusz"; - repo = "steady"; - rev = commit; - sha256 = "0zaxr9aj1q5sr99h133fzxch8lw9daw1pxs2g972s02gdq8r8fzh"; - }; - dontBuild = true; - installPhase = "mkdir -vp $out/include; cp -vr $src/steady $out/include/"; - meta = with stdenv.lib; { - homepage = "https://github.com/marcusz/steady"; - description = "This is a fast and reliable persistent (immutable) vector class for C++"; - license = licenses.asl20; - }; - }; - - chunkedseq = stdenv.mkDerivation rec { - name = "chunkedseq-${version}"; - version = "git-${commit}"; - commit = "f1c4f9470edcb59996fdc4aad34311767c46b25e"; - src = fetchFromGitHub { - owner = "deepsea-inria"; - repo = "chunkedseq"; - rev = commit; - sha256 = "19bps5r3dy55jlvpwq8x2s4d0mwwx0djb6g2r2vvbf628bg6cx8p"; - }; - dontBuild = true; - installPhase = "mkdir -vp $out/include/chunkedseq; cp -vr $src/include/* $out/include/chunkedseq/"; - meta = with stdenv.lib; { - homepage = "http://deepsea.inria.fr/chunkedseq"; - description = "Container data structure for representing sequences by many fixed-capacity heap-allocated buffers--chunks"; - license = licenses.mit; - }; - }; - - immutable_cpp = stdenv.mkDerivation rec { - name = "immutable-cpp-${version}"; - version = "git-${commit}"; - commit = "a4a32022d895dd0d3c03547a2b2a2b03face01eb"; - src = fetchFromGitHub { - owner = "rsms"; - repo = "immutable-cpp"; - rev = commit; - sha256 = "11zn67avqcc8baddf43fsd29bpv08p0ri6zqng12105k725fq2p7"; - }; - dontBuild = true; - installPhase = "mkdir -vp $out/include; cp -vr $src/immutable $out/include/"; - meta = with stdenv.lib; { - homepage = "https://github.com/rsms/immutable-cpp"; - description = "Persistent immutable data structures for C++"; - license = licenses.mit; - }; - }; - - hash_trie = stdenv.mkDerivation rec { - name = "hash_trie-${version}"; - version = "git-${commit}"; - commit = "1ce346c74923ba16329332103dc0f425b658c8be"; - src = fetchFromGitHub { - owner = "philsquared"; - repo = "hash_trie"; - rev = commit; - sha256 = "0rpa1682vm0fvvrs1jr7jdkskcrgkm3qrawrcr7xrmknz5jf0v4l"; - }; - dontBuild = true; - installPhase = "mkdir -vp $out/include; cp -vr $src/hash_trie.hpp $out/include/"; - meta = with stdenv.lib; { - homepage = "https://github.com/rsms/immutable-cpp"; - description = "Persistent immutable data structures for C++"; - license = licenses.mit; - }; - }; -} diff --git a/third_party/immer/nix/docs.nix b/third_party/immer/nix/docs.nix deleted file mode 100644 index f885e6d9e177..000000000000 --- a/third_party/immer/nix/docs.nix +++ /dev/null @@ -1,27 +0,0 @@ -{ nixpkgs ? <nixpkgs>}: - -with import nixpkgs {}; - -rec { - breathe = with python27Packages; buildPythonPackage rec { - version = "git-arximboldi-${commit}"; - pname = "breathe"; - name = "${pname}-${version}"; - commit = "5074aecb5ad37bb70f50216eaa01d03a375801ec"; - src = fetchFromGitHub { - owner = "arximboldi"; - repo = "breathe"; - rev = commit; - sha256 = "10kkh3wb0ggyxx1a7x50aklhhw0cq269g3jddf2gb3pv9gpbj7sa"; - }; - propagatedBuildInputs = [ docutils sphinx ]; - meta = with stdenv.lib; { - homepage = https://github.com/michaeljones/breathe; - license = licenses.bsd3; - description = "Sphinx Doxygen renderer"; - inherit (sphinx.meta) platforms; - }; - }; - - recommonmark = python27Packages.recommonmark; -} diff --git a/third_party/immer/setup.py b/third_party/immer/setup.py deleted file mode 100644 index 98c08449bcc3..000000000000 --- a/third_party/immer/setup.py +++ /dev/null @@ -1,68 +0,0 @@ - -# immer: immutable data structures for C++ -# Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -# -# This software is distributed under the Boost Software License, Version 1.0. -# See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt - -## - -import os -import re -import sys -import platform -import subprocess - -from distutils.version import LooseVersion -from setuptools import setup, Extension -from setuptools.command.build_ext import build_ext - -class CMakeExtension(Extension): - def __init__(self, name, sourcedir=''): - Extension.__init__(self, name, sources=[]) - self.sourcedir = os.path.abspath(sourcedir) - -class CMakeBuild(build_ext): - - def run(self): - try: - subprocess.check_output(['cmake', '--version']) - except OSError: - raise RuntimeError( - "CMake must be installed to build the following extensions: " + - ", ".join(e.name for e in self.extensions)) - for ext in self.extensions: - self.build_extension(ext) - - def build_extension(self, ext): - extdir = os.path.abspath(os.path.dirname( - self.get_ext_fullpath(ext.name))) - cfg = 'Debug' if self.debug else 'Release' - if not os.path.exists(self.build_temp): - os.makedirs(self.build_temp) - subprocess.check_call([ - 'cmake', ext.sourcedir, - '-DCMAKE_BUILD_TYPE=' + cfg, - '-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, - '-DPYTHON_EXECUTABLE=' + sys.executable, - '-DDISABLE_WERROR=1', - ], cwd=self.build_temp) - subprocess.check_call([ - 'cmake', '--build', '.', - '--config', cfg, - '--target', 'python', - ], cwd=self.build_temp) - -setup( - name='immer', - version='0.0.0', - author='Juan Pedro Bolivar Puente', - author_email='raskolnikov@gnu.org', - description='Efficient immutable data structures', - long_description='', - packages=['immer'], - package_dir={'': 'extra/python'}, - ext_modules=[CMakeExtension('immer_python_module', sourcedir='.')], - cmdclass=dict(build_ext=CMakeBuild), - zip_safe=False, -) diff --git a/third_party/immer/shell.nix b/third_party/immer/shell.nix deleted file mode 100644 index 07629a197143..000000000000 --- a/third_party/immer/shell.nix +++ /dev/null @@ -1,65 +0,0 @@ -{ toolchain ? "", - nixpkgs ? (import <nixpkgs> {}).fetchFromGitHub { - owner = "NixOS"; - repo = "nixpkgs"; - rev = "053ad4e0db7241ae6a02394d62750fdc5d64aa9f"; - sha256 = "11l9sr8zg8j1n5p43zjkqwpj59gn8c84z1kf16icnsbnv2smzqdc"; - }}: - -with import nixpkgs {}; - -let - # For the documentation tools we use an older Nixpkgs since the - # newer versions seem to be not working great... - oldNixpkgsSrc = fetchFromGitHub { - owner = "NixOS"; - repo = "nixpkgs"; - rev = "d0d905668c010b65795b57afdf7f0360aac6245b"; - sha256 = "1kqxfmsik1s1jsmim20n5l4kq6wq8743h5h17igfxxbbwwqry88l"; - }; - oldNixpkgs = import oldNixpkgsSrc {}; - docs = import ./nix/docs.nix { nixpkgs = oldNixpkgsSrc; }; - benchmarks = import ./nix/benchmarks.nix { inherit nixpkgs; }; - tc = - if toolchain == "" then { stdenv = stdenv; cc = stdenv.cc; } else - if toolchain == "gnu-6" then { stdenv = gcc6Stdenv; cc = gcc6; } else - if toolchain == "gnu-7" then { stdenv = gcc7Stdenv; cc = gcc7; } else - if toolchain == "gnu-8" then { stdenv = gcc8Stdenv; cc = gcc8; } else - if toolchain == "gnu-9" then { stdenv = gcc9Stdenv; cc = gcc9; } else - if toolchain == "llvm-39" then { stdenv = llvmPackages_39.libcxxStdenv; cc = llvmPackages_39.libcxxClang; } else - if toolchain == "llvm-4" then { stdenv = llvmPackages_4.libcxxStdenv; cc = llvmPackages_4.libcxxClang; } else - if toolchain == "llvm-5" then { stdenv = llvmPackages_5.libcxxStdenv; cc = llvmPackages_5.libcxxClang; } else - if toolchain == "llvm-6" then { stdenv = llvmPackages_6.libcxxStdenv; cc = llvmPackages_6.libcxxClang; } else - if toolchain == "llvm-7" then { stdenv = llvmPackages_7.libcxxStdenv; cc = llvmPackages_7.libcxxClang; } else - if toolchain == "llvm-8" then { stdenv = llvmPackages_8.libcxxStdenv; cc = llvmPackages_8.libcxxClang; } else - if toolchain == "llvm-9" then { stdenv = llvmPackages_9.stdenv; cc = llvmPackages_9.clang; } else - abort "unknown toolchain"; - -in -tc.stdenv.mkDerivation rec { - name = "immer-env"; - buildInputs = [ - tc.cc - git - cmake - pkgconfig - ninja - gdb - lldb - ccache - boost - boehmgc - benchmarks.c_rrb - benchmarks.steady - benchmarks.chunkedseq - benchmarks.immutable_cpp - benchmarks.hash_trie - oldNixpkgs.doxygen - (oldNixpkgs.python.withPackages (ps: [ - ps.sphinx - docs.breathe - docs.recommonmark - ])) - ]; - hardeningDisable = [ "fortify" ]; -} diff --git a/third_party/immer/test/CMakeLists.txt b/third_party/immer/test/CMakeLists.txt deleted file mode 100644 index faa61bbe6d9f..000000000000 --- a/third_party/immer/test/CMakeLists.txt +++ /dev/null @@ -1,22 +0,0 @@ - -# Targets -# ======= - -add_custom_target(tests - COMMENT "Build all the unit tests.") -add_dependencies(check tests) - -include(CTest) - -file(GLOB_RECURSE immer_unit_tests "*.cpp") -foreach(_file IN LISTS immer_unit_tests) - immer_target_name_for(_target _output "${_file}") - add_executable(${_target} EXCLUDE_FROM_ALL "${_file}") - set_target_properties(${_target} PROPERTIES OUTPUT_NAME ${_output}) - add_dependencies(tests ${_target}) - target_compile_definitions(${_target} PUBLIC - DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - CATCH_CONFIG_MAIN) - target_link_libraries(${_target} PUBLIC immer-dev) - add_test("test/${_output}" ${_output}) -endforeach() diff --git a/third_party/immer/test/array/default.cpp b/third_party/immer/test/array/default.cpp deleted file mode 100644 index 928fffaaac5b..000000000000 --- a/third_party/immer/test/array/default.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/array.hpp> - -#define VECTOR_T ::immer::array -#include "../vector/generic.ipp" diff --git a/third_party/immer/test/array/gc.cpp b/third_party/immer/test/array/gc.cpp deleted file mode 100644 index a994208bc745..000000000000 --- a/third_party/immer/test/array/gc.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/array.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename T> -using test_array_t = immer::array<T, gc_memory>; - -#define VECTOR_T test_array_t -#include "../vector/generic.ipp" diff --git a/third_party/immer/test/array_transient/default.cpp b/third_party/immer/test/array_transient/default.cpp deleted file mode 100644 index aa603c7b0aab..000000000000 --- a/third_party/immer/test/array_transient/default.cpp +++ /dev/null @@ -1,41 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/array.hpp> -#include <immer/array_transient.hpp> - -#define VECTOR_T ::immer::array -#define VECTOR_TRANSIENT_T ::immer::array_transient - -#include "../vector_transient/generic.ipp" - -TEST_CASE("array_transient default constructor compiles") -{ - immer::array_transient<int> transient; -} - -TEST_CASE("array provides mutable data") -{ - auto arr = immer::array<int>(10, 0); - CHECK(arr.size() == 10); - auto tr = arr.transient(); - CHECK(tr.data() == arr.data()); - - auto d = tr.data_mut(); - CHECK(tr.data_mut() != arr.data()); - CHECK(tr.data() == tr.data_mut()); - CHECK(arr.data() != tr.data_mut()); - - arr = tr.persistent(); - CHECK(arr.data() == d); - CHECK(arr.data() == tr.data()); - - CHECK(tr.data_mut() != arr.data()); - CHECK(tr.data() == tr.data_mut()); - CHECK(arr.data() != tr.data_mut()); -} diff --git a/third_party/immer/test/array_transient/gc.cpp b/third_party/immer/test/array_transient/gc.cpp deleted file mode 100644 index 4b40185e94fa..000000000000 --- a/third_party/immer/test/array_transient/gc.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/array.hpp> -#include <immer/array_transient.hpp> - -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename T> -using test_array_t = immer::array<T, gc_memory>; - -template <typename T> -using test_array_transient_t = immer::array_transient<T, gc_memory>; - -#define VECTOR_T test_array_t -#define VECTOR_TRANSIENT_T test_array_transient_t - -#include "../vector_transient/generic.ipp" - -TEST_CASE("array provides mutable data") -{ - auto arr = immer::array<int, gc_memory>(10, 0); - CHECK(arr.size() == 10); - auto tr = arr.transient(); - CHECK(tr.data() == arr.data()); - - auto d = tr.data_mut(); - CHECK(tr.data_mut() != arr.data()); - CHECK(tr.data() == tr.data_mut()); - CHECK(arr.data() != tr.data_mut()); - - arr = tr.persistent(); - CHECK(arr.data() == d); - CHECK(arr.data() == tr.data()); - - CHECK(tr.data_mut() != arr.data()); - CHECK(tr.data() == tr.data_mut()); - CHECK(arr.data() != tr.data_mut()); -} diff --git a/third_party/immer/test/atom/default.cpp b/third_party/immer/test/atom/default.cpp deleted file mode 100644 index 7a382c70a85d..000000000000 --- a/third_party/immer/test/atom/default.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/atom.hpp> - -#define ATOM_T ::immer::atom -#include "generic.ipp" diff --git a/third_party/immer/test/atom/gc.cpp b/third_party/immer/test/atom/gc.cpp deleted file mode 100644 index f3219e81c601..000000000000 --- a/third_party/immer/test/atom/gc.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/atom.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy>; - -template <typename T> -using test_atom_t = immer::atom<T, gc_memory>; - -#define ATOM_T test_atom_t -#include "generic.ipp" diff --git a/third_party/immer/test/atom/generic.ipp b/third_party/immer/test/atom/generic.ipp deleted file mode 100644 index 21ff74d7ef69..000000000000 --- a/third_party/immer/test/atom/generic.ipp +++ /dev/null @@ -1,53 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#ifndef ATOM_T -#error "define the box template to use in ATOM_T" -#endif - -#include <catch.hpp> - -template <typename T> -using BOX_T = typename ATOM_T<T>::box_type; - -TEST_CASE("construction") { ATOM_T<int> x; } - -TEST_CASE("store, load, exchange") -{ - ATOM_T<int> x; - CHECK(x.load() == BOX_T<int>{0}); - x.store(42); - CHECK(x.load() == BOX_T<int>{42}); - auto old = x.exchange(12); - CHECK(old == 42); - CHECK(x.load() == BOX_T<int>{12}); -} - -TEST_CASE("box conversion") -{ - ATOM_T<int> x; - auto v1 = BOX_T<int>{42}; - x = v1; - auto v2 = BOX_T<int>{x}; - CHECK(v1 == v2); -} - -TEST_CASE("value conversion") -{ - ATOM_T<int> x; - x = 42; - auto v = int{x}; - CHECK(v == 42); -} - -TEST_CASE("update") -{ - ATOM_T<int> x{42}; - x.update([](auto x) { return x + 2; }); - CHECK(x.load() == 44); -} diff --git a/third_party/immer/test/box/default.cpp b/third_party/immer/test/box/default.cpp deleted file mode 100644 index fbd1b178df08..000000000000 --- a/third_party/immer/test/box/default.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/box.hpp> - -#define BOX_T ::immer::box -#include "generic.ipp" diff --git a/third_party/immer/test/box/gc.cpp b/third_party/immer/test/box/gc.cpp deleted file mode 100644 index 04e459559abc..000000000000 --- a/third_party/immer/test/box/gc.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/box.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy>; - -template <typename T> -using test_box_t = immer::box<T, gc_memory>; - -#define BOX_T test_box_t -#include "generic.ipp" diff --git a/third_party/immer/test/box/generic.ipp b/third_party/immer/test/box/generic.ipp deleted file mode 100644 index cfb5f04ea1b9..000000000000 --- a/third_party/immer/test/box/generic.ipp +++ /dev/null @@ -1,58 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#ifndef BOX_T -#error "define the box template to use in BOX_T" -#endif - -#include <catch.hpp> - -TEST_CASE("construction and copy") -{ - auto x = BOX_T<int>{}; - CHECK(x == 0); - - auto y = x; - CHECK(&x.get() == &y.get()); - - auto z = std::move(x); - CHECK(&z.get() == &y.get()); -} - -TEST_CASE("equality") -{ - auto x = BOX_T<int>{}; - auto y = x; - CHECK(x == 0.0f); - CHECK(x == y); - CHECK(x == BOX_T<int>{}); - CHECK(x != BOX_T<int>{42}); -} - -TEST_CASE("update") -{ - auto x = BOX_T<int>{}; - auto y = x.update([](auto v) { return v + 1; }); - CHECK(x == 0); - CHECK(y == 1); -} - -TEST_CASE("update move") -{ - auto x = BOX_T<int>{}; - auto addr = &x.get(); - auto y = std::move(x).update( - [](auto&& v) { return std::forward<decltype(v)>(v) + 1; }); - - CHECK(y == 1); - if (std::is_empty<typename BOX_T<int>::memory_policy::refcount>::value) { - CHECK(&y.get() != addr); - } else { - CHECK(&y.get() == addr); - } -} diff --git a/third_party/immer/test/box/recursive.cpp b/third_party/immer/test/box/recursive.cpp deleted file mode 100644 index 4c8fce07dea2..000000000000 --- a/third_party/immer/test/box/recursive.cpp +++ /dev/null @@ -1,108 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/algorithm.hpp> -#include <immer/box.hpp> -#include <immer/flex_vector.hpp> -#include <immer/map.hpp> -#include <immer/set.hpp> -#include <immer/vector.hpp> - -#include <catch.hpp> - -struct rec_vec -{ - int data; - immer::vector<immer::box<rec_vec>> children; -}; - -TEST_CASE("recursive vector") -{ - auto v1 = rec_vec{42, - {rec_vec{12, {}}, - rec_vec{13, {rec_vec{5, {}}, rec_vec{7, {}}}}, - rec_vec{15, {}}}}; - CHECK(v1.data == 42); - CHECK(v1.children[0]->data == 12); - CHECK(v1.children[1]->children[0]->data == 5); -} - -struct rec_fvec -{ - int data; - immer::flex_vector<immer::box<rec_fvec>> children; -}; - -TEST_CASE("recursive flex_vector") -{ - auto v1 = rec_fvec{42, - {rec_fvec{12, {}}, - rec_fvec{13, {rec_fvec{5, {}}, rec_fvec{7, {}}}}, - rec_fvec{15, {}}}}; - CHECK(v1.data == 42); - CHECK(v1.children[0]->data == 12); - CHECK(v1.children[1]->children[0]->data == 5); -} - -struct rec_map -{ - int data; - immer::map<std::string, immer::box<rec_map>> children; -}; - -TEST_CASE("recursive map") -{ - auto v1 = rec_map{42, {}}; - auto v2 = rec_map{43, v1.children.set("hello", rec_map{12, {}})}; - auto v3 = rec_map{44, v2.children.set("world", rec_map{13, {}})}; - - CHECK(v3.data == 44); - CHECK(v3.children["hello"]->data == 12); - CHECK(v3.children["world"]->data == 13); -} - -struct rec_set -{ - int data; - immer::set<immer::box<rec_set>> children; - - bool operator==(const rec_set& other) const - { - return data == other.data && children == other.children; - } - bool operator!=(const rec_set& other) const { return !(*this == other); } -}; - -namespace std { - -template <> -struct hash<rec_set> -{ - auto operator()(const rec_set& s) - { - return std::hash<decltype(s.data)>{}(s.data) ^ - immer::accumulate( - s.children, std::size_t{}, [](auto ac, auto v) { - return std::hash<decltype(v)>{}(v); - }); - } -}; - -} // namespace std - -TEST_CASE("recursive set") -{ - auto v1 = rec_set{42, {}}; - auto v2 = rec_set{43, v1.children.insert(rec_set{12, {}})}; - auto v3 = rec_set{44, v2.children.insert(rec_set{13, {}})}; - - CHECK(v3.data == 44); - CHECK(v3.children.count(rec_set{12, {}}) == 1); - CHECK(v3.children.count(rec_set{13, {}}) == 1); - CHECK(v3.children.count(rec_set{14, {}}) == 0); -} diff --git a/third_party/immer/test/box/vector-of-boxes-transient.cpp b/third_party/immer/test/box/vector-of-boxes-transient.cpp deleted file mode 100644 index 623c8ba37d32..000000000000 --- a/third_party/immer/test/box/vector-of-boxes-transient.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/box.hpp> -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -#include <catch.hpp> - -TEST_CASE("issue-33") -{ - using Element = immer::box<std::string>; - auto vect = immer::vector<Element>{}; - - // this one works fine - for (auto i = 0; i < 100; ++i) { - vect = vect.push_back(Element("x")); - } - - // this one doesn't compile - auto t = vect.transient(); - - for (auto i = 0; i < 100; ++i) { - t.push_back(Element("x")); - } - - vect = t.persistent(); - - CHECK(*vect[0] == "x"); - CHECK(*vect[99] == "x"); -} diff --git a/third_party/immer/test/dada.hpp b/third_party/immer/test/dada.hpp deleted file mode 100644 index 1465bf7bf52d..000000000000 --- a/third_party/immer/test/dada.hpp +++ /dev/null @@ -1,243 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <array> -#include <cstddef> -#include <utility> - -#include <immer/detail/hamts/bits.hpp> -#include <immer/detail/rbts/bits.hpp> - -namespace { - -template <typename Iterator> -struct rotator -{ - using value_type = typename std::iterator_traits<Iterator>::value_type; - - Iterator first; - Iterator last; - Iterator curr; - - void init(Iterator f, Iterator l) - { - first = f; - last = l; - curr = f; - } - - value_type next() - { - if (curr == last) - curr = first; - return *curr++; - } -}; - -template <typename Range> -struct range_rotator : rotator<typename Range::iterator> -{ - using base_t = rotator<typename Range::iterator>; - - Range range; - - range_rotator(Range r) - : range{std::move(r)} - { - base_t::init(range.begin(), range.end()); - } -}; - -template <typename Range> -auto make_rotator(Range r) -> range_rotator<Range> -{ - return {r}; -} - -inline auto magic_rotator() -{ - return make_rotator(std::array<unsigned, 15>{ - {7, 11, 2, 3, 5, 7, 11, 13, 17, 19, 23, 5, 29, 31, 37}}); -} - -struct dada_error -{}; - -struct dadaism; -static dadaism* g_dadaism = nullptr; - -struct dadaism -{ - using rotator_t = decltype(magic_rotator()); - - rotator_t magic = magic_rotator(); - - unsigned step = magic.next(); - unsigned count = 0; - unsigned happenings = 0; - unsigned last = 0; - bool toggle = false; - - struct scope - { - bool moved = false; - dadaism* save_ = g_dadaism; - scope(scope&& s) - { - save_ = s.save_; - s.moved = true; - } - scope(dadaism* self) { g_dadaism = self; } - ~scope() - { - if (!moved) - g_dadaism = save_; - } - }; - - static scope disable() { return {nullptr}; } - - scope next() - { - toggle = last == happenings; - last = happenings; - step = toggle ? step : magic.next(); - return {this}; - } - - void dada() - { - if (toggle && ++count % step == 0) { - ++happenings; - throw dada_error{}; - } - } -}; - -inline void dada() -{ - if (g_dadaism) - g_dadaism->dada(); -} - -inline bool soft_dada() -{ - try { - dada(); - return false; - } catch (dada_error) { - return true; - } -} - -template <typename Heap> -struct dadaist_heap : Heap -{ - template <typename... Tags> - static auto allocate(std::size_t s, Tags... tags) - { - dada(); - return Heap::allocate(s, tags...); - } -}; - -template <typename MP> -struct dadaist_memory_policy : MP -{ - struct heap - { - using type = dadaist_heap<typename MP::heap::type>; - - template <std::size_t Size> - struct optimized - { - using base = typename MP::heap::template optimized<Size>::type; - using type = dadaist_heap<base>; - }; - }; -}; - -struct tristan_tzara -{ - tristan_tzara() { dada(); } - tristan_tzara(const tristan_tzara&) { dada(); } - tristan_tzara(tristan_tzara&&) { dada(); } - tristan_tzara& operator=(const tristan_tzara&) - { - dada(); - return *this; - } - tristan_tzara& operator=(tristan_tzara&&) - { - dada(); - return *this; - } -}; - -template <typename T> -struct dadaist : tristan_tzara -{ - T value; - - dadaist() - : value{} - {} - dadaist(T v) - : value{std::move(v)} - {} - operator T() const { return value; } -}; - -template <typename T> -struct dadaist_wrapper; - -using rbits_t = immer::detail::rbts::bits_t; -using hbits_t = immer::detail::rbts::bits_t; - -template <template <class, class, rbits_t, rbits_t> class V, - typename T, - typename MP, - rbits_t B, - rbits_t BL> -struct dadaist_wrapper<V<T, MP, B, BL>> -{ - using type = V<dadaist<T>, dadaist_memory_policy<MP>, B, BL>; -}; - -template <template <class, class> class V, typename T, typename MP> -struct dadaist_wrapper<V<T, MP>> -{ - using type = V<dadaist<T>, dadaist_memory_policy<MP>>; -}; - -template <template <class, class, class, class, hbits_t> class V, - typename T, - typename E, - typename H, - typename MP, - hbits_t B> -struct dadaist_wrapper<V<T, H, E, MP, B>> -{ - using type = V<dadaist<T>, H, E, dadaist_memory_policy<MP>, B>; -}; - -template <template <class, class, class, class, class, hbits_t> class V, - typename K, - typename T, - typename E, - typename H, - typename MP, - hbits_t B> -struct dadaist_wrapper<V<K, T, H, E, MP, B>> -{ - using type = V<K, dadaist<T>, H, E, dadaist_memory_policy<MP>, B>; -}; - -} // anonymous namespace diff --git a/third_party/immer/test/detail/type_traits.cpp b/third_party/immer/test/detail/type_traits.cpp deleted file mode 100644 index 8809418ccea6..000000000000 --- a/third_party/immer/test/detail/type_traits.cpp +++ /dev/null @@ -1,215 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <catch.hpp> -#include <forward_list> -#include <immer/detail/type_traits.hpp> -#include <list> -#include <vector> - -struct string_sentinel -{}; -bool operator==(const char* i, string_sentinel); -bool operator!=(const char* i, string_sentinel); - -TEST_CASE("compatible_sentinel_v") -{ - SECTION("iterator pairs") - { - using Iter = std::vector<int>::iterator; - static_assert(immer::detail::compatible_sentinel_v<Iter, Iter>, ""); - } - - SECTION("pointer pairs") - { - using Iter = char*; - static_assert(immer::detail::compatible_sentinel_v<Iter, Iter>, ""); - } - - SECTION("iterator/sentinel pair") - { - using Iter = char*; - using Sent = string_sentinel; - static_assert(immer::detail::compatible_sentinel_v<Iter, Sent>, ""); - } - - SECTION("incompatible pair") - { - using Iter1 = std::vector<int>::iterator; - using Iter2 = std::list<double>::iterator; - static_assert(not immer::detail::compatible_sentinel_v<Iter1, Iter2>, - ""); - } -} - -TEST_CASE("equality comparable") -{ - SECTION("iterator pairs") - { - using Iter = std::vector<int>::iterator; - static_assert(immer::detail::is_equality_comparable_v<Iter, Iter>, ""); - } - - SECTION("pointer pairs") - { - using Iter = char*; - static_assert(immer::detail::is_equality_comparable_v<Iter, Iter>, ""); - } - - SECTION("iterator/sentinel pair") - { - using Iter = char*; - using Sent = string_sentinel; - static_assert(immer::detail::is_equality_comparable_v<Iter, Sent>, ""); - } - - SECTION("not equality comparable") - { - static_assert( - not immer::detail::is_equality_comparable_v<std::string, double>, - ""); - } -} - -TEST_CASE("inequality comparable") -{ - SECTION("iterator pairs") - { - using Iter = std::vector<int>::iterator; - static_assert(immer::detail::is_inequality_comparable_v<Iter, Iter>, - ""); - } - - SECTION("pointer pairs") - { - using Iter = char*; - static_assert(immer::detail::is_inequality_comparable_v<Iter, Iter>, - ""); - } - - SECTION("iterator/sentinel pair") - { - using Iter = char*; - using Sent = string_sentinel; - static_assert(immer::detail::is_inequality_comparable_v<Iter, Sent>, - ""); - } - - SECTION("not inequality comparable") - { - static_assert( - not immer::detail::is_inequality_comparable_v<std::string, double>, - ""); - } -} - -TEST_CASE("is dereferenceable") -{ - SECTION("iterator") - { - using Iter = std::vector<int>::iterator; - static_assert(immer::detail::is_dereferenceable_v<Iter>, ""); - } - - SECTION("pointer") - { - using Iter = char*; - static_assert(immer::detail::is_dereferenceable_v<Iter>, ""); - } - - SECTION("not dereferenceable") - { - static_assert(not immer::detail::is_dereferenceable_v<int>, ""); - } -} - -TEST_CASE("is forward iterator") -{ - SECTION("random access iterator") - { - using Iter = std::vector<int>::iterator; - static_assert(immer::detail::is_forward_iterator_v<Iter>, ""); - } - - SECTION("bidirectional iterator") - { - using Iter = std::list<int>::iterator; - static_assert(immer::detail::is_forward_iterator_v<Iter>, ""); - } - - SECTION("forward iterator") - { - using Iter = std::forward_list<int>::iterator; - static_assert(immer::detail::is_forward_iterator_v<Iter>, ""); - } - - SECTION("input iterator") - { - using Iter = std::istream_iterator<double>; - static_assert(not immer::detail::is_forward_iterator_v<Iter>, ""); - } - - SECTION("output iterator") - { - using Iter = std::ostream_iterator<double>; - static_assert(not immer::detail::is_forward_iterator_v<Iter>, ""); - } - - SECTION("pointer") - { - using Iter = char*; - static_assert(immer::detail::is_forward_iterator_v<Iter>, ""); - } -} - -TEST_CASE("is iterator") -{ - SECTION("iterator") - { - using Iter = std::vector<int>::iterator; - static_assert(immer::detail::is_iterator_v<Iter>, ""); - } - - SECTION("pointer") - { - using Iter = char*; - static_assert(immer::detail::is_iterator_v<Iter>, ""); - } - - SECTION("not iterator") - { - static_assert(not immer::detail::is_iterator_v<int>, ""); - } -} - -TEST_CASE("provides preincrement") -{ - SECTION("iterator") - { - using Iter = std::vector<int>::iterator; - static_assert(immer::detail::is_preincrementable_v<Iter>, ""); - } - - SECTION("pointer") - { - using Iter = char*; - static_assert(immer::detail::is_preincrementable_v<Iter>, ""); - } - - SECTION("does not provide preincrement") - { - struct type - {}; - static_assert(not immer::detail::is_preincrementable_v<type>, ""); - } -} - -TEST_CASE("void_t") -{ - static_assert(std::is_same<void, immer::detail::void_t<int>>::value, ""); -} diff --git a/third_party/immer/test/experimental/dvektor.cpp b/third_party/immer/test/experimental/dvektor.cpp deleted file mode 100644 index 437384a72771..000000000000 --- a/third_party/immer/test/experimental/dvektor.cpp +++ /dev/null @@ -1,198 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/experimental/dvektor.hpp> - -#include <boost/range/adaptors.hpp> - -#include <algorithm> -#include <numeric> -#include <vector> -#include <iostream> - -#include <doctest.h> - -using namespace immer; - -TEST_CASE("instantiation") -{ - auto v = dvektor<int>{}; - CHECK(v.size() == 0u); -} - -TEST_CASE("push back one element") -{ - SUBCASE("one element") - { - const auto v1 = dvektor<int>{}; - auto v2 = v1.push_back(42); - CHECK(v1.size() == 0u); - CHECK(v2.size() == 1u); - CHECK(v2[0] == 42); - } - - SUBCASE("many elements") - { - const auto n = 666u; - auto v = dvektor<unsigned>{}; - for (auto i = 0u; i < n; ++i) { - v = v.push_back(i * 10); - CHECK(v.size() == i + 1); - for (auto j = 0u; j < v.size(); ++j) - CHECK(i + v[j] == i + j * 10); - } - } -} - -TEST_CASE("update") -{ - const auto n = 42u; - auto v = dvektor<unsigned>{}; - for (auto i = 0u; i < n; ++i) - v = v.push_back(i); - - SUBCASE("assoc") - { - const auto u = v.assoc(3u, 13u); - CHECK(u.size() == v.size()); - CHECK(u[2u] == 2u); - CHECK(u[3u] == 13u); - CHECK(u[4u] == 4u); - CHECK(u[40u] == 40u); - CHECK(v[3u] == 3u); - } - - SUBCASE("assoc further") - { - for (auto i = n; i < 666; ++i) - v = v.push_back(i); - - auto u = v.assoc(3u, 13u); - u = u.assoc(200u, 7u); - CHECK(u.size() == v.size()); - - CHECK(u[2u] == 2u); - CHECK(u[4u] == 4u); - CHECK(u[40u] == 40u); - CHECK(u[600u] == 600u); - - CHECK(u[3u] == 13u); - CHECK(u[200u] == 7u); - - CHECK(v[3u] == 3u); - CHECK(v[200u] == 200u); - } - - SUBCASE("assoc further more") - { - auto v = immer::dvektor<unsigned, 4>{}; - - for (auto i = n; i < 1000u; ++i) - v = v.push_back(i); - - for (auto i = 0u; i < v.size(); ++i) { - v = v.assoc(i, i + 1); - CHECK(v[i] == i + 1); - } - } - - SUBCASE("update") - { - const auto u = v.update(10u, [](auto x) { return x + 10; }); - CHECK(u.size() == v.size()); - CHECK(u[10u] == 20u); - CHECK(v[40u] == 40u); - - const auto w = v.update(40u, [](auto x) { return x - 10; }); - CHECK(w.size() == v.size()); - CHECK(w[40u] == 30u); - CHECK(v[40u] == 40u); - } -} - -#if IMMER_SLOW_TESTS -TEST_CASE("big") -{ - const auto n = 1000000; - auto v = dvektor<unsigned>{}; - for (auto i = 0u; i < n; ++i) - v = v.push_back(i); - - SUBCASE("read") - { - for (auto i = 0u; i < n; ++i) - CHECK(v[i] == i); - } - - SUBCASE("assoc") - { - for (auto i = 0u; i < n; ++i) { - v = v.assoc(i, i + 1); - CHECK(v[i] == i + 1); - } - } -} -#endif // IMMER_SLOW_TESTS - -TEST_CASE("iterator") -{ - const auto n = 666u; - auto v = dvektor<unsigned>{}; - for (auto i = 0u; i < n; ++i) - v = v.push_back(i); - - SUBCASE("works with range loop") - { - auto i = 0u; - for (const auto& x : v) - CHECK(x == i++); - CHECK(i == v.size()); - } - - SUBCASE("works with standard algorithms") - { - auto s = std::vector<unsigned>(n); - std::iota(s.begin(), s.end(), 0u); - std::equal(v.begin(), v.end(), s.begin(), s.end()); - } - - SUBCASE("can go back from end") { CHECK(n - 1 == *--v.end()); } - - SUBCASE("works with reversed range adaptor") - { - auto r = v | boost::adaptors::reversed; - auto i = n; - for (const auto& x : r) - CHECK(x == --i); - } - - SUBCASE("works with strided range adaptor") - { - auto r = v | boost::adaptors::strided(5); - auto i = 0u; - for (const auto& x : r) - CHECK(x == 5 * i++); - } - - SUBCASE("works reversed") - { - auto i = n; - for (auto iter = v.rbegin(), last = v.rend(); iter != last; ++iter) - CHECK(*iter == --i); - } - - SUBCASE("advance and distance") - { - auto i1 = v.begin(); - auto i2 = i1 + 100; - CHECK(*i2 == 100u); - CHECK(i2 - i1 == 100); - CHECK(*(i2 - 50) == 50u); - CHECK((i2 - 30) - i2 == -30); - } -} diff --git a/third_party/immer/test/flex_vector/B3-BL0.cpp b/third_party/immer/test/flex_vector/B3-BL0.cpp deleted file mode 100644 index 83af21d688fc..000000000000 --- a/third_party/immer/test/flex_vector/B3-BL0.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/vector.hpp> - -template <typename T> -using test_flex_vector_t = - immer::flex_vector<T, immer::default_memory_policy, 3u, 0u>; - -template <typename T> -using test_vector_t = immer::vector<T, immer::default_memory_policy, 3u, 0u>; - -#define FLEX_VECTOR_T test_flex_vector_t -#define VECTOR_T test_vector_t -#include "generic.ipp" diff --git a/third_party/immer/test/flex_vector/B3-BL3.cpp b/third_party/immer/test/flex_vector/B3-BL3.cpp deleted file mode 100644 index e44f7e2bfaba..000000000000 --- a/third_party/immer/test/flex_vector/B3-BL3.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/vector.hpp> - -template <typename T> -using test_flex_vector_t = - immer::flex_vector<T, immer::default_memory_policy, 3u, 3u>; - -template <typename T> -using test_vector_t = immer::vector<T, immer::default_memory_policy, 3u, 3u>; - -#define FLEX_VECTOR_T test_flex_vector_t -#define VECTOR_T test_vector_t -#include "generic.ipp" diff --git a/third_party/immer/test/flex_vector/default.cpp b/third_party/immer/test/flex_vector/default.cpp deleted file mode 100644 index 7258cc07728d..000000000000 --- a/third_party/immer/test/flex_vector/default.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/vector.hpp> - -#define FLEX_VECTOR_T ::immer::flex_vector -#define VECTOR_T ::immer::vector -#include "generic.ipp" diff --git a/third_party/immer/test/flex_vector/fuzzed-0.cpp b/third_party/immer/test/flex_vector/fuzzed-0.cpp deleted file mode 100644 index 063ad133a09d..000000000000 --- a/third_party/immer/test/flex_vector/fuzzed-0.cpp +++ /dev/null @@ -1,380 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "extra/fuzzer/fuzzer_input.hpp" -#include <array> -#include <catch.hpp> -#include <immer/flex_vector.hpp> -#include <iostream> - -#define IMMER_FUZZED_TRACE_ENABLE 0 - -#if IMMER_FUZZED_TRACE_ENABLE -#define IMMER_FUZZED_TRACE(...) std::cout << __VA_ARGS__ << std::endl; -#else -#define IMMER_FUZZED_TRACE(...) -#endif - -namespace { - -template <std::size_t VarCount = 8, unsigned Bits = 3> -int run_input(const std::uint8_t* data, std::size_t size) -{ - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, Bits, Bits>; - using size_t = std::uint8_t; - - auto vars = std::array<vector_t, VarCount>{}; - -#if IMMER_FUZZED_TRACE_ENABLE - for (auto i = 0u; i < VarCount; ++i) - std::cout << "auto var" << i << " = vector_t{};" << std::endl; -#endif - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < VarCount; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_drop, - op_concat, - }; - auto src = read<std::uint8_t>(in, is_valid_var); - auto dst = read<std::uint8_t>(in, is_valid_var); - switch (read<char>(in)) { - case op_push_back: - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src - << ".push_back(42);"); - vars[dst] = vars[src].push_back(42); - break; - case op_update: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".update(" - << +idx - << ", [] (auto x) { return x + 1; });"); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".take(" - << +idx << ");"); - vars[dst] = vars[src].take(idx); - break; - } - case op_drop: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".take(" - << +idx << ");"); - vars[dst] = vars[src].drop(idx); - break; - } - case op_concat: { - auto src2 = read<std::uint8_t>(in, is_valid_var); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << " + var" - << +src2 << ";"); - vars[dst] = vars[src] + vars[src2]; - break; - } - default: - break; - }; - return true; - }); -} - -} // anonymous namespace - -TEST_CASE("bug: concatenate too big vectors") -{ - // The problem here was that since we were using 32 bit sizes, - // concatenating big flex_vectors can overflow the sizes. Let's - // just use std::size_t like normal people. - // - // Still, the problem could re-ocurr with longer inputs. For this - // reason later fuzzing efforts do check that concatenation is - // valid for the given vector sizes. Similar assertions are put - // in the code too. - SECTION("simplified example") - { - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, 3, 3>; - auto var0 = vector_t{}; - auto var1 = vector_t{}; - auto var2 = vector_t{}; - auto var4 = vector_t{}; - var1 = var1.push_back(42); - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var2.push_back(42); - var0 = var0.push_back(42); - var2 = var0; - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var4 = var4.push_back(42); - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0 + var0; - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var2 = var0.push_back(42); - var0 = var0 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var1 = var2 + var4; - var4 = var4 + var4; - var0 = var1.push_back(42); - var0 = var0.push_back(42); - var0 = var0 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4.push_back(42); - } - -#if __GNUC__ != 9 - // Assertion `!p->relaxed()' failed - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x1, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x39, 0x6a, 0x76, - 0xb9, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x1, 0x0, 0x0, - 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x2, 0x1, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x0, 0x0, 0x2a, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x1, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x3, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0x4, 0x4, 0x4, - 0x4, 0x4, 0xf8, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x21, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0xb, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x17, 0x4, 0xe2, 0xe2, 0xe2, 0x2a, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x21, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x17, 0x4, 0xe2, 0xe2, 0xe2, 0x2a, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0x1f, 0xe2, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff, 0xe2, - 0xe2, 0xe2, 0xe2, 0xe2, 0xe2, 0x0, 0x0, 0x0, 0x15, 0x15, 0x15, - 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x15, 0x15, 0x15, 0x15, - 0x0, 0x0, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, - 0x0, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x27, 0x0, 0x21, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x1, 0x0, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, - 0x4, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0xe4, 0xe4, 0x0, 0x0, - 0x0, 0x0, 0xe4, 0x0, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, - 0x0, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } - - // buffer overflow when looking inside the sizes array for the - // index of a position - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0xff, - 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x3, 0xff, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x1e, 0x0, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x3, 0xff, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0xfa, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x9, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0xfa, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, - 0xfa, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x55, 0x0, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } - - // fail when deref some null node - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, 0x0, - 0x4, 0x4, 0x4, 0xe4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x6, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0xe5, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0xff, 0x3, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, - 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, 0x0, 0x4, 0x4, 0x4, - 0xe4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x6, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0xe5, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, - 0x4, 0x4, 0x4, 0x4, 0xe1, 0x0, 0x0, 0x80, 0x0, 0x0, 0x1, 0x6, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0x0, 0x75, 0x75, 0x45, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, - 0x0, 0x75, 0x4, 0x0, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x85, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x5, 0x4, 0x28, 0x4, 0x4, 0x4, 0x0, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x24, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x0, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0xf3, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0xf3, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, - 0x4, 0x4, 0x4, 0x4, 0x4, 0x4, 0x3, 0x4, 0x4, 0x4, 0xff, - 0xff, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xad, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } -#endif -} diff --git a/third_party/immer/test/flex_vector/fuzzed-1.cpp b/third_party/immer/test/flex_vector/fuzzed-1.cpp deleted file mode 100644 index d924dc3a8310..000000000000 --- a/third_party/immer/test/flex_vector/fuzzed-1.cpp +++ /dev/null @@ -1,368 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "extra/fuzzer/fuzzer_input.hpp" -#include <array> -#include <catch.hpp> -#include <immer/flex_vector.hpp> -#include <iostream> - -#define IMMER_FUZZED_TRACE_ENABLE 0 - -#if IMMER_FUZZED_TRACE_ENABLE -#define IMMER_FUZZED_TRACE(...) std::cout << __VA_ARGS__ << std::endl; -#else -#define IMMER_FUZZED_TRACE(...) -#endif - -namespace { - -template <std::size_t VarCount = 2, unsigned Bits = 2> -int run_input(const std::uint8_t* data, std::size_t size) -{ - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, Bits, Bits>; - using size_t = std::uint8_t; - - auto vars = std::array<vector_t, VarCount>{}; - -#if IMMER_FUZZED_TRACE_ENABLE - std::cout << "/// new test run" << std::endl; - for (auto i = 0u; i < VarCount; ++i) - std::cout << "auto var" << i << " = vector_t{};" << std::endl; -#endif - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < VarCount; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - auto can_concat = [](auto&& v1, auto&& v2) { - using size_type = decltype(v1.size()); - return v2.size() < (std::numeric_limits<size_type>::max() - v1.size()); - }; - auto can_insert = [](auto&& v1) { - using size_type = decltype(v1.size()); - return v1.size() < std::numeric_limits<size_type>::max(); - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_drop, - op_concat, - op_push_back_move, - op_update_move, - }; - auto src = read<std::uint8_t>(in, is_valid_var); - auto dst = read<std::uint8_t>(in, is_valid_var); - switch (read<char>(in)) { - case op_push_back: - if (can_insert(vars[src])) { - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src - << ".push_back(42);"); - vars[dst] = vars[src].push_back(42); - } - break; - case op_update: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".update(" - << +idx - << ", [] (auto x) { return x + 1; });"); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".take(" - << +idx << ");"); - vars[dst] = vars[src].take(idx); - break; - } - case op_drop: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".take(" - << +idx << ");"); - vars[dst] = vars[src].drop(idx); - break; - } - case op_concat: { - auto src2 = read<std::uint8_t>(in, is_valid_var); - if (can_concat(vars[src], vars[src2])) { - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << " + var" - << +src2 << ";"); - vars[dst] = vars[src] + vars[src2]; - } - break; - } - case op_push_back_move: { - if (can_insert(vars[src])) { - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").push_back(21);"); - vars[dst] = std::move(vars[src]).push_back(21); - } - break; - } - case op_update_move: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").update(" << +idx - << ", [] (auto x) { return x + 1; });"); - vars[dst] = - std::move(vars[src]).update(idx, [](auto x) { return x + 1; }); - break; - } - default: - break; - }; - return true; - }); -} - -} // anonymous namespace - -TEST_CASE("bug: memory leak because of move update") -{ - // There was a problem caused with shared "sizes buffer" in - // relaxed nodes. In particular, the ensure_mutable_relaxed(...) - // function was not decremeting the old sizes buffer. That is why - // the last transient push_back (which uses mutable operations) - // causes some of the relaxed buffers that are created during the - // previous concatenations, and that start to be shared from the - // update() onwards, to later be leaked. - SECTION("simplified") - { - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, 2, 2>; - auto var0 = vector_t{}; - auto var1 = vector_t{}; - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0 + var0; - var1 = var0.push_back(42); - var0 = var0 + var1; - var1 = var0.push_back(42); - var0 = var0 + var0; - var0 = var1 + var0; - var0 = var1.update(5, [](auto x) { return x + 1; }); - var0 = std::move(var0).push_back(21); - } - -#if __GNUC__ != 9 - SECTION("") - { - constexpr std::uint8_t input[] = { - 0xff, 0x0, 0xff, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, - 0x40, 0x0, 0x0, 0x4, 0x0, 0x6d, 0x6d, 0x0, 0x1, 0x0, 0x4, - 0x6d, 0x6d, 0x6d, 0x0, 0x0, 0x4, 0x1, 0x6d, 0x6d, 0x0, 0x1, - 0x0, 0x0, 0x0, 0x4, 0x28, 0x0, 0xfc, 0x1, 0x0, 0x4, 0x0, - 0x0, 0x0, 0xfc, 0x1, 0x0, 0x1, 0x5, 0x0, 0x0, 0x1, 0x5, - 0x0, 0x0, 0x5, 0x0, 0x0, 0xff, 0xff, 0xff, 0x27, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } -#endif -} - -TEST_CASE("non-bug: crash") -{ - // This is an interesting finding that is left here for - // documentation. This test actually should not run... the - // problem is that when we build too large vectors via - // concatenation, we can sometimes "overflow the shift". This is - // a degenerate case that we won't fix, but this helped adding - // appropriate assertions to the code. - // - // To prevent this in further fuzzing, the can_concat check has - // been made stricter. - return; - - SECTION("simplified") - { - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, 2, 2>; - auto var4 = vector_t{}; - var4 = var4.push_back(42); - var4 = var4.push_back(42); - var4 = var4.push_back(42); - var4 = var4.push_back(42); - var4 = var4.push_back(42); - auto var0 = var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var0 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4 + var4; - var4 = var4.update(4, [](auto x) { return x + 1; }); - } -#if __GNUC__ != 9 - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x00, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x2a, 0x00, - 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0xfc, 0xf9, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0xd5, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x00, 0x01, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, - 0x01, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0x13, 0x13, 0x13, 0x13, 0x13, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x29, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x10, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, 0x04, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x01, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x01, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x04, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x04, 0x04, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x00, - }; - CHECK(run_input<8>(input, sizeof(input)) == 0); - } -#endif -} diff --git a/third_party/immer/test/flex_vector/fuzzed-2.cpp b/third_party/immer/test/flex_vector/fuzzed-2.cpp deleted file mode 100644 index ba17c1a620ec..000000000000 --- a/third_party/immer/test/flex_vector/fuzzed-2.cpp +++ /dev/null @@ -1,188 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "extra/fuzzer/fuzzer_input.hpp" -#include <array> -#include <catch.hpp> -#include <immer/flex_vector.hpp> -#include <iostream> - -#define IMMER_FUZZED_TRACE_ENABLE 0 - -#if IMMER_FUZZED_TRACE_ENABLE -#define IMMER_FUZZED_TRACE(...) std::cout << __VA_ARGS__ << std::endl; -#else -#define IMMER_FUZZED_TRACE(...) -#endif - -namespace { - -template <std::size_t VarCount = 2, unsigned Bits = 2> -int run_input(const std::uint8_t* data, std::size_t size) -{ - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, Bits, Bits>; - using size_t = std::uint8_t; - - auto vars = std::array<vector_t, VarCount>{}; - -#if IMMER_FUZZED_TRACE_ENABLE - std::cout << "/// new test run" << std::endl; - for (auto i = 0u; i < VarCount; ++i) - std::cout << "auto var" << i << " = vector_t{};" << std::endl; -#endif - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < VarCount; }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - auto can_concat = [](auto&& v1, auto&& v2) { - using size_type = decltype(v1.size()); - return v2.size() < (std::numeric_limits<size_type>::max() - v1.size()); - }; - auto can_insert = [](auto&& v1) { - using size_type = decltype(v1.size()); - return v1.size() < std::numeric_limits<size_type>::max(); - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_drop, - op_concat, - op_push_back_move, - op_update_move, - op_take_move, - op_drop_move, - }; - auto src = read<std::uint8_t>(in, is_valid_var); - auto dst = read<std::uint8_t>(in, is_valid_var); - switch (read<char>(in)) { - case op_push_back: - if (can_insert(vars[src])) { - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src - << ".push_back(42);"); - vars[dst] = vars[src].push_back(42); - } - break; - case op_update: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".update(" - << +idx - << ", [] (auto x) { return x + 1; });"); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".take(" - << +idx << ");"); - vars[dst] = vars[src].take(idx); - break; - } - case op_drop: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".take(" - << +idx << ");"); - vars[dst] = vars[src].drop(idx); - break; - } - case op_concat: { - auto src2 = read<std::uint8_t>(in, is_valid_var); - if (can_concat(vars[src], vars[src2])) { - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << " + var" - << +src2 << ";"); - vars[dst] = vars[src] + vars[src2]; - } - break; - } - case op_push_back_move: { - if (can_insert(vars[src])) { - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").push_back(21);"); - vars[dst] = std::move(vars[src]).push_back(21); - } - break; - } - case op_update_move: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").update(" << +idx - << ", [] (auto x) { return x + 1; });"); - vars[dst] = - std::move(vars[src]).update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_move: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").take(" << +idx << ");"); - vars[dst] = std::move(vars[src]).take(idx); - break; - } - case op_drop_move: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").drop(" << +idx << ");"); - vars[dst] = std::move(vars[src]).drop(idx); - break; - } - default: - break; - }; - return true; - }); -} - -} // anonymous namespace - -TEST_CASE("bug: use after free on move-take") -{ - SECTION("") - { - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, 2, 2>; - auto var0 = vector_t{}; - auto var1 = vector_t{}; - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0 + var0; - var0 = var0 + var0; - var0 = var0 + var0; - var0 = var0 + var0; - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var1 = var0.push_back(42); - var0 = std::move(var0).take(68); - } - -#if __GNUC__ != 9 - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, - 0x0, 0x40, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, - 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, - 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, 0x0, 0x0, 0x0, 0x4, - 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0, 0x7, 0x41, 0xb5, 0x0, 0x0, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } -#endif -} diff --git a/third_party/immer/test/flex_vector/fuzzed-3.cpp b/third_party/immer/test/flex_vector/fuzzed-3.cpp deleted file mode 100644 index 5ef1eaffb755..000000000000 --- a/third_party/immer/test/flex_vector/fuzzed-3.cpp +++ /dev/null @@ -1,222 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "extra/fuzzer/fuzzer_input.hpp" -#include <array> -#include <catch.hpp> -#include <immer/flex_vector.hpp> -#include <iostream> - -#define IMMER_FUZZED_TRACE_ENABLE 0 - -#if IMMER_FUZZED_TRACE_ENABLE -#define IMMER_FUZZED_TRACE(...) std::cout << __VA_ARGS__ << std::endl; -#else -#define IMMER_FUZZED_TRACE(...) -#endif - -namespace { - -template <std::size_t VarCount = 2, unsigned Bits = 2> -int run_input(const std::uint8_t* data, std::size_t size) -{ - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, Bits, Bits>; - using size_t = std::uint8_t; - - auto vars = std::array<vector_t, VarCount>{}; - -#if IMMER_FUZZED_TRACE_ENABLE - std::cout << "/// new test run" << std::endl; - for (auto i = 0u; i < VarCount; ++i) - std::cout << "auto var" << i << " = vector_t{};" << std::endl; -#endif - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < VarCount; }; - auto is_valid_var_neq = [](auto other) { - return [=](auto idx) { - return idx >= 0 && idx < VarCount && idx != other; - }; - }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - auto can_concat = [](auto&& v1, auto&& v2) { - using size_type = decltype(v1.size()); - return v2.size() < (std::numeric_limits<size_type>::max() - v1.size()); - }; - auto can_insert = [](auto&& v1) { - using size_type = decltype(v1.size()); - return v1.size() < std::numeric_limits<size_type>::max(); - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_push_back, - op_update, - op_take, - op_drop, - op_concat, - op_push_back_move, - op_update_move, - op_take_move, - op_drop_move, - op_concat_move_l, - op_concat_move_r, - op_concat_move_lr, - }; - auto src = read<std::uint8_t>(in, is_valid_var); - auto dst = read<std::uint8_t>(in, is_valid_var); - switch (read<char>(in)) { - case op_push_back: - if (can_insert(vars[src])) { - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src - << ".push_back(42);"); - vars[dst] = vars[src].push_back(42); - } - break; - case op_update: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".update(" - << +idx - << ", [] (auto x) { return x + 1; });"); - vars[dst] = vars[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".take(" - << +idx << ");"); - vars[dst] = vars[src].take(idx); - break; - } - case op_drop: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << ".take(" - << +idx << ");"); - vars[dst] = vars[src].drop(idx); - break; - } - case op_concat: { - auto src2 = read<std::uint8_t>(in, is_valid_var); - if (can_concat(vars[src], vars[src2])) { - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src << " + var" - << +src2 << ";"); - vars[dst] = vars[src] + vars[src2]; - } - break; - } - case op_push_back_move: { - if (can_insert(vars[src])) { - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").push_back(21);"); - vars[dst] = std::move(vars[src]).push_back(21); - } - break; - } - case op_update_move: { - auto idx = read<size_t>(in, is_valid_index(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").update(" << +idx - << ", [] (auto x) { return x + 1; });"); - vars[dst] = - std::move(vars[src]).update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_move: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").take(" << +idx << ");"); - vars[dst] = std::move(vars[src]).take(idx); - break; - } - case op_drop_move: { - auto idx = read<size_t>(in, is_valid_size(vars[src])); - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ").drop(" << +idx << ");"); - vars[dst] = std::move(vars[src]).drop(idx); - break; - } - case op_concat_move_l: { - auto src2 = read<std::uint8_t>(in, is_valid_var_neq(src)); - if (can_concat(vars[src], vars[src2])) { - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ") + var" << +src2 << ";"); - vars[dst] = std::move(vars[src]) + vars[src2]; - } - break; - } - case op_concat_move_r: { - auto src2 = read<std::uint8_t>(in, is_valid_var_neq(src)); - if (can_concat(vars[src], vars[src2])) { - IMMER_FUZZED_TRACE("var" << +dst << " = var" << +src - << " + std::move(var" << +src2 - << ");"); - vars[dst] = vars[src] + std::move(vars[src2]); - } - break; - } - case op_concat_move_lr: { - auto src2 = read<std::uint8_t>(in, is_valid_var_neq(src)); - if (can_concat(vars[src], vars[src2])) { - IMMER_FUZZED_TRACE("var" << +dst << " = std::move(var" << +src - << ") + std::move(var" << +src2 - << ");"); - vars[dst] = std::move(vars[src]) + std::move(vars[src2]); - } - break; - } - default: - break; - }; - return true; - }); -} - -} // namespace - -TEST_CASE("bug: concat with moving the right side") -{ - // This was a stupid bug on the concatenation of small vectors - // when moving one of the sides. - SECTION("simplified") - { - using vector_t = - immer::flex_vector<int, immer::default_memory_policy, 2, 2>; - auto var0 = vector_t{}; - auto var1 = vector_t{}; - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var0 = var0.push_back(42); - var1 = var0.push_back(42); - var0 = var0 + var0; - var0 = var0.push_back(42); - var0 = var0 + var1; - var0 = var0 + var0; - var0 = var0 + std::move(var1); - } - -#if __GNUC__ != 9 - SECTION("vm") - { - constexpr std::uint8_t input[] = { - 0x0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0, - 0x0, 0x0, 0x0, 0x1, 0x0, 0x40, 0x28, 0x0, 0x4, 0x3f, - 0x20, 0x0, 0x0, 0x4, 0x3f, 0x8, 0x0, 0x0, 0x0, 0x0, - 0x1, 0x0, 0x0, 0x0, 0x4, 0x3f, 0x0, 0x0, 0x40, 0x0, - 0x0, 0x0, 0x0, 0x4, 0x3f, 0x1, 0x0, 0x0, 0x4, 0x3f, - 0x0, 0x0, 0xff, 0x0, 0xa, 0x1, 0x0, 0xff, 0x0, 0x0, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } -#endif -} diff --git a/third_party/immer/test/flex_vector/fuzzed-4.cpp b/third_party/immer/test/flex_vector/fuzzed-4.cpp deleted file mode 100644 index d9ecdd7fba7f..000000000000 --- a/third_party/immer/test/flex_vector/fuzzed-4.cpp +++ /dev/null @@ -1,364 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "extra/fuzzer/fuzzer_input.hpp" -#include <array> -#include <catch.hpp> -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <iostream> - -#define IMMER_FUZZED_TRACE_ENABLE 0 - -#if IMMER_FUZZED_TRACE_ENABLE -#define IMMER_FUZZED_TRACE(...) std::cout << __VA_ARGS__ << std::endl; -#else -#define IMMER_FUZZED_TRACE(...) -#endif - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -namespace { - -template <std::size_t VarCount = 4, unsigned Bits = 2> -int run_input(const std::uint8_t* data, std::size_t size) -{ - using vector_t = immer::flex_vector<int, gc_memory, Bits, Bits>; - using transient_t = typename vector_t::transient_type; - using size_t = std::uint8_t; - - auto vs = std::array<vector_t, VarCount>{}; - auto ts = std::array<transient_t, VarCount>{}; - -#if IMMER_FUZZED_TRACE_ENABLE - std::cout << "/// new test run" << std::endl; - for (auto i = 0; i < VarCount; ++i) - std::cout << "auto v" << i << " = vector_t{};" << std::endl; - for (auto i = 0; i < VarCount; ++i) - std::cout << "auto t" << i << " = transient_t{};" << std::endl; -#endif - - auto is_valid_var = [&](auto idx) { return idx >= 0 && idx < VarCount; }; - auto is_valid_var_neq = [](auto other) { - return [=](auto idx) { - return idx >= 0 && idx < VarCount && idx != other; - }; - }; - auto is_valid_index = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx < v.size(); }; - }; - auto is_valid_size = [](auto& v) { - return [&](auto idx) { return idx >= 0 && idx <= v.size(); }; - }; - auto can_concat = [](auto&& v1, auto&& v2) { - using size_type = decltype(v1.size()); - auto max = std::numeric_limits<size_type>::max() >> (Bits * 4); - return v1.size() < max && v2.size() < max; - }; - - return fuzzer_input{data, size}.run([&](auto& in) { - enum ops - { - op_transient, - op_persistent, - op_push_back, - op_update, - op_take, - op_drop, - op_concat, - op_push_back_mut, - op_update_mut, - op_take_mut, - op_drop_mut, - op_prepend_mut, - op_prepend_mut_move, - op_append_mut, - op_append_mut_move, - }; - auto dst = read<std::uint8_t>(in, is_valid_var); - switch (read<char>(in)) { - case op_transient: { - auto src = read<std::uint8_t>(in, is_valid_var); - IMMER_FUZZED_TRACE("t" << +dst << " = v" << +src - << ".transient();"); - ts[dst] = vs[src].transient(); - break; - } - case op_persistent: { - auto src = read<std::uint8_t>(in, is_valid_var); - IMMER_FUZZED_TRACE("v" << +dst << " = t" << +src - << ".persistent();"); - vs[dst] = ts[src].persistent(); - break; - } - case op_push_back: { - auto src = read<std::uint8_t>(in, is_valid_var); - IMMER_FUZZED_TRACE("v" << +dst << " = v" << +src - << ".push_back(42);"); - vs[dst] = vs[src].push_back(42); - break; - } - case op_update: { - auto src = read<std::uint8_t>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_index(vs[src])); - IMMER_FUZZED_TRACE("v" << +dst << " = v" << +src << ".update(" - << +idx - << ", [] (auto x) { return x + 1; });"); - vs[dst] = vs[src].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take: { - auto src = read<std::uint8_t>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_size(vs[src])); - IMMER_FUZZED_TRACE("v" << +dst << " = v" << +src << ".take(" << +idx - << ");"); - vs[dst] = vs[src].take(idx); - break; - } - case op_drop: { - auto src = read<std::uint8_t>(in, is_valid_var); - auto idx = read<size_t>(in, is_valid_size(vs[src])); - IMMER_FUZZED_TRACE("v" << +dst << " = v" << +src << ".take(" << +idx - << ");"); - vs[dst] = vs[src].drop(idx); - break; - } - case op_concat: { - auto src = read<std::uint8_t>(in, is_valid_var); - auto src2 = read<std::uint8_t>(in, is_valid_var); - if (can_concat(vs[src], vs[src2])) { - IMMER_FUZZED_TRACE("v" << +dst << " = v" << +src << " + v" - << +src2 << ";"); - vs[dst] = vs[src] + vs[src2]; - } - break; - } - case op_push_back_mut: { - IMMER_FUZZED_TRACE("t" << +dst << ".push_back(13);"); - ts[dst].push_back(13); - break; - } - case op_update_mut: { - auto idx = read<size_t>(in, is_valid_index(ts[dst])); - IMMER_FUZZED_TRACE("t" << +dst << ".update(" << +idx - << ", [] (auto x) { return x + 1; });"); - ts[dst].update(idx, [](auto x) { return x + 1; }); - break; - } - case op_take_mut: { - auto idx = read<size_t>(in, is_valid_size(ts[dst])); - IMMER_FUZZED_TRACE("t" << +dst << ").take(" << +idx << ");"); - ts[dst].take(idx); - break; - } - case op_prepend_mut: { - auto src = read<std::uint8_t>(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) { - IMMER_FUZZED_TRACE("t" << +dst << ".prepend(t" << +src << ");"); - ts[dst].prepend(ts[src]); - } - break; - } - case op_prepend_mut_move: { - auto src = read<std::uint8_t>(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) { - IMMER_FUZZED_TRACE("t" << +dst << ".prepend(std::move(t" << +src - << "));" - << " t" << +src << " = {};"); - ts[dst].prepend(std::move(ts[src])); - ts[src] = {}; - } - break; - } - case op_append_mut: { - auto src = read<std::uint8_t>(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) { - IMMER_FUZZED_TRACE("t" << +dst << ".append(t" << +src << ");"); - ts[dst].append(ts[src]); - } - break; - } - case op_append_mut_move: { - auto src = read<std::uint8_t>(in, is_valid_var_neq(dst)); - if (can_concat(ts[dst], ts[src])) { - IMMER_FUZZED_TRACE("t" << +dst << ".append(std::move(t" << +src - << "));" - << " t" << +src << " = {};"); - ts[dst].append(std::move(ts[src])); - ts[src] = {}; - } - break; - } - default: - break; - }; - return true; - }); -} - -} // namespace - -TEST_CASE("bug: concatenating transients") -{ - // When concatenating two transients vectors the nodes from the - // argument become aliased in the result. As such, we need to - // reset the identitiy of the argument. - SECTION("simplified") - { - using vector_t = immer::flex_vector<int, gc_memory, 2, 2>; - auto t0 = vector_t{}.transient(); - t0.push_back(42); - t0.push_back(42); - t0.push_back(42); - t0.push_back(42); - t0.push_back(42); - t0.push_back(42); - auto t1 = t0; - t1.append(t0); - t1.append(t0); - t0.append(t1); - t1.append(t0); - } - -#if __GNUC__ != 9 - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x2, 0x2, 0x2, 0x2, 0x29, 0x32, 0x0, 0x0, 0x2, 0x2, 0x2, - 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x6, 0x2, - 0x2, 0x2, 0x2, 0x2, 0x6, 0x2, 0x2, 0x2, 0x0, 0x38, 0x2, - 0x0, 0x0, 0x2, 0x2, 0xd, 0x0, 0x0, 0x3b, 0xff, 0x3a, 0x2, - 0xd, 0xd, 0x2, 0x0, 0x0, 0x10, 0xe, 0x0, 0xd, 0x0, 0x0, - 0x2, 0x2, 0xd, 0x0, 0x1, 0x5, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } -#endif -} - -TEST_CASE("bug: concatenating moved transients") -{ - // A moved from concatenated transient is totally smashed, we can - // not do anything with it but reasign... - SECTION("simplified") - { - using vector_t = immer::flex_vector<int, gc_memory, 2, 2>; - using transient_t = typename vector_t::transient_type; - auto v0 = vector_t{}; - auto t0 = transient_t{}; - auto t2 = transient_t{}; - v0 = v0.push_back(42); - t2 = v0.transient(); - v0 = v0 + v0; - v0 = v0 + v0; - v0 = v0 + v0; - v0 = v0 + v0; - t0 = v0.transient(); - t0 = v0.transient(); - t0.append(std::move(t2)); - t2 = {}; - t2.append(std::move(t0)); - } - -#if __GNUC__ != 9 - SECTION("") - { - constexpr std::uint8_t input[] = { - 0x0, 0x2, 0x0, 0x2, 0x0, 0x0, 0x0, 0x6, 0x0, 0x0, 0x0, - 0x6, 0x0, 0x0, 0x0, 0x9d, 0x0, 0x6, 0x0, 0x0, 0x0, 0x6, - 0x0, 0x0, 0x0, 0x9d, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf7, - 0xc5, 0x0, 0xa, 0xa, 0x0, 0xfa, 0xe7, 0xff, 0xe7, 0xff, 0x0, - 0xe, 0x2, 0x9, 0x0, 0x28, 0x2, 0xe, 0x0, 0x0, 0x2, 0xd, - 0x0, 0x0, 0x28, 0x0, 0xd, 0x2, 0x5, 0x0, 0x2, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } -#endif - - SECTION("simplified") - { - using vector_t = immer::flex_vector<int, gc_memory, 2, 2>; - using transient_t = typename vector_t::transient_type; - auto v0 = vector_t{}; - auto t0 = transient_t{}; - auto t2 = transient_t{}; - v0 = v0.push_back(42); - v0 = v0.push_back(42); - v0 = v0 + v0; - t0 = v0.transient(); - t2.prepend(std::move(t0)); - t0 = {}; - t0 = v0.transient(); - t0.push_back(13); - t2.append(std::move(t0)); - t0 = {}; - t0 = v0.transient(); - t0.push_back(13); - t2.prepend(std::move(t0)); - t0 = {}; - } - -#if __GNUC__ != 9 - SECTION("") - { - return; - constexpr std::uint8_t input[] = { - 0x0, 0x2, 0x0, 0x0, 0x2, 0xb7, 0x1, 0x36, 0x40, 0x0, 0x0, - 0x0, 0x0, 0xb6, 0x0, 0x2, 0x0, 0x0, 0x6, 0xe, 0x0, 0x0, - 0xfe, 0x0, 0x0, 0xff, 0x0, 0x2, 0xc, 0xff, 0xfc, 0x29, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x2, 0xe, 0xff, 0xfc, 0x29, 0x0, - 0x0, 0x0, 0x0, 0x0, 0x7, 0x3, 0x0, 0x0, 0x2, 0xc, 0x2, - 0xc, 0x0, 0xd, 0x0, 0x0, 0x0, 0x0, 0x25, 0x6, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } -#endif -} - -TEST_CASE("bug: aegsdas") -{ - SECTION("simplified") - { - using vector_t = immer::flex_vector<int, gc_memory, 2, 2>; - using transient_t = typename vector_t::transient_type; - auto v2 = vector_t{}; - auto t0 = transient_t{}; - auto t1 = transient_t{}; - v2 = v2.push_back(42); - v2 = v2.push_back(42); - v2 = v2.push_back(42); - v2 = v2.push_back(42); - v2 = v2.push_back(42); - t0 = v2.transient(); - t1.prepend(t0); - t1.prepend(t0); - t1.prepend(t0); - t0.prepend(std::move(t1)); - t1 = {}; - } - -#if __GNUC__ != 9 - SECTION("") - { - constexpr std::uint8_t input[] = { - 0xff, 0xff, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, - 0x82, 0x2, 0x2, 0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x3d, 0x0, - 0x0, 0x0, 0x2, 0x84, 0x0, 0x3b, 0x1, 0xb, 0x0, 0xa, 0x1, - 0xb, 0x0, 0x0, 0x3, 0x2, 0x0, 0x3b, 0x1, 0xb, 0x1, 0x0, - 0x0, 0xc, 0xb, 0x1, 0x8, 0xff, 0xff, 0xfc, 0xfd, 0x0, 0x3b, - 0x3, 0x2, 0x0, 0x3b, 0x1, 0x9, 0x1, 0x3b, - }; - CHECK(run_input(input, sizeof(input)) == 0); - } -#endif -} diff --git a/third_party/immer/test/flex_vector/gc.cpp b/third_party/immer/test/flex_vector/gc.cpp deleted file mode 100644 index 57b97f5ed7d7..000000000000 --- a/third_party/immer/test/flex_vector/gc.cpp +++ /dev/null @@ -1,27 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/vector.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename T> -using test_flex_vector_t = immer::flex_vector<T, gc_memory, 3u>; - -template <typename T> -using test_vector_t = immer::vector<T, gc_memory, 3u>; - -#define FLEX_VECTOR_T test_flex_vector_t -#define VECTOR_T test_vector_t -#include "generic.ipp" diff --git a/third_party/immer/test/flex_vector/generic.ipp b/third_party/immer/test/flex_vector/generic.ipp deleted file mode 100644 index 6dbd73f07cb6..000000000000 --- a/third_party/immer/test/flex_vector/generic.ipp +++ /dev/null @@ -1,599 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "test/dada.hpp" -#include "test/transient_tester.hpp" -#include "test/util.hpp" - -#include <immer/algorithm.hpp> - -#include <boost/range/adaptors.hpp> -#include <boost/range/irange.hpp> -#include <catch.hpp> - -#include <algorithm> -#include <array> -#include <numeric> -#include <vector> - -#ifndef FLEX_VECTOR_T -#error "define the vector template to use in FLEX_VECTOR_T" -#endif - -#ifndef VECTOR_T -#error "define the vector template to use in VECTOR_T" -#endif - -template <typename V = FLEX_VECTOR_T<unsigned>> -auto make_test_flex_vector(unsigned min, unsigned max) -{ - auto v = V{}; - for (auto i = min; i < max; ++i) - v = v.push_back({i}); - return v; -} - -template <typename V = FLEX_VECTOR_T<unsigned>> -auto make_test_flex_vector_front(unsigned min, unsigned max) -{ - auto v = V{}; - for (auto i = max; i > min;) - v = v.push_front({--i}); - return v; -} - -template <std::size_t N> -auto make_many_test_flex_vector() -{ - using vektor_t = FLEX_VECTOR_T<unsigned>; - auto many = std::array<vektor_t, N>{}; - std::generate_n(many.begin(), N, [v = vektor_t{}, i = 0u]() mutable { - auto r = v; - v = v.push_back(i++); - return r; - }); - return many; -} - -template <std::size_t N> -auto make_many_test_flex_vector_front() -{ - using vektor_t = FLEX_VECTOR_T<unsigned>; - auto many = std::array<vektor_t, N>{}; - std::generate_n(many.begin(), N, [i = 0u]() mutable { - return make_test_flex_vector_front(0, i++); - }); - return many; -} - -template <std::size_t N> -auto make_many_test_flex_vector_front_remainder() -{ - using vektor_t = FLEX_VECTOR_T<unsigned>; - auto many = std::array<vektor_t, N>{}; - std::generate_n(many.begin(), N, [v = vektor_t{}, i = N - 1]() mutable { - auto r = v; - v = v.push_front(--i); - return r; - }); - return many; -} - -TEST_CASE("set relaxed") -{ - auto v = make_test_flex_vector_front(0, 666u); - for (decltype(v.size()) i = 0; i < v.size(); ++i) { - v = v.set(i, i + 1); - CHECK(v[i] == i + 1); - } -} - -TEST_CASE("push_front") -{ - const auto n = 666u; - auto v = FLEX_VECTOR_T<unsigned>{}; - - for (auto i = 0u; i < n; ++i) { - v = v.push_front(i); - CHECK(v.size() == i + 1); - for (decltype(v.size()) j = 0; j < v.size(); ++j) - CHECK(v[v.size() - j - 1] == j); - } -} - -TEST_CASE("concat") -{ -#if IMMER_SLOW_TESTS - constexpr auto n = 666u; -#else - constexpr auto n = 101u; -#endif - - auto all_lhs = make_many_test_flex_vector<n>(); - auto all_rhs = make_many_test_flex_vector_front_remainder<n>(); - - SECTION("regular plus regular") - { - for (auto i : test_irange(0u, n)) { - auto c = all_lhs[i] + all_lhs[i]; - CHECK_VECTOR_EQUALS( - c, boost::join(boost::irange(0u, i), boost::irange(0u, i))); - } - } - - SECTION("regular plus relaxed") - { - for (auto i : test_irange(0u, n)) { - auto c = all_lhs[i] + all_rhs[n - i - 1]; - CHECK_VECTOR_EQUALS(c, boost::irange(0u, n - 1)); - } - } -} - -auto make_flex_vector_concat(std::size_t min, std::size_t max) -{ - using vektor_t = FLEX_VECTOR_T<unsigned>; - - if (max == min) - return vektor_t{}; - else if (max == min + 1) - return vektor_t{}.push_back(min); - else { - auto mid = min + (max - min) / 2; - return make_flex_vector_concat(min, mid) + - make_flex_vector_concat(mid, max); - } -} - -TEST_CASE("concat recursive") -{ - const auto n = 666u; - auto v = make_flex_vector_concat(0, n); - CHECK_VECTOR_EQUALS(v, boost::irange(0u, n)); -} - -TEST_CASE("insert") -{ - SECTION("normal") - { - const auto n = 666u; - auto v = make_test_flex_vector(0, n); - v = v.insert(42, 100); - CHECK_VECTOR_EQUALS(v, - boost::join(boost::irange(0u, 42u), - boost::join(boost::irange(100u, 101u), - boost::irange(42u, n)))); - } - - SECTION("move") - { - const auto n = 666u; - auto v = make_test_flex_vector(0, n); - v = std::move(v).insert(42, 100); - CHECK_VECTOR_EQUALS(v, - boost::join(boost::irange(0u, 42u), - boost::join(boost::irange(100u, 101u), - boost::irange(42u, n)))); - } - - SECTION("vec") - { - const auto n = 666u; - auto v = make_test_flex_vector(0, n); - v = std::move(v).insert(42, {100, 101, 102}); - CHECK_VECTOR_EQUALS(v, - boost::join(boost::irange(0u, 42u), - boost::join(boost::irange(100u, 103u), - boost::irange(42u, n)))); - } - - SECTION("vec move") - { - const auto n = 666u; - auto v = make_test_flex_vector(0, n); - v = std::move(v).insert(42, {100, 101, 102}); - CHECK_VECTOR_EQUALS(v, - boost::join(boost::irange(0u, 42u), - boost::join(boost::irange(100u, 103u), - boost::irange(42u, n)))); - } -} - -TEST_CASE("erase") -{ - const auto n = 666u; - auto v = make_test_flex_vector(0, n); - auto vv = v.erase(0); - CHECK_VECTOR_EQUALS(vv, boost::irange(1u, n)); - CHECK_VECTOR_EQUALS(v.erase(v.size() - 1), boost::irange(0u, n - 1)); - CHECK_VECTOR_EQUALS(v.erase(v.size() - 1), boost::irange(0u, n - 1)); - CHECK_VECTOR_EQUALS( - v.erase(42), - boost::join(boost::irange(0u, 42u), boost::irange(43u, n))); - CHECK_VECTOR_EQUALS(v.erase(v.size() - 1, v.size()), - boost::irange(0u, n - 1)); - CHECK_VECTOR_EQUALS(v.erase(0, 0), boost::irange(0u, n)); - CHECK_VECTOR_EQUALS( - v.erase(42, 50), - boost::join(boost::irange(0u, 42u), boost::irange(50u, n))); -} - -TEST_CASE("accumulate relaxed") -{ - auto expected_n = [](auto n) { return n * (n - 1) / 2; }; - auto expected_i = [&](auto i, auto n) { - return expected_n(n) - expected_n(i); - }; - - SECTION("sum") - { - const auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - - auto sum = immer::accumulate(v, 0u); - auto expected = v.size() * (v.size() - 1) / 2; - CHECK(sum == expected); - } - - SECTION("sum complex") - { - const auto n = 20u; - - auto v = FLEX_VECTOR_T<unsigned>{}; - for (auto i = 0u; i < n; ++i) - v = v.push_front(i) + v; - - auto sum = immer::accumulate(v, 0u); - auto expected = (1 << n) - n - 1; - CHECK(sum == expected); - } - - SECTION("sum range") - { - using namespace std; - const auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - { - auto sum = immer::accumulate(begin(v) + 100, begin(v) + 300, 0u); - CHECK(sum == expected_i(100, 300)); - } - { - auto sum = immer::accumulate(begin(v) + 31, begin(v) + 300, 0u); - CHECK(sum == expected_i(31, 300)); - } - { - auto sum = immer::accumulate(begin(v), begin(v) + 33, 0u); - CHECK(sum == expected_i(0, 33)); - } - { - auto sum = immer::accumulate(begin(v) + 100, begin(v) + 660, 0u); - CHECK(sum == expected_i(100, 660)); - } - { - auto sum = immer::accumulate(begin(v) + 100, begin(v) + 105, 0u); - CHECK(sum == expected_i(100, 105)); - } - { - auto sum = immer::accumulate(begin(v) + 660, begin(v) + 664, 0u); - CHECK(sum == expected_i(660, 664)); - } - } -} - -TEST_CASE("equals") -{ - const auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - - CHECK(v == v); - CHECK(v == v.set(42, 42)); - CHECK(v != v.set(42, 24)); - CHECK(v == v.set(42, 24).set(42, 42)); - CHECK(v.set(42, 24) == v.set(42, 24)); - CHECK(v != v.push_back(7)); - CHECK(v.push_back(7) == v.push_back(7)); - CHECK(v.push_back(5) != v.push_back(7)); - CHECK(v != v.set(v.size() - 2, 24)); - CHECK(v == v.set(v.size() - 2, 24).set(v.size() - 2, v[v.size() - 2])); - CHECK(v == v.insert(42, 12).erase(42)); - CHECK(v == v.insert(0, 12).erase(0)); -} - -TEST_CASE("equals bugs") -{ - { - const auto n = 666u; - auto v = make_test_flex_vector(0, n); - CHECK(v == v.insert(42, 12).erase(42)); - CHECK(v == v.insert(0, 12).erase(0)); - } - { - const auto n = 30u; - auto v = make_test_flex_vector(0, n); - CHECK(v == v.insert(10, 12).erase(10)); - CHECK(v == v.insert(0, 12).erase(0)); - } - { - const auto n = 666u; - auto v = make_test_flex_vector(0, n); - for (auto i : test_irange(0u, n)) - CHECK(v == v.insert(i, 42).erase(i)); - } - { - const auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - for (auto i : test_irange(0u, n)) - CHECK(v == v.insert(i, 42).erase(i)); - } - { - const auto n = 666u; - auto v = FLEX_VECTOR_T<unsigned>{}; - using size_t = decltype(v.size()); - for (auto i : test_irange(0u, n)) { - while (v.size() < i) - v = std::move(v).push_back(i); - auto vv = v; - for (auto j : test_irange(size_t{}, v.size())) { - auto vz = vv.insert(j, 42).erase(j); - CHECK(v == vz); - CHECK(vv == vz); - vv = vz; - } - } - } -} - -TEST_CASE("take relaxed") -{ - const auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - - for (auto i : test_irange(0u, n)) { - auto vv = v.take(i); - CHECK_VECTOR_EQUALS_RANGE(vv, v.begin(), v.begin() + i); - } -} - -TEST_CASE("drop") -{ - const auto n = 666u; - - SECTION("regular") - { - auto v = make_test_flex_vector(0, n); - - for (auto i : test_irange(0u, n)) { - auto vv = v.drop(i); - CHECK_VECTOR_EQUALS_RANGE(vv, v.begin() + i, v.end()); - } - } - - SECTION("relaxed") - { - auto v = make_test_flex_vector_front(0, n); - - for (auto i : test_irange(0u, n)) { - auto vv = v.drop(i); - CHECK_VECTOR_EQUALS_RANGE(vv, v.begin() + i, v.end()); - } - } -} - -#if IMMER_SLOW_TESTS -TEST_CASE("reconcat") -{ - constexpr auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - auto all_lhs = make_many_test_flex_vector_front<n + 1>(); - auto all_rhs = make_many_test_flex_vector_front_remainder<n + 1>(); - - for (auto i = 0u; i < n; ++i) { - auto vv = all_lhs[i] + all_rhs[n - i]; - CHECK_VECTOR_EQUALS(vv, v); - CHECK_SLOW(vv == v); - } -} - -TEST_CASE("reconcat drop") -{ - constexpr auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - auto all_lhs = make_many_test_flex_vector_front<n + 1>(); - - for (auto i = 0u; i < n; ++i) { - auto vv = all_lhs[i] + v.drop(i); - CHECK_VECTOR_EQUALS(vv, v); - CHECK_SLOW(vv == v); - } -} - -TEST_CASE("reconcat take") -{ - constexpr auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - auto all_rhs = make_many_test_flex_vector_front_remainder<n + 1>(); - - for (auto i = 0u; i < n; ++i) { - auto vv = v.take(i) + all_rhs[n - i]; - CHECK_VECTOR_EQUALS(vv, v); - CHECK_SLOW(vv == v); - } -} -#endif - -TEST_CASE("reconcat take drop") -{ - const auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - - for (auto i : test_irange(0u, n)) { - auto vv = v.take(i) + v.drop(i); - CHECK_VECTOR_EQUALS(vv, v); - CHECK_SLOW(vv == v); - } -} - -TEST_CASE("reconcat take drop feedback") -{ - const auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - auto vv = v; - for (auto i : test_irange(0u, n)) { - vv = vv.take(i) + vv.drop(i); - CHECK_VECTOR_EQUALS(vv, v); - CHECK_SLOW(vv == v); - } -} - -TEST_CASE("iterator relaxed") -{ - const auto n = 666u; - auto v = make_test_flex_vector_front(0, n); - - SECTION("works with range loop") - { - auto i = 0u; - for (const auto& x : v) - CHECK(x == i++); - CHECK(i == v.size()); - } - - SECTION("works with standard algorithms") - { - auto s = std::vector<unsigned>(n); - std::iota(s.begin(), s.end(), 0u); - std::equal(v.begin(), v.end(), s.begin(), s.end()); - } - - SECTION("can go back from end") - { - auto expected = n - 1; - CHECK(expected == *--v.end()); - } - - SECTION("works with reversed range adaptor") - { - auto r = v | boost::adaptors::reversed; - auto i = n; - for (const auto& x : r) - CHECK(x == --i); - } - - SECTION("works with strided range adaptor") - { - auto r = v | boost::adaptors::strided(5); - auto i = 0u; - for (const auto& x : r) - CHECK(x == 5 * i++); - } - - SECTION("works reversed") - { - auto i = n; - for (auto iter = v.rbegin(), last = v.rend(); iter != last; ++iter) - CHECK(*iter == --i); - } - - SECTION("advance and distance") - { - auto i1 = v.begin(); - auto i2 = i1 + 100; - CHECK(100u == *i2); - CHECK(100 == i2 - i1); - CHECK(50u == *(i2 - 50)); - CHECK(-30 == (i2 - 30) - i2); - } -} - -TEST_CASE("adopt regular vector contents") -{ - const auto n = 666u; - auto v = VECTOR_T<unsigned>{}; - for (auto i = 0u; i < n; ++i) { - v = v.push_back(i); - auto fv = FLEX_VECTOR_T<unsigned>{v}; - CHECK_VECTOR_EQUALS_AUX(v, fv, [](auto&& v) { return &v; }); - } -} - -TEST_CASE("exception safety relaxed") -{ - using dadaist_vector_t = - typename dadaist_wrapper<FLEX_VECTOR_T<unsigned>>::type; - constexpr auto n = 666u; - - SECTION("push back") - { - auto half = n / 2; - auto v = make_test_flex_vector_front<dadaist_vector_t>(0, half); - auto d = dadaism{}; - for (auto i = half; v.size() < static_cast<decltype(v.size())>(n);) { - auto s = d.next(); - try { - v = v.push_back({i}); - ++i; - } catch (dada_error) {} - CHECK_VECTOR_EQUALS(v, boost::irange(0u, i)); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } - - SECTION("update") - { - auto v = make_test_flex_vector_front<dadaist_vector_t>(0, n); - auto d = dadaism{}; - for (auto i = 0u; i < n;) { - auto s = d.next(); - try { - v = v.update(i, [](auto x) { return dada(), x + 1; }); - ++i; - } catch (dada_error) {} - CHECK_VECTOR_EQUALS( - v, boost::join(boost::irange(1u, 1u + i), boost::irange(i, n))); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } - - SECTION("take") - { - auto v = make_test_flex_vector_front<dadaist_vector_t>(0, n); - auto d = dadaism{}; - for (auto i = 0u; i < n;) { - auto s = d.next(); - auto r = dadaist_vector_t{}; - try { - r = v.take(i); - CHECK_VECTOR_EQUALS(r, boost::irange(0u, i++)); - } catch (dada_error) { - CHECK_VECTOR_EQUALS(r, boost::irange(0u, 0u)); - } - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } - - SECTION("concat") - { - auto v = make_test_flex_vector<dadaist_vector_t>(0, n); - auto d = dadaism{}; - for (auto i = 0u; i < n;) { - auto lhs = v.take(i); - auto rhs = v.drop(i); - auto s = d.next(); - try { - v = lhs + rhs; - ++i; - } catch (dada_error) {} - CHECK_VECTOR_EQUALS(v, boost::irange(0u, n)); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } -} diff --git a/third_party/immer/test/flex_vector/issue-45.cpp b/third_party/immer/test/flex_vector/issue-45.cpp deleted file mode 100644 index 76bd77b2e240..000000000000 --- a/third_party/immer/test/flex_vector/issue-45.cpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// Thanks Guiguiprim for reporting this issue -// https://github.com/arximboldi/immer/issues/46 - -#include <immer/flex_vector.hpp> -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -#include <catch.hpp> - -#if IMMER_CXX_STANDARD >= 17 - -#include <variant> - -TEST_CASE("error when erasing an element from a " - "immer::flex_vector<std::variant/optional/any>") -{ - using Vector = immer::flex_vector<std::variant<int, double>>; - // using Vector = immer::flex_vector<std::optional<int>>; - // using Vector = immer::flex_vector<std::any>; - - Vector v{1, 2, 3, 4}; - Vector v2 = v.erase(2); - - CHECK(v2.size() == 3); -} - -#endif diff --git a/third_party/immer/test/flex_vector/issue-47.cpp b/third_party/immer/test/flex_vector/issue-47.cpp deleted file mode 100644 index 7757fe4ee4e5..000000000000 --- a/third_party/immer/test/flex_vector/issue-47.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include <immer/flex_vector.hpp> - -immer::flex_vector<int> v{1}; - -int main() { return 0; } diff --git a/third_party/immer/test/flex_vector/regular-B3-BL3.cpp b/third_party/immer/test/flex_vector/regular-B3-BL3.cpp deleted file mode 100644 index fb5d13d1aa8e..000000000000 --- a/third_party/immer/test/flex_vector/regular-B3-BL3.cpp +++ /dev/null @@ -1,16 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> - -template <typename T> -using test_vector_t = - immer::flex_vector<T, immer::default_memory_policy, 3u, 3u>; - -#define VECTOR_T test_vector_t -#include "../vector/generic.ipp" diff --git a/third_party/immer/test/flex_vector/regular-default.cpp b/third_party/immer/test/flex_vector/regular-default.cpp deleted file mode 100644 index 8f28c3d8099f..000000000000 --- a/third_party/immer/test/flex_vector/regular-default.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> - -#define VECTOR_T ::immer::flex_vector -#include "../vector/generic.ipp" diff --git a/third_party/immer/test/flex_vector_transient/B3-BL0.cpp b/third_party/immer/test/flex_vector_transient/B3-BL0.cpp deleted file mode 100644 index da28028c0685..000000000000 --- a/third_party/immer/test/flex_vector_transient/B3-BL0.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -template <typename T> -using test_flex_vector_t = - immer::flex_vector<T, immer::default_memory_policy, 3u, 0u>; - -template <typename T> -using test_flex_vector_transient_t = - typename test_flex_vector_t<T>::transient_type; - -template <typename T> -using test_vector_t = immer::vector<T, immer::default_memory_policy, 3u, 0u>; - -#define FLEX_VECTOR_T test_flex_vector_t -#define FLEX_VECTOR_TRANSIENT_T test_flex_vector_transient_t -#define VECTOR_T test_vector_t - -#include "generic.ipp" diff --git a/third_party/immer/test/flex_vector_transient/default.cpp b/third_party/immer/test/flex_vector_transient/default.cpp deleted file mode 100644 index e9d843ccd226..000000000000 --- a/third_party/immer/test/flex_vector_transient/default.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -#define FLEX_VECTOR_T ::immer::flex_vector -#define FLEX_VECTOR_TRANSIENT_T ::immer::flex_vector_transient -#define VECTOR_T ::immer::vector -#include "generic.ipp" diff --git a/third_party/immer/test/flex_vector_transient/gc.cpp b/third_party/immer/test/flex_vector_transient/gc.cpp deleted file mode 100644 index 5577ee43df5f..000000000000 --- a/third_party/immer/test/flex_vector_transient/gc.cpp +++ /dev/null @@ -1,34 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename T> -using test_flex_vector_t = immer::flex_vector<T, gc_memory, 3u>; - -template <typename T> -using test_vector_t = immer::vector<T, gc_memory, 3u>; - -template <typename T> -using test_flex_vector_transient_t = - immer::flex_vector_transient<T, gc_memory, 3u>; - -#define FLEX_VECTOR_T test_flex_vector_t -#define FLEX_VECTOR_TRANSIENT_T test_flex_vector_transient_t -#define VECTOR_T test_vector_t -#include "generic.ipp" diff --git a/third_party/immer/test/flex_vector_transient/generic.ipp b/third_party/immer/test/flex_vector_transient/generic.ipp deleted file mode 100644 index 8c93cd163e69..000000000000 --- a/third_party/immer/test/flex_vector_transient/generic.ipp +++ /dev/null @@ -1,398 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "test/dada.hpp" -#include "test/transient_tester.hpp" -#include "test/util.hpp" - -#include <immer/algorithm.hpp> - -#include <boost/range/adaptors.hpp> -#include <boost/range/irange.hpp> -#include <catch.hpp> - -#include <algorithm> -#include <array> -#include <numeric> -#include <vector> - -#ifndef FLEX_VECTOR_T -#error "define the vector template to use in FLEX_VECTOR_T" -#endif - -#ifndef FLEX_VECTOR_TRANSIENT_T -#error "define the vector template to use in FLEX_VECTOR_TRANSIENT_T" -#endif - -#ifndef VECTOR_T -#error "define the vector template to use in VECTOR_T" -#endif - -template <typename V = VECTOR_T<unsigned>> -auto make_test_flex_vector(unsigned min, unsigned max) -{ - auto v = V{}; - for (auto i = min; i < max; ++i) - v = v.push_back({i}); - return v; -} - -template <typename V = FLEX_VECTOR_T<unsigned>> -auto make_test_flex_vector_front(unsigned min, unsigned max) -{ - auto v = V{}; - for (auto i = max; i > min;) - v = v.push_front({--i}); - return v; -} - -TEST_CASE("from flex_vector and to flex_vector") -{ - constexpr auto n = 100u; - - auto v = make_test_flex_vector(0, n).transient(); - CHECK_VECTOR_EQUALS(v, boost::irange(0u, n)); - - auto p = v.persistent(); - CHECK_VECTOR_EQUALS(p, boost::irange(0u, n)); -} - -TEST_CASE("adopt regular vector contents") -{ - const auto n = 666u; - auto v = VECTOR_T<unsigned>{}; - for (auto i = 0u; i < n; ++i) { - v = v.push_back(i); - auto fv = FLEX_VECTOR_TRANSIENT_T<unsigned>{v.transient()}; - CHECK_VECTOR_EQUALS_AUX(v, fv, [](auto&& v) { return &v; }); - } -} - -TEST_CASE("drop move") -{ - using vector_t = FLEX_VECTOR_T<unsigned>; - - auto v = vector_t{}; - - auto check_move = [&](vector_t&& x) -> vector_t&& { - if (vector_t::memory_policy::use_transient_rvalues) - CHECK(&x == &v); - else - CHECK(&x != &v); - return std::move(x); - }; - - v = v.push_back(0).push_back(1); - - auto addr_before = &v[0]; - v = check_move(std::move(v).drop(1)); - auto addr_after = &v[0]; - - if (vector_t::bits_leaf > 0 && - vector_t::memory_policy::use_transient_rvalues) - CHECK(addr_before == addr_after); - else - CHECK(addr_before != addr_after); - - CHECK_VECTOR_EQUALS(v, boost::irange(1u, 2u)); -} - -TEST_CASE("exception safety relaxed") -{ - using dadaist_vector_t = - typename dadaist_wrapper<FLEX_VECTOR_T<unsigned>>::type; - constexpr auto n = 667u; - - SECTION("push back") - { - auto half = n / 2; - auto t = as_transient_tester( - make_test_flex_vector_front<dadaist_vector_t>(0, half)); - auto d = dadaism{}; - for (auto li = half, i = half; i < n;) { - auto s = d.next(); - try { - if (t.transient) - t.vt.push_back({i}); - else - t.vp = t.vp.push_back({i}); - ++i; - } catch (dada_error) {} - if (t.step()) - li = i; - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i)); - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); - } else { - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, i)); - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, li)); - } - } - CHECK(d.happenings > 0); - CHECK(t.d.happenings > 0); - IMMER_TRACE_E(d.happenings); - IMMER_TRACE_E(t.d.happenings); - } - - SECTION("update") - { - using boost::irange; - using boost::join; - - auto t = as_transient_tester( - make_test_flex_vector_front<dadaist_vector_t>(0, n)); - auto d = dadaism{}; - for (auto li = 0u, i = 0u; i < n;) { - auto s = d.next(); - try { - if (t.transient) { - t.vt.update(i, [](auto x) { return dada(), x + 1; }); - } else { - t.vp = t.vp.update(i, [](auto x) { return dada(), x + 1; }); - } - ++i; - } catch (dada_error) {} - if (t.step()) - li = i; - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, - join(irange(1u, 1u + i), irange(i, n))); - CHECK_VECTOR_EQUALS(t.vp, - join(irange(1u, 1u + li), irange(li, n))); - } else { - CHECK_VECTOR_EQUALS(t.vp, - join(irange(1u, 1u + i), irange(i, n))); - CHECK_VECTOR_EQUALS(t.vt, - join(irange(1u, 1u + li), irange(li, n))); - } - } - CHECK(d.happenings > 0); - CHECK(t.d.happenings > 0); - } - - SECTION("take") - { - auto t = as_transient_tester( - make_test_flex_vector_front<dadaist_vector_t>(0, n)); - auto d = dadaism{}; - auto deltas = magic_rotator(); - auto delta = deltas.next(); - for (auto i = n, li = i;;) { - auto s = d.next(); - auto r = dadaist_vector_t{}; - try { - if (t.transient) - t.vt.take(i); - else - t.vp = t.vp.take(i); - if (t.step()) - li = i; - delta = deltas.next(); - if (i < delta) - break; - i -= delta; - } catch (dada_error) {} - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i + delta)); - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); - } else { - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, i + delta)); - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, li)); - } - } - CHECK(d.happenings > 0); - CHECK(t.d.happenings > 0); - } - - SECTION("drop") - { - auto t = - as_transient_tester(make_test_flex_vector<dadaist_vector_t>(0, n)); - auto d = dadaism{}; - auto deltas = magic_rotator(); - auto delta = deltas.next(); - for (auto i = delta, li = 0u; i < n;) { - auto s = d.next(); - auto r = dadaist_vector_t{}; - try { - if (t.transient) - t.vt.drop(delta); - else - t.vp = t.vp.drop(delta); - if (t.step()) { - li = i; - } - delta = deltas.next(); - i += delta; - } catch (dada_error) {} - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, boost::irange(i - delta, n)); - CHECK_VECTOR_EQUALS(t.vp, boost::irange(li, n)); - } else { - CHECK_VECTOR_EQUALS(t.vp, boost::irange(i - delta, n)); - CHECK_VECTOR_EQUALS(t.vt, boost::irange(li, n)); - } - } - CHECK(d.happenings > 0); - CHECK(t.d.happenings > 0); - } - - SECTION("append") - { - auto make_ = [](auto i, auto delta) { - auto d = dadaism::disable(); - return make_test_flex_vector<dadaist_vector_t>(i, i + delta); - }; - auto t = as_transient_tester(dadaist_vector_t{}); - auto d = dadaism(); - auto deltas = magic_rotator(); - auto delta = deltas.next(); - for (auto i = 0u, li = 0u; i < n;) { - try { - if (t.transient) { - auto data = make_(i, delta); - auto datat = data.transient(); - t.vt.append(datat); - } else { - auto data = make_(i, delta); - t.vp = t.vp + data; - } - i += delta; - if (t.step()) { - li = i; - } - delta = deltas.next() * 3; - } catch (dada_error) {} - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i)); - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); - } else { - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, i)); - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, li)); - } - } - CHECK(d.happenings == 0); - CHECK(t.d.happenings > 0); - } - - SECTION("append mut") - { - auto make_ = [](auto i, auto delta) { - auto d = dadaism::disable(); - return make_test_flex_vector<dadaist_vector_t>(i, i + delta); - }; - auto t = as_transient_tester(dadaist_vector_t{}); - auto d = dadaism(); - auto deltas = magic_rotator(); - auto delta = deltas.next(); - for (auto i = 0u, li = 0u; i < n;) { - try { - if (t.transient) { - auto data = make_(i, delta); - auto datat = data.transient(); - t.vt.append(std::move(datat)); - } else { - auto data = make_(i, delta); - t.vp = t.vp + data; - } - i += delta; - if (t.step()) { - li = i; - } - delta = deltas.next() * 3; - } catch (dada_error) {} - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i)); - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); - } else { - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, i)); - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, li)); - } - } - CHECK(d.happenings == 0); - CHECK(t.d.happenings > 0); - } - - SECTION("prepend") - { - auto make_ = [](auto i, auto delta) { - auto d = dadaism::disable(); - return make_test_flex_vector<dadaist_vector_t>(i, i + delta); - }; - auto t = as_transient_tester(dadaist_vector_t{}); - auto d = dadaism(); - auto deltas = magic_rotator(); - auto delta = deltas.next(); - for (auto i = n, li = n; i > 0;) { - delta = std::min(i, delta); - try { - if (t.transient) { - auto data = make_(i - delta, delta); - auto datat = data.transient(); - t.vt.prepend(datat); - } else { - auto data = make_(i - delta, delta); - t.vp = data + t.vp; - } - i -= delta; - if (t.step()) { - li = i; - } - delta = deltas.next() * 3; - } catch (dada_error) {} - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, boost::irange(i, n)); - CHECK_VECTOR_EQUALS(t.vp, boost::irange(li, n)); - } else { - CHECK_VECTOR_EQUALS(t.vp, boost::irange(i, n)); - CHECK_VECTOR_EQUALS(t.vt, boost::irange(li, n)); - } - } - CHECK(d.happenings == 0); - CHECK(t.d.happenings > 0); - } - - SECTION("prepend mut") - { - auto make_ = [](auto i, auto delta) { - auto d = dadaism::disable(); - return make_test_flex_vector<dadaist_vector_t>(i, i + delta); - }; - auto t = as_transient_tester(dadaist_vector_t{}); - auto d = dadaism(); - auto deltas = magic_rotator(); - auto delta = deltas.next(); - for (auto i = n, li = n; i > 0;) { - delta = std::min(i, delta); - try { - if (t.transient) { - auto data = make_(i - delta, delta); - auto datat = data.transient(); - t.vt.prepend(std::move(datat)); - } else { - auto data = make_(i - delta, delta); - t.vp = data + t.vp; - } - i -= delta; - if (t.step()) { - li = i; - } - delta = deltas.next() * 3; - } catch (dada_error) {} - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, boost::irange(i, n)); - CHECK_VECTOR_EQUALS(t.vp, boost::irange(li, n)); - } else { - CHECK_VECTOR_EQUALS(t.vp, boost::irange(i, n)); - CHECK_VECTOR_EQUALS(t.vt, boost::irange(li, n)); - } - } - CHECK(d.happenings == 0); - CHECK(t.d.happenings > 0); - } -} diff --git a/third_party/immer/test/flex_vector_transient/regular-default.cpp b/third_party/immer/test/flex_vector_transient/regular-default.cpp deleted file mode 100644 index d8443afb5553..000000000000 --- a/third_party/immer/test/flex_vector_transient/regular-default.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> - -#define VECTOR_T ::immer::flex_vector -#define VECTOR_TRANSIENT_T ::immer::flex_vector_transient - -#include "../vector_transient/generic.ipp" diff --git a/third_party/immer/test/flex_vector_transient/regular-gc.cpp b/third_party/immer/test/flex_vector_transient/regular-gc.cpp deleted file mode 100644 index f1e0ec2dd518..000000000000 --- a/third_party/immer/test/flex_vector_transient/regular-gc.cpp +++ /dev/null @@ -1,31 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename T> -using test_flex_vector_t = immer::flex_vector<T, gc_memory, 3u>; - -template <typename T> -using test_flex_vector_transient_t = - immer::flex_vector_transient<T, gc_memory, 3u>; - -#define VECTOR_T test_flex_vector_t -#define VECTOR_TRANSIENT_T test_flex_vector_transient_t - -#include "../vector_transient/generic.ipp" diff --git a/third_party/immer/test/map/B3.cpp b/third_party/immer/test/map/B3.cpp deleted file mode 100644 index 61458a013537..000000000000 --- a/third_party/immer/test/map/B3.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/map.hpp> - -template <typename K, - typename T, - typename Hash = std::hash<K>, - typename Eq = std::equal_to<K>> -using test_map_t = immer::map<K, T, Hash, Eq, immer::default_memory_policy, 3u>; - -#define MAP_T test_map_t -#include "generic.ipp" diff --git a/third_party/immer/test/map/B6.cpp b/third_party/immer/test/map/B6.cpp deleted file mode 100644 index 52da689c67b6..000000000000 --- a/third_party/immer/test/map/B6.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/map.hpp> - -template <typename K, - typename T, - typename Hash = std::hash<K>, - typename Eq = std::equal_to<K>> -using test_map_t = immer::map<K, T, Hash, Eq, immer::default_memory_policy, 6u>; - -#define MAP_T test_map_t -#include "generic.ipp" diff --git a/third_party/immer/test/map/default.cpp b/third_party/immer/test/map/default.cpp deleted file mode 100644 index cb453c4f81e2..000000000000 --- a/third_party/immer/test/map/default.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/map.hpp> - -#define MAP_T ::immer::map -#include "generic.ipp" diff --git a/third_party/immer/test/map/gc.cpp b/third_party/immer/test/map/gc.cpp deleted file mode 100644 index 818fb03aaa5b..000000000000 --- a/third_party/immer/test/map/gc.cpp +++ /dev/null @@ -1,25 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/heap/gc_heap.hpp> -#include <immer/map.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename K, - typename T, - typename Hash = std::hash<K>, - typename Eq = std::equal_to<K>> -using test_map_t = immer::map<K, T, Hash, Eq, gc_memory, 3u>; - -#define MAP_T test_map_t -#include "generic.ipp" diff --git a/third_party/immer/test/map/generic.ipp b/third_party/immer/test/map/generic.ipp deleted file mode 100644 index 18fc9d11f567..000000000000 --- a/third_party/immer/test/map/generic.ipp +++ /dev/null @@ -1,312 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#ifndef MAP_T -#error "define the map template to use in MAP_T" -#include <immer/map.hpp> -#define MAP_T ::immer::map -#endif - -#include <immer/algorithm.hpp> - -#include "test/dada.hpp" -#include "test/util.hpp" - -#include <catch.hpp> - -#include <random> -#include <unordered_set> - -template <typename T = unsigned> -auto make_generator() -{ - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution<T>{}; - return std::bind(dist, engine); -} - -struct conflictor -{ - unsigned v1; - unsigned v2; - - bool operator==(const conflictor& x) const - { - return v1 == x.v1 && v2 == x.v2; - } -}; - -struct hash_conflictor -{ - std::size_t operator()(const conflictor& x) const { return x.v1; } -}; - -auto make_values_with_collisions(unsigned n) -{ - auto gen = make_generator(); - auto vals = std::vector<std::pair<conflictor, unsigned>>{}; - auto vals_ = std::unordered_set<conflictor, hash_conflictor>{}; - auto i = 0u; - generate_n(back_inserter(vals), n, [&] { - auto newv = conflictor{}; - do { - newv = {unsigned(gen() % (n / 2)), gen()}; - } while (!vals_.insert(newv).second); - return std::pair<conflictor, unsigned>{newv, i++}; - }); - return vals; -} - -auto make_test_map(unsigned n) -{ - auto s = MAP_T<unsigned, unsigned>{}; - for (auto i = 0u; i < n; ++i) - s = s.insert({i, i}); - return s; -} - -auto make_test_map(const std::vector<std::pair<conflictor, unsigned>>& vals) -{ - auto s = MAP_T<conflictor, unsigned, hash_conflictor>{}; - for (auto&& v : vals) - s = s.insert(v); - return s; -} - -TEST_CASE("instantiation") -{ - SECTION("default") - { - auto v = MAP_T<int, int>{}; - CHECK(v.size() == 0u); - } -} - -TEST_CASE("basic insertion") -{ - auto v1 = MAP_T<int, int>{}; - CHECK(v1.count(42) == 0); - - auto v2 = v1.insert({42, {}}); - CHECK(v1.count(42) == 0); - CHECK(v2.count(42) == 1); - - auto v3 = v2.insert({42, {}}); - CHECK(v1.count(42) == 0); - CHECK(v2.count(42) == 1); - CHECK(v3.count(42) == 1); -} - -TEST_CASE("accessor") -{ - const auto n = 666u; - auto v = make_test_map(n); - CHECK(v[0] == 0); - CHECK(v[42] == 42); - CHECK(v[665] == 665); - CHECK(v[666] == 0); - CHECK(v[1234] == 0); -} - -TEST_CASE("at") -{ - const auto n = 666u; - auto v = make_test_map(n); - CHECK(v.at(0) == 0); - CHECK(v.at(42) == 42); - CHECK(v.at(665) == 665); - CHECK_THROWS_AS(v.at(666), std::out_of_range&); - CHECK_THROWS_AS(v.at(1234), std::out_of_range&); -} - -TEST_CASE("find") -{ - const auto n = 666u; - auto v = make_test_map(n); - CHECK(*v.find(0) == 0); - CHECK(*v.find(42) == 42); - CHECK(*v.find(665) == 665); - CHECK(v.find(666) == nullptr); - CHECK(v.find(1234) == nullptr); -} - -TEST_CASE("equals and setting") -{ - const auto n = 666u; - auto v = make_test_map(n); - - CHECK(v == v); - CHECK(v != v.insert({1234, 42})); - CHECK(v != v.erase(32)); - CHECK(v == v.insert({1234, 42}).erase(1234)); - CHECK(v == v.erase(32).insert({32, 32})); - - CHECK(v.set(1234, 42) == v.insert({1234, 42})); - CHECK(v.update(1234, [](auto&& x) { return x + 1; }) == v.set(1234, 1)); - CHECK(v.update(42, [](auto&& x) { return x + 1; }) == v.set(42, 43)); -} - -TEST_CASE("iterator") -{ - const auto N = 666u; - auto v = make_test_map(N); - - SECTION("empty set") - { - auto s = MAP_T<unsigned, unsigned>{}; - CHECK(s.begin() == s.end()); - } - - SECTION("works with range loop") - { - auto seen = std::unordered_set<unsigned>{}; - for (const auto& x : v) - CHECK(seen.insert(x.first).second); - CHECK(seen.size() == v.size()); - } - - SECTION("iterator and collisions") - { - auto vals = make_values_with_collisions(N); - auto s = make_test_map(vals); - auto seen = std::unordered_set<conflictor, hash_conflictor>{}; - for (const auto& x : s) - CHECK(seen.insert(x.first).second); - CHECK(seen.size() == s.size()); - } -} - -TEST_CASE("accumulate") -{ - const auto n = 666u; - auto v = make_test_map(n); - - auto expected_n = [](auto n) { return n * (n - 1) / 2; }; - - SECTION("sum collection") - { - auto acc = [](unsigned acc, const std::pair<unsigned, unsigned>& x) { - return acc + x.first + x.second; - }; - auto sum = immer::accumulate(v, 0u, acc); - CHECK(sum == 2 * expected_n(v.size())); - } - - SECTION("sum collisions") - { - auto vals = make_values_with_collisions(n); - auto s = make_test_map(vals); - auto acc = [](unsigned r, std::pair<conflictor, unsigned> x) { - return r + x.first.v1 + x.first.v2 + x.second; - }; - auto sum1 = std::accumulate(vals.begin(), vals.end(), 0u, acc); - auto sum2 = immer::accumulate(s, 0u, acc); - CHECK(sum1 == sum2); - } -} - -TEST_CASE("update a lot") -{ - auto v = make_test_map(666u); - - for (decltype(v.size()) i = 0; i < v.size(); ++i) { - v = v.update(i, [](auto&& x) { return x + 1; }); - CHECK(v[i] == i + 1); - } -} - -TEST_CASE("exception safety") -{ - constexpr auto n = 2666u; - - using dadaist_map_t = - typename dadaist_wrapper<MAP_T<unsigned, unsigned>>::type; - using dadaist_conflictor_map_t = typename dadaist_wrapper< - MAP_T<conflictor, unsigned, hash_conflictor>>::type; - - SECTION("update collisions") - { - auto v = dadaist_map_t{}; - auto d = dadaism{}; - for (auto i = 0u; i < n; ++i) - v = v.set(i, i); - for (auto i = 0u; i < v.size();) { - try { - auto s = d.next(); - v = v.update(i, [](auto x) { return x + 1; }); - ++i; - } catch (dada_error) {} - for (auto i : test_irange(0u, i)) - CHECK(v.at(i) == i + 1); - for (auto i : test_irange(i, n)) - CHECK(v.at(i) == i); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } - - SECTION("update collisisions") - { - auto vals = make_values_with_collisions(n); - auto v = dadaist_conflictor_map_t{}; - auto d = dadaism{}; - for (auto i = 0u; i < n; ++i) - v = v.insert(vals[i]); - for (auto i = 0u; i < v.size();) { - try { - auto s = d.next(); - v = v.update(vals[i].first, [](auto x) { return x + 1; }); - ++i; - } catch (dada_error) {} - for (auto i : test_irange(0u, i)) - CHECK(v.at(vals[i].first) == vals[i].second + 1); - for (auto i : test_irange(i, n)) - CHECK(v.at(vals[i].first) == vals[i].second); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } -} - -namespace { - -class KElem -{ -public: - KElem(int* elem) { this->elem = elem; } - - bool operator==(const KElem& other) const - { - return this->elem == other.elem; - } - - bool operator!=(const KElem& other) const { return !(*this == other); } - - int* elem; -}; - -struct HashBlock -{ - size_t operator()(const KElem& block) const noexcept - { - return (uintptr_t) block.elem & 0xffffffff00000000; - } -}; - -using map = immer::map<KElem, KElem, HashBlock, std::equal_to<KElem>>; - -TEST_CASE("issue 134") -{ - int a[100]; - map m; - for (int i = 0; i < 100; i++) { - m = m.set(KElem(a + i), KElem(a + i)); - } -} - -} // namespace diff --git a/third_party/immer/test/map/issue-56.cpp b/third_party/immer/test/map/issue-56.cpp deleted file mode 100644 index 447c623ddad9..000000000000 --- a/third_party/immer/test/map/issue-56.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// Thanks @dgel for reporting this issue -// https://github.com/arximboldi/immer/issues/56 - -#include <immer/flex_vector.hpp> -#include <immer/map.hpp> -#include <immer/vector.hpp> - -#include <catch.hpp> - -TEST_CASE("const map") -{ - const auto x = immer::map<std::string, int>{}.set("A", 1); - auto it = x.begin(); - CHECK(it->first == "A"); - CHECK(it->second == 1); -} - -TEST_CASE("const vector") -{ - const auto x = - immer::vector<std::pair<std::string, int>>{}.push_back({"A", 1}); - auto it = x.begin(); - CHECK(it->first == "A"); - CHECK(it->second == 1); -} - -TEST_CASE("const flex vector") -{ - const auto x = - immer::flex_vector<std::pair<std::string, int>>{}.push_back({"A", 1}); - auto it = x.begin(); - CHECK(it->first == "A"); - CHECK(it->second == 1); -} diff --git a/third_party/immer/test/memory/heaps.cpp b/third_party/immer/test/memory/heaps.cpp deleted file mode 100644 index 94af2be20868..000000000000 --- a/third_party/immer/test/memory/heaps.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/heap/cpp_heap.hpp> -#include <immer/heap/free_list_heap.hpp> -#include <immer/heap/gc_heap.hpp> -#include <immer/heap/malloc_heap.hpp> -#include <immer/heap/thread_local_free_list_heap.hpp> - -#include <catch.hpp> -#include <numeric> - -void do_stuff_to(void* buf, std::size_t size) -{ - auto ptr = static_cast<unsigned char*>(buf); - CHECK(buf != 0); - std::iota(ptr, ptr + size, 42); -} - -TEST_CASE("malloc") -{ - using heap = immer::malloc_heap; - - SECTION("basic") - { - auto p = heap::allocate(42u); - do_stuff_to(p, 42u); - heap::deallocate(42, p); - } -} - -TEST_CASE("gc") -{ - using heap = immer::gc_heap; - - SECTION("basic") - { - auto p = heap::allocate(42u); - do_stuff_to(p, 42u); - heap::deallocate(42, p); - } -} - -TEST_CASE("cpp") -{ - using heap = immer::cpp_heap; - - SECTION("basic") - { - auto p = heap::allocate(42u); - do_stuff_to(p, 42u); - heap::deallocate(42, p); - } -} - -template <typename Heap> -void test_free_list_heap() -{ - using heap = Heap; - - SECTION("basic") - { - auto p = heap::allocate(42u); - do_stuff_to(p, 42u); - heap::deallocate(42, p); - } - - SECTION("reuse") - { - auto p = heap::allocate(42u); - do_stuff_to(p, 42u); - heap::deallocate(42, p); - - auto u = heap::allocate(12u); - do_stuff_to(u, 12u); - heap::deallocate(12, u); - CHECK(u == p); - } -} - -TEST_CASE("free list") -{ - test_free_list_heap<immer::free_list_heap<42u, 2, immer::malloc_heap>>(); -} - -TEST_CASE("thread local free list") -{ - test_free_list_heap< - immer::thread_local_free_list_heap<42u, 2, immer::malloc_heap>>(); -} - -TEST_CASE("unsafe free_list") -{ - test_free_list_heap< - immer::unsafe_free_list_heap<42u, 2, immer::malloc_heap>>(); -} diff --git a/third_party/immer/test/memory/refcounts.cpp b/third_party/immer/test/memory/refcounts.cpp deleted file mode 100644 index f9278ca7794e..000000000000 --- a/third_party/immer/test/memory/refcounts.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/refcount/refcount_policy.hpp> -#include <immer/refcount/unsafe_refcount_policy.hpp> - -#include <catch.hpp> - -TEST_CASE("no refcount has no data") -{ - static_assert(std::is_empty<immer::no_refcount_policy>{}, ""); -} - -template <typename RefcountPolicy> -void test_refcount() -{ - using refcount = RefcountPolicy; - - SECTION("starts at one") - { - refcount elem{}; - CHECK(elem.dec()); - } - - SECTION("disowned starts at zero") - { - refcount elem{immer::disowned{}}; - elem.inc(); - CHECK(elem.dec()); - } - - SECTION("inc dec") - { - refcount elem{}; - elem.inc(); - CHECK(!elem.dec()); - CHECK(elem.dec()); - } - - SECTION("inc dec unsafe") - { - refcount elem{}; - elem.inc(); - CHECK(!elem.dec()); - elem.inc(); - elem.dec_unsafe(); - CHECK(elem.dec()); - } -} - -TEST_CASE("basic refcount") { test_refcount<immer::refcount_policy>(); } - -TEST_CASE("thread unsafe refcount") -{ - test_refcount<immer::unsafe_refcount_policy>(); -} diff --git a/third_party/immer/test/set/B3.cpp b/third_party/immer/test/set/B3.cpp deleted file mode 100644 index 192b0f8e9afd..000000000000 --- a/third_party/immer/test/set/B3.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/set.hpp> - -template <typename T, - typename Hash = std::hash<T>, - typename Eq = std::equal_to<T>> -using test_set_t = immer::set<T, Hash, Eq, immer::default_memory_policy, 3u>; - -#define SET_T test_set_t -#include "generic.ipp" diff --git a/third_party/immer/test/set/B6.cpp b/third_party/immer/test/set/B6.cpp deleted file mode 100644 index 7fe3e5b7728c..000000000000 --- a/third_party/immer/test/set/B6.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/set.hpp> - -template <typename T, - typename Hash = std::hash<T>, - typename Eq = std::equal_to<T>> -using test_set_t = immer::set<T, Hash, Eq, immer::default_memory_policy, 6u>; - -#define SET_T test_set_t -#include "generic.ipp" diff --git a/third_party/immer/test/set/default.cpp b/third_party/immer/test/set/default.cpp deleted file mode 100644 index 8e6611a4ea7e..000000000000 --- a/third_party/immer/test/set/default.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/set.hpp> - -#define SET_T ::immer::set -#include "generic.ipp" diff --git a/third_party/immer/test/set/gc.cpp b/third_party/immer/test/set/gc.cpp deleted file mode 100644 index 098c8c97d087..000000000000 --- a/third_party/immer/test/set/gc.cpp +++ /dev/null @@ -1,24 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/set.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename T, - typename Hash = std::hash<T>, - typename Eq = std::equal_to<T>> -using test_set_t = immer::set<T, Hash, Eq, gc_memory, 3u>; - -#define SET_T test_set_t -#include "generic.ipp" diff --git a/third_party/immer/test/set/generic.ipp b/third_party/immer/test/set/generic.ipp deleted file mode 100644 index 8d75373787e2..000000000000 --- a/third_party/immer/test/set/generic.ipp +++ /dev/null @@ -1,459 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#ifndef SET_T -#error "define the set template to use in SET_T" -#include <immer/set.hpp> -#define SET_T ::immer::set -#endif - -#include "test/dada.hpp" -#include "test/util.hpp" - -#include <immer/algorithm.hpp> - -#include <catch.hpp> - -#include <random> -#include <unordered_set> - -template <typename T = unsigned> -auto make_generator() -{ - auto engine = std::default_random_engine{42}; - auto dist = std::uniform_int_distribution<T>{}; - return std::bind(dist, engine); -} - -struct conflictor -{ - unsigned v1; - unsigned v2; - - bool operator==(const conflictor& x) const - { - return v1 == x.v1 && v2 == x.v2; - } -}; - -struct hash_conflictor -{ - std::size_t operator()(const conflictor& x) const { return x.v1; } -}; - -auto make_values_with_collisions(unsigned n) -{ - auto gen = make_generator(); - auto vals = std::vector<conflictor>{}; - auto vals_ = std::unordered_set<conflictor, hash_conflictor>{}; - generate_n(back_inserter(vals), n, [&] { - auto newv = conflictor{}; - do { - newv = {unsigned(gen() % (n / 2)), gen()}; - } while (!vals_.insert(newv).second); - return newv; - }); - return vals; -} - -auto make_test_set(unsigned n) -{ - auto s = SET_T<unsigned>{}; - for (auto i = 0u; i < n; ++i) - s = s.insert(i); - return s; -} - -auto make_test_set(const std::vector<conflictor>& vals) -{ - auto s = SET_T<conflictor, hash_conflictor>{}; - for (auto&& v : vals) - s = s.insert(v); - return s; -} - -template <std::size_t BufLen> -struct unaligned_str -{ - std::array<char, BufLen> m_data{}; - - unaligned_str() = default; - unaligned_str(const std::string& in) - { - for (std::size_t i = 0; i < std::min(m_data.size() - 1, in.size()); i++) - m_data[i] = in[i]; - } - unaligned_str(const char* in) - : unaligned_str{std::string{in}} - {} - - std::string str() const { return m_data.data(); } - - bool operator==(unaligned_str other) const - { - return m_data == other.m_data; - } - - bool operator!=(unaligned_str other) const - { - return m_data != other.m_data; - } -}; - -namespace std { -template <size_t BufLen> -struct hash<unaligned_str<BufLen>> -{ - size_t operator()(const unaligned_str<BufLen>& str) const - { - return std::hash<std::string>{}(str.str()); - } -}; -} // namespace std - -template <size_t BufLen> -void check_with_len() -{ - auto v = SET_T<unaligned_str<BufLen>>{}; - - for (int i = 0; i < 1; i++) - v = v.insert(std::to_string(i)); - - CHECK(v.count("0") == 1); -} - -TEST_CASE("insert type with no alignment requirement") -{ - check_with_len<1>(); - check_with_len<9>(); - check_with_len<15>(); - check_with_len<17>(); -} - -TEST_CASE("instantiation") -{ - SECTION("default") - { - auto v = SET_T<unsigned>{}; - CHECK(v.size() == 0u); - } -} - -TEST_CASE("basic insertion") -{ - auto v1 = SET_T<unsigned>{}; - CHECK(v1.count(42) == 0); - - auto v2 = v1.insert(42); - CHECK(v1.count(42) == 0); - CHECK(v2.count(42) == 1); - - auto v3 = v2.insert(42); - CHECK(v1.count(42) == 0); - CHECK(v2.count(42) == 1); - CHECK(v3.count(42) == 1); -} - -TEST_CASE("insert a lot") -{ - constexpr auto N = 666u; - - auto gen = make_generator(); - auto vals = std::vector<unsigned>{}; - generate_n(back_inserter(vals), N, gen); - auto s = SET_T<unsigned>{}; - - for (auto i = 0u; i < N; ++i) { - s = s.insert(vals[i]); - CHECK(s.size() == i + 1); - for (auto j : test_irange(0u, i + 1)) - CHECK(s.count(vals[j]) == 1); - for (auto j : test_irange(i + 1u, N)) - CHECK(s.count(vals[j]) == 0); - } -} - -TEST_CASE("insert conflicts") -{ - constexpr auto N = 666u; - auto vals = make_values_with_collisions(N); - auto s = SET_T<conflictor, hash_conflictor>{}; - for (auto i = 0u; i < N; ++i) { - s = s.insert(vals[i]); - CHECK(s.size() == i + 1); - for (auto j : test_irange(0u, i + 1)) - CHECK(s.count(vals[j]) == 1); - for (auto j : test_irange(i + 1u, N)) - CHECK(s.count(vals[j]) == 0); - } -} - -TEST_CASE("erase a lot") -{ - constexpr auto N = 666u; - auto gen = make_generator(); - auto vals = std::vector<unsigned>{}; - generate_n(back_inserter(vals), N, gen); - - auto s = SET_T<unsigned>{}; - for (auto i = 0u; i < N; ++i) - s = s.insert(vals[i]); - - for (auto i = 0u; i < N; ++i) { - s = s.erase(vals[i]); - CHECK(s.size() == N - i - 1); - for (auto j : test_irange(0u, i + 1)) - CHECK(s.count(vals[j]) == 0); - for (auto j : test_irange(i + 1u, N)) - CHECK(s.count(vals[j]) == 1); - } -} - -TEST_CASE("erase conflicts") -{ - constexpr auto N = 666u; - auto vals = make_values_with_collisions(N); - auto s = SET_T<conflictor, hash_conflictor>{}; - for (auto i = 0u; i < N; ++i) - s = s.insert(vals[i]); - - for (auto i = 0u; i < N; ++i) { - s = s.erase(vals[i]); - CHECK(s.size() == N - i - 1); - for (auto j : test_irange(0u, i + 1)) - CHECK(s.count(vals[j]) == 0); - for (auto j : test_irange(i + 1u, N)) - CHECK(s.count(vals[j]) == 1); - } -} - -TEST_CASE("accumulate") -{ - const auto n = 666u; - auto v = make_test_set(n); - - auto expected_n = [](auto n) { return n * (n - 1) / 2; }; - - SECTION("sum collection") - { - auto sum = immer::accumulate(v, 0u); - CHECK(sum == expected_n(v.size())); - } - - SECTION("sum collisions") - { - auto vals = make_values_with_collisions(n); - auto s = make_test_set(vals); - auto acc = [](unsigned r, conflictor x) { return r + x.v1 + x.v2; }; - auto sum1 = std::accumulate(vals.begin(), vals.end(), 0, acc); - auto sum2 = immer::accumulate(s, 0u, acc); - CHECK(sum1 == sum2); - } -} - -TEST_CASE("find") -{ - const auto n = 666u; - auto v = make_test_set(n); - CHECK(*v.find(0) == 0); - CHECK(*v.find(42) == 42); - CHECK(*v.find(665) == 665); - CHECK(v.find(666) == nullptr); - CHECK(v.find(1234) == nullptr); -} - -TEST_CASE("iterator") -{ - const auto N = 666u; - auto v = make_test_set(N); - - SECTION("empty set") - { - auto s = SET_T<unsigned>{}; - CHECK(s.begin() == s.end()); - } - - SECTION("works with range loop") - { - auto seen = std::unordered_set<unsigned>{}; - for (const auto& x : v) - CHECK(seen.insert(x).second); - CHECK(seen.size() == v.size()); - } - - SECTION("works with standard algorithms") - { - auto s = std::vector<unsigned>(N); - std::iota(s.begin(), s.end(), 0u); - std::equal(v.begin(), v.end(), s.begin(), s.end()); - } - - SECTION("iterator and collisions") - { - auto vals = make_values_with_collisions(N); - auto s = make_test_set(vals); - auto seen = std::unordered_set<conflictor, hash_conflictor>{}; - for (const auto& x : s) - CHECK(seen.insert(x).second); - CHECK(seen.size() == s.size()); - } -} - -struct non_default -{ - unsigned value; - non_default() = delete; - operator unsigned() const { return value; } - -#if IMMER_DEBUG_PRINT - friend std::ostream& operator<<(std::ostream& os, non_default x) - { - os << "ND{" << x.value << "}"; - return os; - } -#endif -}; - -namespace std { - -template <> -struct hash<non_default> -{ - std::size_t operator()(const non_default& x) - { - return std::hash<decltype(x.value)>{}(x.value); - } -}; - -} // namespace std - -TEST_CASE("non default") -{ - const auto n = 666u; - - auto v = SET_T<non_default>{}; - for (auto i = 0u; i < n; ++i) - v = v.insert({i}); - - CHECK(v.size() == n); -} - -TEST_CASE("equals") -{ - const auto n = 666u; - auto v = make_test_set(n); - - CHECK(v == v); - CHECK(v != v.insert(1234)); - CHECK(v == v.erase(1234)); - CHECK(v == v.insert(1234).erase(1234)); - CHECK(v == v.erase(64).insert(64)); - CHECK(v != v.erase(1234).insert(1234)); -} - -TEST_CASE("equals collisions") -{ - const auto n = 666u; - auto vals = make_values_with_collisions(n); - auto v = make_test_set(vals); - - CHECK(v == v); - CHECK(v != v.erase(vals[42])); - CHECK(v == v.erase(vals[42]).insert(vals[42])); - CHECK(v == - v.erase(vals[42]).erase(vals[13]).insert(vals[42]).insert(vals[13])); - CHECK(v == - v.erase(vals[42]).erase(vals[13]).insert(vals[13]).insert(vals[42])); -} - -TEST_CASE("exception safety") -{ - constexpr auto n = 2666u; - - using dadaist_set_t = typename dadaist_wrapper<SET_T<unsigned>>::type; - using dadaist_conflictor_set_t = - typename dadaist_wrapper<SET_T<conflictor, hash_conflictor>>::type; - - SECTION("insert") - { - auto v = dadaist_set_t{}; - auto d = dadaism{}; - for (auto i = 0u; v.size() < n;) { - try { - auto s = d.next(); - v = v.insert({i}); - ++i; - } catch (dada_error) {} - for (auto i : test_irange(0u, i)) - CHECK(v.count({i}) == 1); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } - - SECTION("insert collisions") - { - auto vals = make_values_with_collisions(n); - auto v = dadaist_conflictor_set_t{}; - auto d = dadaism{}; - for (auto i = 0u; v.size() < n;) { - try { - auto s = d.next(); - v = v.insert({vals[i]}); - ++i; - } catch (dada_error) {} - for (auto i : test_irange(0u, i)) - CHECK(v.count({vals[i]}) == 1); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } - - SECTION("erase") - { - auto v = dadaist_set_t{}; - auto d = dadaism{}; - for (auto i = 0u; i < n; ++i) - v = v.insert({i}); - for (auto i = 0u; v.size() > 0;) { - try { - auto s = d.next(); - v = v.erase({i}); - ++i; - } catch (dada_error) {} - for (auto i : test_irange(0u, i)) - CHECK(v.count({i}) == 0); - for (auto i : test_irange(i, n)) - CHECK(v.count({i}) == 1); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } - - SECTION("erase collisisions") - { - auto vals = make_values_with_collisions(n); - auto v = dadaist_conflictor_set_t{}; - auto d = dadaism{}; - for (auto i = 0u; i < n; ++i) - v = v.insert({vals[i]}); - for (auto i = 0u; v.size() > 0;) { - try { - auto s = d.next(); - v = v.erase({vals[i]}); - ++i; - } catch (dada_error) {} - for (auto i : test_irange(0u, i)) - CHECK(v.count({vals[i]}) == 0); - for (auto i : test_irange(i, n)) - CHECK(v.count({vals[i]}) == 1); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } -} diff --git a/third_party/immer/test/transient_tester.hpp b/third_party/immer/test/transient_tester.hpp deleted file mode 100644 index 3cf891bef957..000000000000 --- a/third_party/immer/test/transient_tester.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include "dada.hpp" - -namespace { - -template <typename VP, typename VT> -struct transient_tester -{ - VP vp; - VT vt; - dadaism d = {}; - bool transient = false; - - transient_tester(VP vp) - : vp{vp} - , vt{vp.transient()} - {} - - bool step() - { - auto s = d.next(); - if (soft_dada()) { - auto new_transient = !transient; - try { - if (new_transient) - vt = vp.transient(); - else - vp = vt.persistent(); - } catch (const dada_error&) { - return false; - } - transient = new_transient; - return true; - } else - return false; - } -}; - -template <typename VP> -transient_tester<VP, typename VP::transient_type> as_transient_tester(VP p) -{ - return {std::move(p)}; -} - -} // anonymous namespace diff --git a/third_party/immer/test/util.hpp b/third_party/immer/test/util.hpp deleted file mode 100644 index 41904f5a8907..000000000000 --- a/third_party/immer/test/util.hpp +++ /dev/null @@ -1,103 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#pragma once - -#include <boost/range/irange.hpp> -#include <boost/range/join.hpp> -#include <cstddef> - -namespace { - -struct identity_t -{ - template <typename T> - decltype(auto) operator()(T&& x) - { - return std::forward<decltype(x)>(x); - } -}; - -template <typename Integer> -auto test_irange(Integer from, Integer to) -{ -#if IMMER_SLOW_TESTS - return boost::irange(from, to); -#else - if (to - from < Integer{10}) - return boost::join(boost::irange(Integer{}, Integer{}), - boost::join(boost::irange(from, to, 1), - boost::irange(Integer{}, Integer{}))); - else - return boost::join(boost::irange(from, from + Integer{2}), - boost::join(boost::irange(from + Integer{2}, - to - Integer{2}, - (to - from) / Integer{5}), - boost::irange(to - Integer{2}, to))); -#endif -} - -} // anonymous namespace - -#if IMMER_SLOW_TESTS -#define CHECK_SLOW(...) CHECK(__VA_ARGS__) -#else -#define CHECK_SLOW(...) -#endif - -#if IMMER_SLOW_TESTS -#define CHECK_VECTOR_EQUALS_RANGE_AUX(v1_, first_, last_, xf_) \ - [](auto&& v1, auto&& first, auto&& last, auto&& xf) { \ - auto size = std::distance(first, last); \ - CHECK(static_cast<std::ptrdiff_t>(v1.size()) == size); \ - if (static_cast<std::ptrdiff_t>(v1.size()) != size) \ - return; \ - for (auto j = 0u; j < size; ++j) \ - CHECK(xf(v1[j]) == xf(*first++)); \ - }(v1_, first_, last_, xf_) // CHECK_EQUALS -#else -#define CHECK_VECTOR_EQUALS_RANGE_AUX(v1_, first_, last_, ...) \ - [](auto&& v1, auto&& first, auto&& last, auto&& xf) { \ - auto size = std::distance(first, last); \ - CHECK(static_cast<std::ptrdiff_t>(v1.size()) == size); \ - if (static_cast<std::ptrdiff_t>(v1.size()) != size) \ - return; \ - if (size > 0) { \ - CHECK(xf(v1[0]) == xf(*(first + (0)))); \ - CHECK(xf(v1[size - 1]) == xf(*(first + (size - 1)))); \ - CHECK(xf(v1[size / 2]) == xf(*(first + (size / 2)))); \ - CHECK(xf(v1[size / 3]) == xf(*(first + (size / 3)))); \ - CHECK(xf(v1[size / 4]) == xf(*(first + (size / 4)))); \ - CHECK(xf(v1[size - 1 - size / 2]) == \ - xf(*(first + (size - 1 - size / 2)))); \ - CHECK(xf(v1[size - 1 - size / 3]) == \ - xf(*(first + (size - 1 - size / 3)))); \ - CHECK(xf(v1[size - 1 - size / 4]) == \ - xf(*(first + (size - 1 - size / 4)))); \ - } \ - if (size > 1) { \ - CHECK(xf(v1[1]) == xf(*(first + (1)))); \ - CHECK(xf(v1[size - 2]) == xf(*(first + (size - 2)))); \ - } \ - if (size > 2) { \ - CHECK(xf(v1[2]) == xf(*(first + (2)))); \ - CHECK(xf(v1[size - 3]) == xf(*(first + (size - 3)))); \ - } \ - }(v1_, first_, last_, __VA_ARGS__) // CHECK_EQUALS -#endif // IMMER_SLOW_TESTS - -#define CHECK_VECTOR_EQUALS_AUX(v1_, v2_, ...) \ - [](auto&& v1, auto&& v2, auto&&... xs) { \ - CHECK_VECTOR_EQUALS_RANGE_AUX(v1, v2.begin(), v2.end(), xs...); \ - }(v1_, v2_, __VA_ARGS__) - -#define CHECK_VECTOR_EQUALS_RANGE(v1, b, e) \ - CHECK_VECTOR_EQUALS_RANGE_AUX((v1), (b), (e), identity_t{}) - -#define CHECK_VECTOR_EQUALS(v1, v2) \ - CHECK_VECTOR_EQUALS_AUX((v1), (v2), identity_t{}) diff --git a/third_party/immer/test/vector/B3-BL0.cpp b/third_party/immer/test/vector/B3-BL0.cpp deleted file mode 100644 index c0ddd2d66545..000000000000 --- a/third_party/immer/test/vector/B3-BL0.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> - -template <typename T> -using test_vector_t = immer::vector<T, immer::default_memory_policy, 3u, 0u>; - -#define VECTOR_T test_vector_t -#include "generic.ipp" diff --git a/third_party/immer/test/vector/B3-BL2.cpp b/third_party/immer/test/vector/B3-BL2.cpp deleted file mode 100644 index 15cfeb9e2f11..000000000000 --- a/third_party/immer/test/vector/B3-BL2.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> - -template <typename T> -using test_vector_t = immer::vector<T, immer::default_memory_policy, 3u, 2u>; - -#define VECTOR_T test_vector_t -#include "generic.ipp" diff --git a/third_party/immer/test/vector/B3-BL3.cpp b/third_party/immer/test/vector/B3-BL3.cpp deleted file mode 100644 index 5901940eab23..000000000000 --- a/third_party/immer/test/vector/B3-BL3.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> - -template <typename T> -using test_vector_t = immer::vector<T, immer::default_memory_policy, 3u, 3u>; - -#define VECTOR_T test_vector_t -#include "generic.ipp" diff --git a/third_party/immer/test/vector/B3-BL4.cpp b/third_party/immer/test/vector/B3-BL4.cpp deleted file mode 100644 index 5f3b8c17eec8..000000000000 --- a/third_party/immer/test/vector/B3-BL4.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> - -template <typename T> -using test_vector_t = immer::vector<T, immer::default_memory_policy, 3u, 4u>; - -#define VECTOR_T test_vector_t -#include "generic.ipp" diff --git a/third_party/immer/test/vector/default.cpp b/third_party/immer/test/vector/default.cpp deleted file mode 100644 index 1a1459ca124e..000000000000 --- a/third_party/immer/test/vector/default.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> - -#define VECTOR_T ::immer::vector -#include "generic.ipp" diff --git a/third_party/immer/test/vector/gc.cpp b/third_party/immer/test/vector/gc.cpp deleted file mode 100644 index ec006adfb748..000000000000 --- a/third_party/immer/test/vector/gc.cpp +++ /dev/null @@ -1,22 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> -#include <immer/vector.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename T> -using test_vector_t = immer::vector<T, gc_memory, 3u>; - -#define VECTOR_T test_vector_t -#include "generic.ipp" diff --git a/third_party/immer/test/vector/generic.ipp b/third_party/immer/test/vector/generic.ipp deleted file mode 100644 index ff277edbdb45..000000000000 --- a/third_party/immer/test/vector/generic.ipp +++ /dev/null @@ -1,488 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "test/dada.hpp" -#include "test/util.hpp" - -#include <immer/algorithm.hpp> - -#include <boost/range/adaptors.hpp> -#include <catch.hpp> - -#include <algorithm> -#include <numeric> -#include <string> -#include <vector> - -using namespace std::string_literals; - -#ifndef VECTOR_T -#error "define the vector template to use in VECTOR_T" -#endif - -template <typename V = VECTOR_T<unsigned>> -auto make_test_vector(unsigned min, unsigned max) -{ - auto v = V{}; - for (auto i = min; i < max; ++i) - v = v.push_back({i}); - return v; -} - -struct big_object -{ - std::array<std::size_t, 42> v; -}; - -struct string_sentinel -{}; - -bool operator==(const char16_t* i, string_sentinel) { return *i == '\0'; } - -bool operator!=(const char16_t* i, string_sentinel) { return *i != '\0'; } - -TEST_CASE("instantiation") -{ - SECTION("default") - { - auto v = VECTOR_T<int>{}; - CHECK(v.size() == 0u); - CHECK(v.empty()); - } - - SECTION("initializer list") - { - auto v = VECTOR_T<unsigned>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - CHECK_VECTOR_EQUALS(v, boost::irange(0u, 10u)); - CHECK(!v.empty()); - } - - SECTION("big object") - { - auto v = VECTOR_T<big_object>{{}, {}, {}, {}}; - CHECK(v.size() == 4); - } - - SECTION("range") - { - auto r = std::vector<int>{{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}}; - auto v = VECTOR_T<unsigned>{r.begin(), r.end()}; - CHECK_VECTOR_EQUALS(v, boost::irange(0u, 10u)); - } - - SECTION("empty range") - { - auto r = std::vector<int>{}; - auto v = VECTOR_T<unsigned>{r.begin(), r.end()}; - CHECK(v.size() == 0); - } - - SECTION("iterator/sentinel") - { - auto r = u"012345678"; - string_sentinel s; - auto v = VECTOR_T<unsigned>{r, s}; - CHECK_VECTOR_EQUALS(v, boost::irange(u'0', u'9')); - } - - SECTION("fill") - { - auto v1 = VECTOR_T<int>(4); - CHECK(v1.size() == 4); - auto v2 = VECTOR_T<int>(4, 42); - CHECK(v2.size() == 4); - CHECK(v2[2] == 42); - } -} - -TEST_CASE("back and front") -{ - auto v = VECTOR_T<unsigned>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - CHECK(v.front() == 0); - CHECK(v.back() == 9); -} - -TEST_CASE("at") -{ - auto v = VECTOR_T<unsigned>{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; - CHECK(v.at(0) == 0); - CHECK(v.at(5) == 5); - CHECK_THROWS_AS(v.at(10), const std::out_of_range&); - CHECK_THROWS_AS(v.at(11), const std::out_of_range&); -} - -TEST_CASE("push back one element") -{ - SECTION("one element") - { - const auto v1 = VECTOR_T<int>{}; - auto v2 = v1.push_back(42); - CHECK(v1.size() == 0u); - CHECK(v2.size() == 1u); - CHECK(v2[0] == 42); - } - - SECTION("many elements") - { - const auto n = 666u; - auto v = VECTOR_T<unsigned>{}; - for (auto i = 0u; i < n; ++i) { - v = v.push_back(i * 42); - CHECK(v.size() == i + 1); - for (decltype(v.size()) j = 0; j < v.size(); ++j) - CHECK(v[j] == j * 42); - } - } -} - -TEST_CASE("update") -{ - const auto n = 42u; - auto v = make_test_vector(0, n); - - SECTION("set") - { - const auto u = v.set(3u, 13u); - CHECK(u.size() == v.size()); - CHECK(u[2u] == 2u); - CHECK(u[3u] == 13u); - CHECK(u[4u] == 4u); - CHECK(u[40u] == 40u); - CHECK(v[3u] == 3u); - } - - SECTION("set further") - { - auto v = make_test_vector(0, 666); - - auto u = v.set(3u, 13u); - u = u.set(200u, 7u); - CHECK(u.size() == v.size()); - - CHECK(u[2u] == 2u); - CHECK(u[4u] == 4u); - CHECK(u[40u] == 40u); - CHECK(u[600u] == 600u); - - CHECK(u[3u] == 13u); - CHECK(u[200u] == 7u); - - CHECK(v[3u] == 3u); - CHECK(v[200u] == 200u); - } - - SECTION("set further more") - { - auto v = make_test_vector(0, 666u); - - for (decltype(v.size()) i = 0; i < v.size(); ++i) { - v = v.set(i, i + 1); - CHECK(v[i] == i + 1); - } - } - - SECTION("update") - { - const auto u = v.update(10u, [](auto x) { return x + 10; }); - CHECK(u.size() == v.size()); - CHECK(u[10u] == 20u); - CHECK(v[40u] == 40u); - - const auto w = v.update(40u, [](auto x) { return x - 10; }); - CHECK(w.size() == v.size()); - CHECK(w[40u] == 30u); - CHECK(v[40u] == 40u); - } -} - -TEST_CASE("iterator") -{ - const auto n = 666u; - auto v = make_test_vector(0, n); - - SECTION("empty vector") - { - auto v = VECTOR_T<unsigned>{}; - CHECK(v.begin() == v.end()); - } - - SECTION("works with range loop") - { - auto i = 0u; - for (const auto& x : v) - CHECK(x == i++); - CHECK(i == v.size()); - } - - SECTION("works with standard algorithms") - { - auto s = std::vector<unsigned>(n); - std::iota(s.begin(), s.end(), 0u); - std::equal(v.begin(), v.end(), s.begin(), s.end()); - } - - SECTION("can go back from end") - { - auto expected = n - 1; - auto last = v.end(); - CHECK(expected == *--last); - } - - SECTION("works with reversed range adaptor") - { - auto r = v | boost::adaptors::reversed; - auto i = n; - for (const auto& x : r) - CHECK(x == --i); - } - - SECTION("works with strided range adaptor") - { - auto r = v | boost::adaptors::strided(5); - auto i = 0u; - for (const auto& x : r) - CHECK(x == 5 * i++); - } - - SECTION("works reversed") - { - auto i = n; - for (auto iter = v.rbegin(), last = v.rend(); iter != last; ++iter) - CHECK(*iter == --i); - } - - SECTION("advance and distance") - { - auto i1 = v.begin(); - auto i2 = i1 + 100; - CHECK(100u == *i2); - CHECK(100 == i2 - i1); - CHECK(50u == *(i2 - 50)); - CHECK(-30 == (i2 - 30) - i2); - } -} - -TEST_CASE("equals") -{ - const auto n = 666u; - auto v = make_test_vector(0, n); - - CHECK(v == v); - CHECK(v == v.set(42, 42)); - CHECK(v != v.set(42, 24)); - CHECK(v == v.set(42, 24).set(42, 42)); - CHECK(v.set(42, 24) == v.set(42, 24)); - CHECK(v != v.push_back(7)); - CHECK(v.push_back(7) == v.push_back(7)); - CHECK(v.push_back(5) != v.push_back(7)); - CHECK(v != v.set(v.size() - 2, 24)); - CHECK(v == v.set(v.size() - 2, 24).set(v.size() - 2, v[v.size() - 2])); -} - -TEST_CASE("all of") -{ - const auto n = 666u; - auto v = make_test_vector(0, n); - - SECTION("false") - { - auto res = immer::all_of(v, [](auto x) { return x < 100; }); - CHECK(res == false); - } - SECTION("true") - { - auto res = immer::all_of(v, [](auto x) { return x < 1000; }); - CHECK(res == true); - } - SECTION("bounded, true") - { - auto res = immer::all_of( - v.begin() + 101, v.end() - 10, [](auto x) { return x > 100; }); - CHECK(res == true); - } - SECTION("bounded, false") - { - auto res = immer::all_of( - v.begin() + 101, v.end() - 10, [](auto x) { return x < 600; }); - CHECK(res == false); - } -} - -TEST_CASE("accumulate") -{ - const auto n = 666u; - auto v = make_test_vector(0, n); - - auto expected_n = [](auto n) { return n * (n - 1) / 2; }; - auto expected_i = [&](auto i, auto n) { - return expected_n(n) - expected_n(i); - }; - - SECTION("sum collection") - { - auto sum = immer::accumulate(v, 0u); - CHECK(sum == expected_n(v.size())); - } - - SECTION("sum range") - { - using namespace std; - { - auto sum = immer::accumulate(begin(v) + 100, begin(v) + 300, 0u); - CHECK(sum == expected_i(100, 300)); - } - { - auto sum = immer::accumulate(begin(v) + 31, begin(v) + 300, 0u); - CHECK(sum == expected_i(31, 300)); - } - { - auto sum = immer::accumulate(begin(v), begin(v) + 33, 0u); - CHECK(sum == expected_i(0, 33)); - } - { - auto sum = immer::accumulate(begin(v) + 100, begin(v) + 660, 0u); - CHECK(sum == expected_i(100, 660)); - } - { - auto sum = immer::accumulate(begin(v) + 100, begin(v) + 105, 0u); - CHECK(sum == expected_i(100, 105)); - } - { - auto sum = immer::accumulate(begin(v) + 660, begin(v) + 664, 0u); - CHECK(sum == expected_i(660, 664)); - } - } -} - -TEST_CASE("vector of strings") -{ - const auto n = 666u; - - auto v = VECTOR_T<std::string>{}; - for (auto i = 0u; i < n; ++i) - v = v.push_back(std::to_string(i)); - - for (decltype(v.size()) i = 0; i < v.size(); ++i) - CHECK(v[i] == std::to_string(i)); - - SECTION("set") - { - for (auto i = 0u; i < n; ++i) - v = v.set(i, "foo " + std::to_string(i)); - for (auto i = 0u; i < n; ++i) - CHECK(v[i] == "foo " + std::to_string(i)); - } -} - -struct non_default -{ - unsigned value; - non_default() = delete; - operator unsigned() const { return value; } - -#if IMMER_DEBUG_PRINT - friend std::ostream& operator<<(std::ostream& os, non_default x) - { - os << "ND{" << x.value << "}"; - return os; - } -#endif -}; - -TEST_CASE("non default") -{ - const auto n = 666u; - - auto v = VECTOR_T<non_default>{}; - for (auto i = 0u; i < n; ++i) - v = v.push_back({i}); - - CHECK_VECTOR_EQUALS(v, boost::irange(0u, n)); - - SECTION("set") - { - for (auto i = 0u; i < n; ++i) - v = v.set(i, {i + 1}); - - CHECK_VECTOR_EQUALS(v, boost::irange(1u, n + 1u)); - } -} - -TEST_CASE("take") -{ - const auto n = 666u; - - SECTION("anywhere") - { - auto v = make_test_vector(0, n); - - for (auto i : test_irange(0u, n)) { - auto vv = v.take(i); - CHECK(vv.size() == i); - CHECK_VECTOR_EQUALS_RANGE(vv, v.begin(), v.begin() + i); - } - } -} - -TEST_CASE("exception safety") -{ - constexpr auto n = 666u; - - using dadaist_vector_t = typename dadaist_wrapper<VECTOR_T<unsigned>>::type; - - SECTION("push back") - { - auto v = dadaist_vector_t{}; - auto d = dadaism{}; - for (auto i = 0u; v.size() < static_cast<decltype(v.size())>(n);) { - auto s = d.next(); - try { - v = v.push_back({i}); - ++i; - } catch (dada_error) {} - CHECK_VECTOR_EQUALS(v, boost::irange(0u, i)); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } - - SECTION("update") - { - auto v = make_test_vector<dadaist_vector_t>(0, n); - auto d = dadaism{}; - for (auto i = 0u; i < n;) { - auto s = d.next(); - try { - v = v.update(i, [](auto x) { return dada(), x + 1; }); - ++i; - } catch (dada_error) {} - CHECK_VECTOR_EQUALS( - v, boost::join(boost::irange(1u, 1u + i), boost::irange(i, n))); - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } - - SECTION("take") - { - auto v = make_test_vector<dadaist_vector_t>(0, n); - auto d = dadaism{}; - for (auto i = 0u; i < n;) { - auto s = d.next(); - auto r = dadaist_vector_t{}; - try { - r = v.take(i); - CHECK_VECTOR_EQUALS(r, boost::irange(0u, i++)); - } catch (dada_error) { - CHECK_VECTOR_EQUALS(r, boost::irange(0u, 0u)); - } - } - CHECK(d.happenings > 0); - IMMER_TRACE_E(d.happenings); - } -} diff --git a/third_party/immer/test/vector/issue-16.cpp b/third_party/immer/test/vector/issue-16.cpp deleted file mode 100644 index 81156b240bda..000000000000 --- a/third_party/immer/test/vector/issue-16.cpp +++ /dev/null @@ -1,122 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// Thanks Dominic Chen <ddchen@cs.cmu.edu> for reporting this issue -// https://github.com/arximboldi/immer/issues/16 - -#include <immer/flex_vector.hpp> -#include <immer/flex_vector_transient.hpp> -#include <immer/heap/gc_heap.hpp> -#include <vector> - -std::vector<unsigned> init = { - 291, 438, 755, 608, 594, 912, 73, 97, 496, 101, 837, 696, 978, - 948, 126, 131, 624, 26, 590, 201, 219, 339, 193, 218, 866, 407, - 538, 780, 312, 909, 129, 883, 571, 865, 854, 372, 488, 695, 750, - 341, 798, 375, 350, 1013, 361, 1012, 743, 425, 68, 280, 245, 149, - 342, 535, 901, 223, 285, 928, 666, 534, 166, 963, 171, 893, 297, - 1017, 549, 172, 505, 965, 831, 563, 79, 180, 147, 543, 639, 1022, - 880, 559, 426, 27, 657, 33, 252, 758, 8, 641, 699, 399, 335, - 473, 625, 703, 264, 796, 61, 737, 527, 795, 123, 200, 287, 857, - 208, 897, 354, 885, 581, 57, 752, 855, 56, 1007, 357, 643, 476, - 113, 955, 349, 299, 76, 393, 557, 967, 995, 233, 990, 469, 742, - 681, 874, 673, 530, 835, 24, 178, 81, 69, 40, 368, 981, 941, - 645, 808, 511, 982, 888, 136, 100, 960, 804, 806, 600, 500, 337, - 580, 551, 593, 612, 318, 660, 232, 17, 879, 86, 424, 202, 112, - 235, 791, 873, 838, 47, 574, 858, 78, 237, 846, 340, 802, 907, - 72, 38, 44, 902, 595, 940, 182, 784, 207, 355, 815, 545, 555, - 258, 144, 564, 463, 198, 1004, 4, 175, 468, 658, 59, 938, 63, - 20, 179, 714, 721, 723, 381, 3, 745, 415, 119, 413, 923, 157, - 824, 668, 409, 459, 560, 353, 379, 450, 430, 479, 274, 309, 661, - 508, 474, 771, 504, 674, 51, 173, 670, 83, 921, 1019, 956, 725, - 556, 427, 597, 794, 918, 95, 514, 98, 638, 205, 727, 162, 905, - 728, 431, 203, 828, 971, 648, 871, 215, 646, 1006, 816, 277, 861, - 576, 99, 637, 67, 28, 161, 137, 14, 506, 717, 93, 298, 251, - 975, 927, 818, 43, 284, 994, 196, 195, 260, 705, 604, 169, 296, - 785, 911, 398, 687, 760, 486, 642, 417, 445, 925, 763, 756, 653, - 662, 359, 84, 151, 980, 914, 440, 546, 329, 665, 435, 732, 922, - 377, 105, 532, 282, 822, 878, 419, 659, 65, 111, 421, 672, 146, - 320, 316, 31, 522, 145, 513, 373, 773, 184, 974, 621, 366, 124, - 623, 953, 267, 712, 121, 512, 214, 1002, 455, 694, 834, 618, 324, - 656, 257, 206, 554, 334, 606, 305, 1008, 190, 160, 502, 1024, 891, - 751, 789, 821, 462, 489, 908, 370, 164, 746, 270, 319, 491, 443, - 531, 775, 977, 244, 485, 840, 892, 850, 347, 729, 317, 74, 731, - 738, 790, 988, 903, 176, 211, 890, 509, 592, 444, 307, 45, 810, - 390, 239, 678, 999, 414, 693, 345, 363, 382, 602, 516, 801, 310, - 754, 774, 364, 480, 290, 322, 887, 168, 37, 140, 937, 578, 1005, - 614, 734, 449, 230, 541, 761, 931, 882, 920, 210, 807, 115, 964, - 521, 862, 628, 747, 490, 422, 788, 691, 675, 652, 25, 582, 585, - 961, 472, 722, 7, 367, 15, 275, 700, 249, 116, 969, 325, 706, - 493, 524, 537, 875, 22, 688, 843, 575, 288, 141, 830, 698, 562, - 833, 143, 117, 683, 1000, 238, 397, 827, 619, 686, 1018, 973, 80, - 689, 165, 702, 88, 332, 192, 730, 847, 408, 58, 634, 471, 958, - 204, 236, 314, 494, 158, 412, 226, 135, 103, 998, 85, 904, 587, - 194, 6, 380, 987, 266, 853, 369, 949, 34, 799, 884, 16, 944, - 701, 313, 300, 611, 148, 457, 216, 900, 10, 715, 586, 561, 917, - 1020, 800, 640, 104, 864, 185, 566, 492, 709, 1009, 498, 859, 945, - 710, 433, 819, 411, 418, 649, 876, 733, 286, 326, 599, 986, 465, - 929, 272, 916, 935, 1, 87, 650, 609, 344, 598, 951, 221, 242, - 352, 635, 680, 464, 75, 256, 962, 336, 82, 383, 836, 993, 222, - 446, 110, 970, 591, 439, 677, 308, 186, 664, 188, 253, 770, 5, - 651, 467, 684, 139, 762, 315, 89, 507, 477, 406, 358, 753, 877, - 442, 32, 2, 997, 120, 946, 391, 220, 996, 125, 943, 749, 130, - 553, 385, 692, 814, 615, 396, 388, 610, 630, 957, 371, 741, 268, - 199, 740, 823, 588, 250, 269, 577, 254, 845, 825, 153, 62, 303, - 842, 453, 241, 114, 483, 868, 550, 952, 429, 434, 529, 503, 333, - 616, 913, 23, 872, 679, 497, 9, 841, 772, 150, 776, 52, 947, - 805, 613, 620, 343, 895, 812, 782, 138, 281, 778, 829, 289, 820, - 106, 400, 484, 402, 915, 720, 122, 724, 783, 436, 499, 605, 627, - 191, 607, 536, 91, 461, 108, 976, 851, 46, 676, 765, 109, 96, - 437, 323, 261, 330, 273, 311, 271, 972, 719, 306, 889, 707, 384, - 764, 979, 572, 475, 231, 519, 682, 832, 448, 356, 966, 1010, 404, - 757, 209, 548, 617, 228, 482, 156, 596, 1014, 405, 187, 860, 420, - 655, 276, 797, 243, 1003, 229, 950, 869, 163, 321, 848, 395, 302, - 803, 711, 515, 376, 886, 278, 128, 870, 1015, 989, 636, 1023, 573, - 704, 984, 601, 932, 18, 386, 926, 632, 647, 579, 365, 669, 910, - 768, 809, 526, 769, 66, 432, 213, 293, 48, 839, 217, 224, 813, - 899, 328, 177, 654, 401, 544, 154, 118, 736, 766, 495, 936, 767, - 523, 569, 458, 460, 685, 107, 718, 631, 844, 248, 933, 60, 227, - 374, 246, 247, 331, 894, 183, 279, 338, 387, 633, 565, 403, 744, - 849, 41, 942, 517, 389, 518, 133, 622, 35, 779, 362, 726, 1021, - 189, 787, 71, 539, 262, 423, 346, 856, 212, 748, 64, 930, 667, - 881, 781, 603, 817, 410, 378, 170, 225, 558, 29, 906, 174, 939, - 21, 292, 304, 663, 240, 793, 567, 456, 255, 811, 954, 735, 867, - 428, 991, 152, 528, 70, 263, 392, 697, 671, 155, 49, 301, 792, - 525, 959, 1001, 90, 924, 896, 826, 452, 968, 11, 542, 53, 327, - 777, 294, 94, 589, 547, 584, 416, 351, 713, 478, 55, 451, 36, - 708, 501, 132, 863, 54, 19, 142, 13, 934, 134, 30, 466, 716, - 295, 92, 447, 102, 181, 520, 644, 481, 470, 540, 583, 552, 786, - 690, 487, 394, 983, 259, 510, 50, 568, 533, 759, 992, 283, 39, - 360, 919, 167, 852, 42, 629, 1016, 454, 441, 1011, 0, 77, 197, - 234, 127, 159, 12, 898, 348, 265, 626, 739, 985}; - -using gc_policy = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -using immvec = immer::flex_vector_transient<unsigned, gc_policy>; - -void erase(immvec& v, unsigned idx) -{ - auto v2(v); - v.take(idx); - v2.drop(idx + 1); - v.append(v2); -} - -int main(int argc, char** argv) -{ - immvec vector; - for (auto i : init) - vector.push_back(i); - - erase(vector, 470); - vector.push_back(224); - erase(vector, 958); -} diff --git a/third_party/immer/test/vector/issue-46.cpp b/third_party/immer/test/vector/issue-46.cpp deleted file mode 100644 index 6475be210d05..000000000000 --- a/third_party/immer/test/vector/issue-46.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -// Thanks Guiguiprim for reporting this issue -// https://github.com/arximboldi/immer/issues/46 - -#include <immer/flex_vector.hpp> -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -#include <catch.hpp> - -TEST_CASE("operator==() may return bad result") -{ - using bool_vec = immer::flex_vector<bool>; - - immer::vector<bool_vec> v0; - auto tv = v0.transient(); - tv.push_back(bool_vec(9, false)); - tv.push_back(bool_vec(10, false)); - tv.push_back(bool_vec(8, false)); - tv.push_back(bool_vec(6, false)); - tv.push_back(bool_vec(9, false)); - tv.push_back(bool_vec(7, false)); - tv.push_back(bool_vec(8, false)); - tv.push_back(bool_vec(9, false)); - tv.push_back(bool_vec(10, false)); - v0 = tv.persistent(); - - auto v1 = v0.update(1, [](bool_vec vec) { return vec.set(8, true); }); - - CHECK(v0[1] != v1[1]); - CHECK(v0 != v1); -} diff --git a/third_party/immer/test/vector/issue-74.cpp b/third_party/immer/test/vector/issue-74.cpp deleted file mode 100644 index 8650be014f1f..000000000000 --- a/third_party/immer/test/vector/issue-74.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "immer/box.hpp" -#include "immer/set.hpp" -#include "immer/vector.hpp" - -#include <functional> - -struct my_type -{ - using container_t = immer::vector<immer::box<my_type>>; - using func_t = std::function<int(int)>; - - int ival; - double dval; - func_t func; - container_t children; -}; - -int main() -{ - my_type::container_t items = {my_type()}; - immer::set<int> items2; - auto items3 = items2.insert(10); - return 0; -} diff --git a/third_party/immer/test/vector_transient/B3-BL0.cpp b/third_party/immer/test/vector_transient/B3-BL0.cpp deleted file mode 100644 index a0af0a17124c..000000000000 --- a/third_party/immer/test/vector_transient/B3-BL0.cpp +++ /dev/null @@ -1,21 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -template <typename T> -using test_vector_t = immer::vector<T, immer::default_memory_policy, 3u, 0u>; - -template <typename T> -using test_vector_transient_t = typename test_vector_t<T>::transient_type; - -#define VECTOR_T test_vector_t -#define VECTOR_TRANSIENT_T test_vector_transient_t - -#include "generic.ipp" diff --git a/third_party/immer/test/vector_transient/default.cpp b/third_party/immer/test/vector_transient/default.cpp deleted file mode 100644 index f3089086a9a0..000000000000 --- a/third_party/immer/test/vector_transient/default.cpp +++ /dev/null @@ -1,15 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -#define VECTOR_T ::immer::vector -#define VECTOR_TRANSIENT_T ::immer::vector_transient - -#include "generic.ipp" diff --git a/third_party/immer/test/vector_transient/gc.cpp b/third_party/immer/test/vector_transient/gc.cpp deleted file mode 100644 index 393d2d1bbc10..000000000000 --- a/third_party/immer/test/vector_transient/gc.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include <immer/vector.hpp> -#include <immer/vector_transient.hpp> - -#include <immer/heap/gc_heap.hpp> -#include <immer/refcount/no_refcount_policy.hpp> - -using gc_memory = immer::memory_policy<immer::heap_policy<immer::gc_heap>, - immer::no_refcount_policy, - immer::gc_transience_policy, - false>; - -template <typename T> -using test_vector_t = immer::vector<T, gc_memory, 3u>; - -template <typename T> -using test_vector_transient_t = immer::vector_transient<T, gc_memory, 3u>; - -#define VECTOR_T test_vector_t -#define VECTOR_TRANSIENT_T test_vector_transient_t - -#include "generic.ipp" diff --git a/third_party/immer/test/vector_transient/generic.ipp b/third_party/immer/test/vector_transient/generic.ipp deleted file mode 100644 index 6cd25a567d53..000000000000 --- a/third_party/immer/test/vector_transient/generic.ipp +++ /dev/null @@ -1,267 +0,0 @@ -// -// immer: immutable data structures for C++ -// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente -// -// This software is distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt -// - -#include "test/dada.hpp" -#include "test/transient_tester.hpp" -#include "test/util.hpp" - -#include <catch.hpp> - -#ifndef VECTOR_T -#error "define the vector template to use in VECTOR_T" -#endif - -#ifndef VECTOR_TRANSIENT_T -#error "define the vector template to use in VECTOR_TRANSIENT_T" -#endif - -template <typename V = VECTOR_T<unsigned>> -auto make_test_vector(unsigned min, unsigned max) -{ - auto v = V{}; - for (auto i = min; i < max; ++i) - v = v.push_back({i}); - return v; -} - -TEST_CASE("from vector and to vector") -{ - constexpr auto n = 100u; - - auto v = make_test_vector(0, n).transient(); - CHECK_VECTOR_EQUALS(v, boost::irange(0u, n)); - - auto p = v.persistent(); - CHECK_VECTOR_EQUALS(p, boost::irange(0u, n)); -} - -TEST_CASE("protect persistence") -{ - auto v = VECTOR_T<unsigned>{}.transient(); - v.push_back(12); - auto p = v.persistent(); - v.set(0, 42); - CHECK(p[0] == 12); - CHECK(v[0] == 42); -} - -TEST_CASE("push back move") -{ - using vector_t = VECTOR_T<unsigned>; - - auto v = vector_t{}; - - auto check_move = [&](vector_t&& x) -> vector_t&& { - if (vector_t::memory_policy::use_transient_rvalues) - CHECK(&x == &v); - else - CHECK(&x != &v); - return std::move(x); - }; - - v = check_move(std::move(v).push_back(0)); - v = check_move(std::move(v).push_back(1)); - v = check_move(std::move(v).push_back(2)); - auto addr_before = &v[0]; - v = check_move(std::move(v).push_back(3)); - auto addr_after = &v[0]; - - if (vector_t::memory_policy::use_transient_rvalues) - CHECK(addr_before == addr_after); - else - CHECK(addr_before != addr_after); - - CHECK_VECTOR_EQUALS(v, boost::irange(0u, 4u)); -} - -TEST_CASE("set move") -{ - using vector_t = VECTOR_T<unsigned>; - - auto v = vector_t{}; - - auto check_move = [&](vector_t&& x) -> vector_t&& { - if (vector_t::memory_policy::use_transient_rvalues) - CHECK(&x == &v); - else - CHECK(&x != &v); - return std::move(x); - }; - - v = v.push_back(0); - - auto addr_before = &v[0]; - v = check_move(std::move(v).set(0, 1)); - auto addr_after = &v[0]; - - if (vector_t::memory_policy::use_transient_rvalues) - CHECK(addr_before == addr_after); - else - CHECK(addr_before != addr_after); - - CHECK_VECTOR_EQUALS(v, boost::irange(1u, 2u)); -} - -TEST_CASE("update move") -{ - using vector_t = VECTOR_T<unsigned>; - - auto v = vector_t{}; - - auto check_move = [&](vector_t&& x) -> vector_t&& { - if (vector_t::memory_policy::use_transient_rvalues) - CHECK(&x == &v); - else - CHECK(&x != &v); - return std::move(x); - }; - - v = v.push_back(0); - - auto addr_before = &v[0]; - v = check_move(std::move(v).update(0, [](auto x) { return x + 1; })); - auto addr_after = &v[0]; - - if (vector_t::memory_policy::use_transient_rvalues) - CHECK(addr_before == addr_after); - else - CHECK(addr_before != addr_after); - - CHECK_VECTOR_EQUALS(v, boost::irange(1u, 2u)); -} - -TEST_CASE("take move") -{ - using vector_t = VECTOR_T<unsigned>; - - auto v = vector_t{}; - - auto check_move = [&](vector_t&& x) -> vector_t&& { - if (vector_t::memory_policy::use_transient_rvalues) - CHECK(&x == &v); - else - CHECK(&x != &v); - return std::move(x); - }; - - v = v.push_back(0).push_back(1); - - auto addr_before = &v[0]; - v = check_move(std::move(v).take(1)); - auto addr_after = &v[0]; - - if (vector_t::memory_policy::use_transient_rvalues) - CHECK(addr_before == addr_after); - else - CHECK(addr_before != addr_after); - - CHECK_VECTOR_EQUALS(v, boost::irange(0u, 1u)); -} - -TEST_CASE("exception safety") -{ - constexpr auto n = 667u; - - using dadaist_vector_t = typename dadaist_wrapper<VECTOR_T<unsigned>>::type; - - SECTION("push back") - { - auto t = as_transient_tester(dadaist_vector_t{}); - auto d = dadaism{}; - for (auto li = 0u, i = 0u; i < n;) { - auto s = d.next(); - try { - if (t.transient) - t.vt.push_back({i}); - else - t.vp = t.vp.push_back({i}); - ++i; - if (t.step()) - li = i; - } catch (dada_error) {} - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i)); - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); - } else { - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, i)); - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, li)); - } - } - CHECK(d.happenings > 0); - CHECK(t.d.happenings > 0); - IMMER_TRACE_E(d.happenings); - IMMER_TRACE_E(t.d.happenings); - } - - SECTION("update") - { - using boost::irange; - using boost::join; - - auto t = as_transient_tester(make_test_vector<dadaist_vector_t>(0, n)); - auto d = dadaism{}; - for (auto li = 0u, i = 0u; i < n;) { - auto s = d.next(); - try { - if (t.transient) - t.vt.update(i, [](auto x) { return dada(), x + 1; }); - else - t.vp = t.vp.update(i, [](auto x) { return dada(), x + 1; }); - ++i; - if (t.step()) - li = i; - } catch (dada_error) {} - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, - join(irange(1u, 1u + i), irange(i, n))); - CHECK_VECTOR_EQUALS(t.vp, - join(irange(1u, 1u + li), irange(li, n))); - } else { - CHECK_VECTOR_EQUALS(t.vp, - join(irange(1u, 1u + i), irange(i, n))); - CHECK_VECTOR_EQUALS(t.vt, - join(irange(1u, 1u + li), irange(li, n))); - } - } - CHECK(d.happenings > 0); - CHECK(t.d.happenings > 0); - } - - SECTION("take") - { - auto t = as_transient_tester(make_test_vector<dadaist_vector_t>(0, n)); - auto d = dadaism{}; - auto deltas = magic_rotator(); - auto delta = 0u; - for (auto i = n, li = i;;) { - auto s = d.next(); - auto r = dadaist_vector_t{}; - try { - if (t.transient) - t.vt.take(i); - else - t.vp = t.vp.take(i); - if (t.step()) - li = i; - delta = deltas.next(); - if (i < delta) - break; - i -= delta; - } catch (dada_error) {} - if (t.transient) { - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, i + delta)); - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, li)); - } else { - CHECK_VECTOR_EQUALS(t.vp, boost::irange(0u, i + delta)); - CHECK_VECTOR_EQUALS(t.vt, boost::irange(0u, li)); - } - } - CHECK(d.happenings > 0); - CHECK(t.d.happenings > 0); - } -} diff --git a/third_party/immer/tools/clojure/README.md b/third_party/immer/tools/clojure/README.md deleted file mode 100644 index 2628aa2e5f40..000000000000 --- a/third_party/immer/tools/clojure/README.md +++ /dev/null @@ -1,4 +0,0 @@ - -``` -lein run -``` diff --git a/third_party/immer/tools/clojure/project.clj b/third_party/immer/tools/clojure/project.clj deleted file mode 100644 index 735deab2f9eb..000000000000 --- a/third_party/immer/tools/clojure/project.clj +++ /dev/null @@ -1,12 +0,0 @@ -(defproject immer-benchmarks "0.1.0-SNAPSHOT" - :description "Benchmarks for immutable data structures" - :url "http://example.com/FIXME" - :dependencies [[org.clojure/clojure "1.8.0"] - [org.clojure/core.rrb-vector "0.0.11"] - [criterium "0.4.4"]] - :plugins [[lein-git-deps "0.0.1-SNAPSHOT"]] - ;;:git-dependencies [["https://github.com/clojure/core.rrb-vector.git"]] - :source-paths [;;".lein-git-deps/core.rrb-vector/src/main/clojure" - "src"] - - :main immer-benchmark) diff --git a/third_party/immer/tools/clojure/src/immer_benchmark.clj b/third_party/immer/tools/clojure/src/immer_benchmark.clj deleted file mode 100644 index f3d6f73e6c18..000000000000 --- a/third_party/immer/tools/clojure/src/immer_benchmark.clj +++ /dev/null @@ -1,131 +0,0 @@ -(ns immer-benchmark - (:require [criterium.core :as c] - [clojure.core.rrb-vector :as fv])) - -(defn h0 [& args] - (apply println "\n####" args)) - -(defn h1 [& args] - (apply println "\n====" args)) - -(defn h2 [& args] - (apply println "\n----" args)) - -(defn run-benchmarks [N S] - (h0 "Running benchmarks: N =" N " S =" S) - - (def c-steps 10) - - (defn vector-push-f [v] - (loop [v v - i 0] - (if (< i N) - (recur (fv/catvec (fv/vector i) v) - (inc i)) - v))) - - (defn vector-push [v] - (loop [v v - i 0] - (if (< i N) - (recur (conj v i) - (inc i)) - v))) - - (defn vector-push! [v] - (loop [v (transient v) - i 0] - (if (< i N) - (recur (conj! v i) - (inc i)) - (persistent! v)))) - - (defn vector-concat [v vc] - (loop [v v - i 0] - (if (< i c-steps) - (recur (fv/catvec v vc) - (inc i)) - v))) - - (defn vector-update [v] - (loop [v v - i 0] - (if (< i N) - (recur (assoc v i (+ i 1)) - (inc i)) - v))) - - (defn vector-update-random [v] - (loop [v v - i 0] - (if (< i N) - (recur (assoc v (rand-int N) i) - (inc i)) - v))) - - (defn vector-update! [v] - (loop [v (transient v) - i 0] - (if (< i N) - (recur (assoc! v i (+ i 1)) - (inc i)) - (persistent! v)))) - - (defn vector-update-random! [v] - (loop [v (transient v) - i 0] - (if (< i N) - (recur (assoc! v (rand-int N) i) - (inc i)) - (persistent! v)))) - - (defn vector-iter [v] - (reduce + 0 v)) - - (defn the-benchmarks [empty-v] - (def full-v (into empty-v (range N))) - (h2 "iter") - (c/bench (vector-iter full-v) :samples S) - (if (> N 100000) - (h2 "skipping updates 'cuz N > 100000 (would run out of mem)") - (do - (h2 "update!") - (c/bench (vector-update! full-v) :samples S) - (h2 "update-random!") - (c/bench (vector-update-random! full-v) :samples S) - (h2 "push!") - (c/bench (vector-push! empty-v) :samples S) - (h2 "update") - (c/bench (vector-update full-v) :samples S) - (h2 "update-random") - (c/bench (vector-update-random full-v) :samples S) - (h2 "push") - (c/bench (vector-push empty-v) :samples S)))) - - (defn the-rrb-benchmarks [empty-v] - (if (> N 1000) - (h2 "skipping relaxed test 'cuz N > 1000 (rrb-vector bug)") - (do - (def full-v (vector-push-f empty-v)) - (h2 "iter/f") - (c/bench (vector-iter full-v) :samples S) - (h2 "update/f") - (c/bench (vector-update full-v) :samples S) - (h2 "update-random/f") - (c/bench (vector-update-random full-v) :samples S))) - (def short-v (into empty-v (range (/ N c-steps)))) - (h2 "concat") - (c/bench (vector-concat empty-v short-v)) :samples S) - - (h1 "vector") - (the-benchmarks (vector)) - - (h1 "rrb-vector") - (the-benchmarks (fv/vector)) - (the-rrb-benchmarks (fv/vector))) - -(defn -main [] - (run-benchmarks 1000 100) - (run-benchmarks 100000 20) - (run-benchmarks 10000000 3)) diff --git a/third_party/immer/tools/docker/icfp17/Dockerfile b/third_party/immer/tools/docker/icfp17/Dockerfile deleted file mode 100644 index 5e6d1292e592..000000000000 --- a/third_party/immer/tools/docker/icfp17/Dockerfile +++ /dev/null @@ -1,77 +0,0 @@ -FROM debian:stretch - -MAINTAINER arximboldi - -## install immer - -RUN apt-get update && \ - apt-get install -y git -RUN git clone https://github.com/arximboldi/immer.git - -## prepare test dependencies - -RUN apt-get update && \ - apt-get install -y \ - autoconf \ - automake \ - cmake \ - g++ \ - libboost-dev \ - libtool \ - make \ - pkg-config \ - -- - -RUN mkdir /immer/build -WORKDIR /immer/build -RUN cmake .. -DCMAKE_BUILD_TYPE=Release -DCHECK_BENCHMARKS=1 -RUN make deps -RUN make tests examples benchmarks - -## prepare clojure dependencies - -RUN apt-get update && \ - apt-get install -y default-jdk curl - -RUN curl https://raw.githubusercontent.com/technomancy/leiningen/stable/bin/lein \ - > /usr/local/bin/lein && \ - chmod +x /usr/local/bin/lein - -WORKDIR /immer/tools/clojure -ENV LEIN_ROOT ok -RUN lein deps -RUN lein compile - -## prepare scala dependencies - -RUN apt-get update && \ - apt-get install -y gnupg2 apt-transport-https -RUN echo "deb https://dl.bintray.com/sbt/debian /" \ - > /etc/apt/sources.list.d/sbt.list && \ - apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 \ - --recv 2EE0EA64E40A89B84B2DF73499E82A75642AC823 && \ - apt-get update && \ - apt-get install -y sbt - -WORKDIR /immer/tools/scala -RUN sbt compile - -## prepare python dependencies - -RUN apt-get update && \ - apt-get install -y python-pip - -RUN pip install \ - pytest-benchmark \ - pyrsistent - -RUN pip install /immer - -## add some editors - -RUN apt-get update && \ - apt-get install -y emacs vim nano - -## go to a useful working dir - -WORKDIR /immer diff --git a/third_party/immer/tools/include/catch.hpp b/third_party/immer/tools/include/catch.hpp deleted file mode 100644 index c86bc6adc328..000000000000 --- a/third_party/immer/tools/include/catch.hpp +++ /dev/null @@ -1,9458 +0,0 @@ -/* - * CATCH v1.1 build 3 (master branch) - * Generated: 2015-05-20 13:23:44.423074 - * ---------------------------------------------------------- - * This file has been merged from multiple headers. Please don't edit it directly - * Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved. - * - * Distributed under the Boost Software License, Version 1.0. (See accompanying - * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - */ -#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED -#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED - -#define TWOBLUECUBES_CATCH_HPP_INCLUDED - -// #included from: internal/catch_suppress_warnings.h - -#define TWOBLUECUBES_CATCH_SUPPRESS_WARNINGS_H_INCLUDED - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(push) -# pragma warning(disable: 161 1682) -# else // __ICC -# pragma clang diagnostic ignored "-Wglobal-constructors" -# pragma clang diagnostic ignored "-Wvariadic-macros" -# pragma clang diagnostic ignored "-Wc99-extensions" -# pragma clang diagnostic ignored "-Wunused-variable" -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wpadded" -# pragma clang diagnostic ignored "-Wc++98-compat" -# pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -# endif -#elif defined __GNUC__ -# pragma GCC diagnostic ignored "-Wvariadic-macros" -# pragma GCC diagnostic ignored "-Wunused-variable" -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wpadded" -#endif - -#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) -# define CATCH_IMPL -#endif - -#ifdef CATCH_IMPL -# ifndef CLARA_CONFIG_MAIN -# define CLARA_CONFIG_MAIN_NOT_DEFINED -# define CLARA_CONFIG_MAIN -# endif -#endif - -// #included from: internal/catch_notimplemented_exception.h -#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_H_INCLUDED - -// #included from: catch_common.h -#define TWOBLUECUBES_CATCH_COMMON_H_INCLUDED - -#define INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) name##line -#define INTERNAL_CATCH_UNIQUE_NAME_LINE( name, line ) INTERNAL_CATCH_UNIQUE_NAME_LINE2( name, line ) -#define INTERNAL_CATCH_UNIQUE_NAME( name ) INTERNAL_CATCH_UNIQUE_NAME_LINE( name, __LINE__ ) - -#define INTERNAL_CATCH_STRINGIFY2( expr ) #expr -#define INTERNAL_CATCH_STRINGIFY( expr ) INTERNAL_CATCH_STRINGIFY2( expr ) - -#include <sstream> -#include <stdexcept> -#include <algorithm> - -// #included from: catch_compiler_capabilities.h -#define TWOBLUECUBES_CATCH_COMPILER_CAPABILITIES_HPP_INCLUDED - -// Detect a number of compiler features - mostly C++11/14 conformance - by compiler -// The following features are defined: -// -// CATCH_CONFIG_CPP11_NULLPTR : is nullptr supported? -// CATCH_CONFIG_CPP11_NOEXCEPT : is noexcept supported? -// CATCH_CONFIG_CPP11_GENERATED_METHODS : The delete and default keywords for compiler generated methods -// CATCH_CONFIG_CPP11_IS_ENUM : std::is_enum is supported? -// CATCH_CONFIG_CPP11_TUPLE : std::tuple is supported - -// CATCH_CONFIG_CPP11_OR_GREATER : Is C++11 supported? - -// CATCH_CONFIG_SFINAE : is basic (C++03) SFINAE supported? -// CATCH_CONFIG_VARIADIC_MACROS : are variadic macros supported? - -// A lot of this code is based on Boost (1.53) - -#ifdef __clang__ - -# if __has_feature(cxx_nullptr) -# define CATCH_CONFIG_CPP11_NULLPTR -# endif - -# if __has_feature(cxx_noexcept) -# define CATCH_CONFIG_CPP11_NOEXCEPT -# endif - -#endif // __clang__ - -//////////////////////////////////////////////////////////////////////////////// -// Borland -#ifdef __BORLANDC__ - -#if (__BORLANDC__ > 0x582 ) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif - -#endif // __BORLANDC__ - -//////////////////////////////////////////////////////////////////////////////// -// EDG -#ifdef __EDG_VERSION__ - -#if (__EDG_VERSION__ > 238 ) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif - -#endif // __EDG_VERSION__ - -//////////////////////////////////////////////////////////////////////////////// -// Digital Mars -#ifdef __DMC__ - -#if (__DMC__ > 0x840 ) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif - -#endif // __DMC__ - -//////////////////////////////////////////////////////////////////////////////// -// GCC -#ifdef __GNUC__ - -#if __GNUC__ < 3 - -#if (__GNUC_MINOR__ >= 96 ) -//#define CATCH_CONFIG_SFINAE -#endif - -#elif __GNUC__ >= 3 - -// #define CATCH_CONFIG_SFINAE // Taking this out completely for now - -#endif // __GNUC__ < 3 - -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6 && defined(__GXX_EXPERIMENTAL_CXX0X__) ) - -#define CATCH_CONFIG_CPP11_NULLPTR -#endif - -#endif // __GNUC__ - -//////////////////////////////////////////////////////////////////////////////// -// Visual C++ -#ifdef _MSC_VER - -#if (_MSC_VER >= 1310 ) // (VC++ 7.0+) -//#define CATCH_CONFIG_SFINAE // Not confirmed -#endif - -#if (_MSC_VER >= 1600) -#define CATCH_CONFIG_CPP11_NULLPTR -#endif - -#if (_MSC_VER >= 1900 ) // (VC++ 13 (VS2015)) -#define CATCH_CONFIG_CPP11_NOEXCEPT -#define CATCH_CONFIG_CPP11_GENERATED_METHODS -#endif - -#endif // _MSC_VER - -// Use variadic macros if the compiler supports them -#if ( defined _MSC_VER && _MSC_VER > 1400 && !defined __EDGE__) || \ - ( defined __WAVE__ && __WAVE_HAS_VARIADICS ) || \ - ( defined __GNUC__ && __GNUC__ >= 3 ) || \ - ( !defined __cplusplus && __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L ) - -#ifndef CATCH_CONFIG_NO_VARIADIC_MACROS -#define CATCH_CONFIG_VARIADIC_MACROS -#endif - -#endif - -//////////////////////////////////////////////////////////////////////////////// -// C++ language feature support - -// catch all support for C++11 -#if (__cplusplus >= 201103L) - -# define CATCH_CPP11_OR_GREATER - -# ifndef CATCH_CONFIG_CPP11_NULLPTR -# define CATCH_CONFIG_CPP11_NULLPTR -# endif - -# ifndef CATCH_CONFIG_CPP11_NOEXCEPT -# define CATCH_CONFIG_CPP11_NOEXCEPT -# endif - -# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS -# define CATCH_CONFIG_CPP11_GENERATED_METHODS -# endif - -# ifndef CATCH_CONFIG_CPP11_IS_ENUM -# define CATCH_CONFIG_CPP11_IS_ENUM -# endif - -# ifndef CATCH_CONFIG_CPP11_TUPLE -# define CATCH_CONFIG_CPP11_TUPLE -# endif - -# ifndef CATCH_CONFIG_SFINAE -//# define CATCH_CONFIG_SFINAE // Don't use, for now -# endif - -# ifndef CATCH_CONFIG_VARIADIC_MACROS -# define CATCH_CONFIG_VARIADIC_MACROS -# endif - -#endif // __cplusplus >= 201103L - -// noexcept support: -#if defined(CATCH_CONFIG_CPP11_NOEXCEPT) && !defined(CATCH_NOEXCEPT) -# define CATCH_NOEXCEPT noexcept -# define CATCH_NOEXCEPT_IS(x) noexcept(x) -#else -# define CATCH_NOEXCEPT throw() -# define CATCH_NOEXCEPT_IS(x) -#endif - -namespace Catch { - - class NonCopyable { -#ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - NonCopyable( NonCopyable const& ) = delete; - NonCopyable( NonCopyable && ) = delete; - NonCopyable& operator = ( NonCopyable const& ) = delete; - NonCopyable& operator = ( NonCopyable && ) = delete; -#else - NonCopyable( NonCopyable const& info ); - NonCopyable& operator = ( NonCopyable const& ); -#endif - - protected: - NonCopyable() {} - virtual ~NonCopyable(); - }; - - class SafeBool { - public: - typedef void (SafeBool::*type)() const; - - static type makeSafe( bool value ) { - return value ? &SafeBool::trueValue : 0; - } - private: - void trueValue() const {} - }; - - template<typename ContainerT> - inline void deleteAll( ContainerT& container ) { - typename ContainerT::const_iterator it = container.begin(); - typename ContainerT::const_iterator itEnd = container.end(); - for(; it != itEnd; ++it ) - delete *it; - } - template<typename AssociativeContainerT> - inline void deleteAllValues( AssociativeContainerT& container ) { - typename AssociativeContainerT::const_iterator it = container.begin(); - typename AssociativeContainerT::const_iterator itEnd = container.end(); - for(; it != itEnd; ++it ) - delete it->second; - } - - bool startsWith( std::string const& s, std::string const& prefix ); - bool endsWith( std::string const& s, std::string const& suffix ); - bool contains( std::string const& s, std::string const& infix ); - void toLowerInPlace( std::string& s ); - std::string toLower( std::string const& s ); - std::string trim( std::string const& str ); - bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ); - - struct pluralise { - pluralise( std::size_t count, std::string const& label ); - - friend std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ); - - std::size_t m_count; - std::string m_label; - }; - - struct SourceLineInfo { - - SourceLineInfo(); - SourceLineInfo( char const* _file, std::size_t _line ); - SourceLineInfo( SourceLineInfo const& other ); -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - SourceLineInfo( SourceLineInfo && ) = default; - SourceLineInfo& operator = ( SourceLineInfo const& ) = default; - SourceLineInfo& operator = ( SourceLineInfo && ) = default; -# endif - bool empty() const; - bool operator == ( SourceLineInfo const& other ) const; - bool operator < ( SourceLineInfo const& other ) const; - - std::string file; - std::size_t line; - }; - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ); - - // This is just here to avoid compiler warnings with macro constants and boolean literals - inline bool isTrue( bool value ){ return value; } - inline bool alwaysTrue() { return true; } - inline bool alwaysFalse() { return false; } - - void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ); - - // Use this in variadic streaming macros to allow - // >> +StreamEndStop - // as well as - // >> stuff +StreamEndStop - struct StreamEndStop { - std::string operator+() { - return std::string(); - } - }; - template<typename T> - T const& operator + ( T const& value, StreamEndStop ) { - return value; - } -} - -#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo( __FILE__, static_cast<std::size_t>( __LINE__ ) ) -#define CATCH_INTERNAL_ERROR( msg ) ::Catch::throwLogicError( msg, CATCH_INTERNAL_LINEINFO ); - -#include <ostream> - -namespace Catch { - - class NotImplementedException : public std::exception - { - public: - NotImplementedException( SourceLineInfo const& lineInfo ); - NotImplementedException( NotImplementedException const& ) {} - - virtual ~NotImplementedException() CATCH_NOEXCEPT {} - - virtual const char* what() const CATCH_NOEXCEPT; - - private: - std::string m_what; - SourceLineInfo m_lineInfo; - }; - -} // end namespace Catch - -/////////////////////////////////////////////////////////////////////////////// -#define CATCH_NOT_IMPLEMENTED throw Catch::NotImplementedException( CATCH_INTERNAL_LINEINFO ) - -// #included from: internal/catch_context.h -#define TWOBLUECUBES_CATCH_CONTEXT_H_INCLUDED - -// #included from: catch_interfaces_generators.h -#define TWOBLUECUBES_CATCH_INTERFACES_GENERATORS_H_INCLUDED - -#include <string> - -namespace Catch { - - struct IGeneratorInfo { - virtual ~IGeneratorInfo(); - virtual bool moveNext() = 0; - virtual std::size_t getCurrentIndex() const = 0; - }; - - struct IGeneratorsForTest { - virtual ~IGeneratorsForTest(); - - virtual IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) = 0; - virtual bool moveNext() = 0; - }; - - IGeneratorsForTest* createGeneratorsForTest(); - -} // end namespace Catch - -// #included from: catch_ptr.hpp -#define TWOBLUECUBES_CATCH_PTR_HPP_INCLUDED - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -namespace Catch { - - // An intrusive reference counting smart pointer. - // T must implement addRef() and release() methods - // typically implementing the IShared interface - template<typename T> - class Ptr { - public: - Ptr() : m_p( NULL ){} - Ptr( T* p ) : m_p( p ){ - if( m_p ) - m_p->addRef(); - } - Ptr( Ptr const& other ) : m_p( other.m_p ){ - if( m_p ) - m_p->addRef(); - } - ~Ptr(){ - if( m_p ) - m_p->release(); - } - void reset() { - if( m_p ) - m_p->release(); - m_p = NULL; - } - Ptr& operator = ( T* p ){ - Ptr temp( p ); - swap( temp ); - return *this; - } - Ptr& operator = ( Ptr const& other ){ - Ptr temp( other ); - swap( temp ); - return *this; - } - void swap( Ptr& other ) { std::swap( m_p, other.m_p ); } - T* get() { return m_p; } - const T* get() const{ return m_p; } - T& operator*() const { return *m_p; } - T* operator->() const { return m_p; } - bool operator !() const { return m_p == NULL; } - operator SafeBool::type() const { return SafeBool::makeSafe( m_p != NULL ); } - - private: - T* m_p; - }; - - struct IShared : NonCopyable { - virtual ~IShared(); - virtual void addRef() const = 0; - virtual void release() const = 0; - }; - - template<typename T = IShared> - struct SharedImpl : T { - - SharedImpl() : m_rc( 0 ){} - - virtual void addRef() const { - ++m_rc; - } - virtual void release() const { - if( --m_rc == 0 ) - delete this; - } - - mutable unsigned int m_rc; - }; - -} // end namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#include <memory> -#include <vector> -#include <stdlib.h> - -namespace Catch { - - class TestCase; - class Stream; - struct IResultCapture; - struct IRunner; - struct IGeneratorsForTest; - struct IConfig; - - struct IContext - { - virtual ~IContext(); - - virtual IResultCapture* getResultCapture() = 0; - virtual IRunner* getRunner() = 0; - virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) = 0; - virtual bool advanceGeneratorsForCurrentTest() = 0; - virtual Ptr<IConfig const> getConfig() const = 0; - }; - - struct IMutableContext : IContext - { - virtual ~IMutableContext(); - virtual void setResultCapture( IResultCapture* resultCapture ) = 0; - virtual void setRunner( IRunner* runner ) = 0; - virtual void setConfig( Ptr<IConfig const> const& config ) = 0; - }; - - IContext& getCurrentContext(); - IMutableContext& getCurrentMutableContext(); - void cleanUpContext(); - Stream createStream( std::string const& streamName ); - -} - -// #included from: internal/catch_test_registry.hpp -#define TWOBLUECUBES_CATCH_TEST_REGISTRY_HPP_INCLUDED - -// #included from: catch_interfaces_testcase.h -#define TWOBLUECUBES_CATCH_INTERFACES_TESTCASE_H_INCLUDED - -#include <vector> - -namespace Catch { - - class TestSpec; - - struct ITestCase : IShared { - virtual void invoke () const = 0; - protected: - virtual ~ITestCase(); - }; - - class TestCase; - struct IConfig; - - struct ITestCaseRegistry { - virtual ~ITestCaseRegistry(); - virtual std::vector<TestCase> const& getAllTests() const = 0; - virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const = 0; - - }; -} - -namespace Catch { - -template<typename C> -class MethodTestCase : public SharedImpl<ITestCase> { - -public: - MethodTestCase( void (C::*method)() ) : m_method( method ) {} - - virtual void invoke() const { - C obj; - (obj.*m_method)(); - } - -private: - virtual ~MethodTestCase() {} - - void (C::*m_method)(); -}; - -typedef void(*TestFunction)(); - -struct NameAndDesc { - NameAndDesc( const char* _name = "", const char* _description= "" ) - : name( _name ), description( _description ) - {} - - const char* name; - const char* description; -}; - -struct AutoReg { - - AutoReg( TestFunction function, - SourceLineInfo const& lineInfo, - NameAndDesc const& nameAndDesc ); - - template<typename C> - AutoReg( void (C::*method)(), - char const* className, - NameAndDesc const& nameAndDesc, - SourceLineInfo const& lineInfo ) { - registerTestCase( new MethodTestCase<C>( method ), - className, - nameAndDesc, - lineInfo ); - } - - void registerTestCase( ITestCase* testCase, - char const* className, - NameAndDesc const& nameAndDesc, - SourceLineInfo const& lineInfo ); - - ~AutoReg(); - -private: - AutoReg( AutoReg const& ); - void operator= ( AutoReg const& ); -}; - -} // end namespace Catch - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TESTCASE( ... ) \ - static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( __VA_ARGS__ ) ); }\ - static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, ... ) \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); } - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, ... )\ - namespace{ \ - struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ - void test(); \ - }; \ - Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( __VA_ARGS__ ), CATCH_INTERNAL_LINEINFO ); \ - } \ - void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() - -#else - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TESTCASE( Name, Desc ) \ - static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )(); \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ), CATCH_INTERNAL_LINEINFO, Catch::NameAndDesc( Name, Desc ) ); }\ - static void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )() - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_METHOD_AS_TEST_CASE( QualifiedMethod, Name, Desc ) \ - namespace{ Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar )( &QualifiedMethod, "&" #QualifiedMethod, Catch::NameAndDesc( Name, Desc ), CATCH_INTERNAL_LINEINFO ); } - - /////////////////////////////////////////////////////////////////////////////// - #define INTERNAL_CATCH_TEST_CASE_METHOD( ClassName, TestName, Desc )\ - namespace{ \ - struct INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ ) : ClassName{ \ - void test(); \ - }; \ - Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME( autoRegistrar ) ( &INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test, #ClassName, Catch::NameAndDesc( TestName, Desc ), CATCH_INTERNAL_LINEINFO ); \ - } \ - void INTERNAL_CATCH_UNIQUE_NAME( ____C_A_T_C_H____T_E_S_T____ )::test() - -#endif - -// #included from: internal/catch_capture.hpp -#define TWOBLUECUBES_CATCH_CAPTURE_HPP_INCLUDED - -// #included from: catch_result_builder.h -#define TWOBLUECUBES_CATCH_RESULT_BUILDER_H_INCLUDED - -// #included from: catch_result_type.h -#define TWOBLUECUBES_CATCH_RESULT_TYPE_H_INCLUDED - -namespace Catch { - - // ResultWas::OfType enum - struct ResultWas { enum OfType { - Unknown = -1, - Ok = 0, - Info = 1, - Warning = 2, - - FailureBit = 0x10, - - ExpressionFailed = FailureBit | 1, - ExplicitFailure = FailureBit | 2, - - Exception = 0x100 | FailureBit, - - ThrewException = Exception | 1, - DidntThrowException = Exception | 2, - - FatalErrorCondition = 0x200 | FailureBit - - }; }; - - inline bool isOk( ResultWas::OfType resultType ) { - return ( resultType & ResultWas::FailureBit ) == 0; - } - inline bool isJustInfo( int flags ) { - return flags == ResultWas::Info; - } - - // ResultDisposition::Flags enum - struct ResultDisposition { enum Flags { - Normal = 0x01, - - ContinueOnFailure = 0x02, // Failures fail test, but execution continues - FalseTest = 0x04, // Prefix expression with ! - SuppressFail = 0x08 // Failures are reported but do not fail the test - }; }; - - inline ResultDisposition::Flags operator | ( ResultDisposition::Flags lhs, ResultDisposition::Flags rhs ) { - return static_cast<ResultDisposition::Flags>( static_cast<int>( lhs ) | static_cast<int>( rhs ) ); - } - - inline bool shouldContinueOnFailure( int flags ) { return ( flags & ResultDisposition::ContinueOnFailure ) != 0; } - inline bool isFalseTest( int flags ) { return ( flags & ResultDisposition::FalseTest ) != 0; } - inline bool shouldSuppressFailure( int flags ) { return ( flags & ResultDisposition::SuppressFail ) != 0; } - -} // end namespace Catch - -// #included from: catch_assertionresult.h -#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_H_INCLUDED - -#include <string> - -namespace Catch { - - struct AssertionInfo - { - AssertionInfo() {} - AssertionInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - std::string const& _capturedExpression, - ResultDisposition::Flags _resultDisposition ); - - std::string macroName; - SourceLineInfo lineInfo; - std::string capturedExpression; - ResultDisposition::Flags resultDisposition; - }; - - struct AssertionResultData - { - AssertionResultData() : resultType( ResultWas::Unknown ) {} - - std::string reconstructedExpression; - std::string message; - ResultWas::OfType resultType; - }; - - class AssertionResult { - public: - AssertionResult(); - AssertionResult( AssertionInfo const& info, AssertionResultData const& data ); - ~AssertionResult(); -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - AssertionResult( AssertionResult const& ) = default; - AssertionResult( AssertionResult && ) = default; - AssertionResult& operator = ( AssertionResult const& ) = default; - AssertionResult& operator = ( AssertionResult && ) = default; -# endif - - bool isOk() const; - bool succeeded() const; - ResultWas::OfType getResultType() const; - bool hasExpression() const; - bool hasMessage() const; - std::string getExpression() const; - std::string getExpressionInMacro() const; - bool hasExpandedExpression() const; - std::string getExpandedExpression() const; - std::string getMessage() const; - SourceLineInfo getSourceInfo() const; - std::string getTestMacroName() const; - - protected: - AssertionInfo m_info; - AssertionResultData m_resultData; - }; - -} // end namespace Catch - -namespace Catch { - - struct TestFailureException{}; - - template<typename T> class ExpressionLhs; - - struct STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison; - - struct CopyableStream { - CopyableStream() {} - CopyableStream( CopyableStream const& other ) { - oss << other.oss.str(); - } - CopyableStream& operator=( CopyableStream const& other ) { - oss.str(""); - oss << other.oss.str(); - return *this; - } - std::ostringstream oss; - }; - - class ResultBuilder { - public: - ResultBuilder( char const* macroName, - SourceLineInfo const& lineInfo, - char const* capturedExpression, - ResultDisposition::Flags resultDisposition ); - - template<typename T> - ExpressionLhs<T const&> operator->* ( T const& operand ); - ExpressionLhs<bool> operator->* ( bool value ); - - template<typename T> - ResultBuilder& operator << ( T const& value ) { - m_stream.oss << value; - return *this; - } - - template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); - template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); - - ResultBuilder& setResultType( ResultWas::OfType result ); - ResultBuilder& setResultType( bool result ); - ResultBuilder& setLhs( std::string const& lhs ); - ResultBuilder& setRhs( std::string const& rhs ); - ResultBuilder& setOp( std::string const& op ); - - void endExpression(); - - std::string reconstructExpression() const; - AssertionResult build() const; - - void useActiveException( ResultDisposition::Flags resultDisposition = ResultDisposition::Normal ); - void captureResult( ResultWas::OfType resultType ); - void captureExpression(); - void react(); - bool shouldDebugBreak() const; - bool allowThrows() const; - - private: - AssertionInfo m_assertionInfo; - AssertionResultData m_data; - struct ExprComponents { - ExprComponents() : testFalse( false ) {} - bool testFalse; - std::string lhs, rhs, op; - } m_exprComponents; - CopyableStream m_stream; - - bool m_shouldDebugBreak; - bool m_shouldThrow; - }; - -} // namespace Catch - -// Include after due to circular dependency: -// #included from: catch_expression_lhs.hpp -#define TWOBLUECUBES_CATCH_EXPRESSION_LHS_HPP_INCLUDED - -// #included from: catch_evaluate.hpp -#define TWOBLUECUBES_CATCH_EVALUATE_HPP_INCLUDED - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable:4389) // '==' : signed/unsigned mismatch -#endif - -#include <cstddef> - -namespace Catch { -namespace Internal { - - enum Operator { - IsEqualTo, - IsNotEqualTo, - IsLessThan, - IsGreaterThan, - IsLessThanOrEqualTo, - IsGreaterThanOrEqualTo - }; - - template<Operator Op> struct OperatorTraits { static const char* getName(){ return "*error*"; } }; - template<> struct OperatorTraits<IsEqualTo> { static const char* getName(){ return "=="; } }; - template<> struct OperatorTraits<IsNotEqualTo> { static const char* getName(){ return "!="; } }; - template<> struct OperatorTraits<IsLessThan> { static const char* getName(){ return "<"; } }; - template<> struct OperatorTraits<IsGreaterThan> { static const char* getName(){ return ">"; } }; - template<> struct OperatorTraits<IsLessThanOrEqualTo> { static const char* getName(){ return "<="; } }; - template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } }; - - template<typename T> - inline T& opCast(T const& t) { return const_cast<T&>(t); } - -// nullptr_t support based on pull request #154 from Konstantin Baumann -#ifdef CATCH_CONFIG_CPP11_NULLPTR - inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } -#endif // CATCH_CONFIG_CPP11_NULLPTR - - // So the compare overloads can be operator agnostic we convey the operator as a template - // enum, which is used to specialise an Evaluator for doing the comparison. - template<typename T1, typename T2, Operator Op> - class Evaluator{}; - - template<typename T1, typename T2> - struct Evaluator<T1, T2, IsEqualTo> { - static bool evaluate( T1 const& lhs, T2 const& rhs) { - return opCast( lhs ) == opCast( rhs ); - } - }; - template<typename T1, typename T2> - struct Evaluator<T1, T2, IsNotEqualTo> { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) != opCast( rhs ); - } - }; - template<typename T1, typename T2> - struct Evaluator<T1, T2, IsLessThan> { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) < opCast( rhs ); - } - }; - template<typename T1, typename T2> - struct Evaluator<T1, T2, IsGreaterThan> { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) > opCast( rhs ); - } - }; - template<typename T1, typename T2> - struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) >= opCast( rhs ); - } - }; - template<typename T1, typename T2> - struct Evaluator<T1, T2, IsLessThanOrEqualTo> { - static bool evaluate( T1 const& lhs, T2 const& rhs ) { - return opCast( lhs ) <= opCast( rhs ); - } - }; - - template<Operator Op, typename T1, typename T2> - bool applyEvaluator( T1 const& lhs, T2 const& rhs ) { - return Evaluator<T1, T2, Op>::evaluate( lhs, rhs ); - } - - // This level of indirection allows us to specialise for integer types - // to avoid signed/ unsigned warnings - - // "base" overload - template<Operator Op, typename T1, typename T2> - bool compare( T1 const& lhs, T2 const& rhs ) { - return Evaluator<T1, T2, Op>::evaluate( lhs, rhs ); - } - - // unsigned X to int - template<Operator Op> bool compare( unsigned int lhs, int rhs ) { - return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); - } - template<Operator Op> bool compare( unsigned long lhs, int rhs ) { - return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); - } - template<Operator Op> bool compare( unsigned char lhs, int rhs ) { - return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) ); - } - - // unsigned X to long - template<Operator Op> bool compare( unsigned int lhs, long rhs ) { - return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) ); - } - template<Operator Op> bool compare( unsigned long lhs, long rhs ) { - return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) ); - } - template<Operator Op> bool compare( unsigned char lhs, long rhs ) { - return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) ); - } - - // int to unsigned X - template<Operator Op> bool compare( int lhs, unsigned int rhs ) { - return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs ); - } - template<Operator Op> bool compare( int lhs, unsigned long rhs ) { - return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs ); - } - template<Operator Op> bool compare( int lhs, unsigned char rhs ) { - return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs ); - } - - // long to unsigned X - template<Operator Op> bool compare( long lhs, unsigned int rhs ) { - return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); - } - template<Operator Op> bool compare( long lhs, unsigned long rhs ) { - return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); - } - template<Operator Op> bool compare( long lhs, unsigned char rhs ) { - return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs ); - } - - // pointer to long (when comparing against NULL) - template<Operator Op, typename T> bool compare( long lhs, T* rhs ) { - return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs ); - } - template<Operator Op, typename T> bool compare( T* lhs, long rhs ) { - return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); - } - - // pointer to int (when comparing against NULL) - template<Operator Op, typename T> bool compare( int lhs, T* rhs ) { - return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs ); - } - template<Operator Op, typename T> bool compare( T* lhs, int rhs ) { - return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) ); - } - -#ifdef CATCH_CONFIG_CPP11_NULLPTR - // pointer to nullptr_t (when comparing against nullptr) - template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) { - return Evaluator<T*, T*, Op>::evaluate( NULL, rhs ); - } - template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) { - return Evaluator<T*, T*, Op>::evaluate( lhs, NULL ); - } -#endif // CATCH_CONFIG_CPP11_NULLPTR - -} // end of namespace Internal -} // end of namespace Catch - -#ifdef _MSC_VER -#pragma warning(pop) -#endif - -// #included from: catch_tostring.h -#define TWOBLUECUBES_CATCH_TOSTRING_H_INCLUDED - -// #included from: catch_sfinae.hpp -#define TWOBLUECUBES_CATCH_SFINAE_HPP_INCLUDED - -// Try to detect if the current compiler supports SFINAE - -namespace Catch { - - struct TrueType { - static const bool value = true; - typedef void Enable; - char sizer[1]; - }; - struct FalseType { - static const bool value = false; - typedef void Disable; - char sizer[2]; - }; - -#ifdef CATCH_CONFIG_SFINAE - - template<bool> struct NotABooleanExpression; - - template<bool c> struct If : NotABooleanExpression<c> {}; - template<> struct If<true> : TrueType {}; - template<> struct If<false> : FalseType {}; - - template<int size> struct SizedIf; - template<> struct SizedIf<sizeof(TrueType)> : TrueType {}; - template<> struct SizedIf<sizeof(FalseType)> : FalseType {}; - -#endif // CATCH_CONFIG_SFINAE - -} // end namespace Catch - -#include <sstream> -#include <iomanip> -#include <limits> -#include <vector> -#include <cstddef> - -#ifdef __OBJC__ -// #included from: catch_objc_arc.hpp -#define TWOBLUECUBES_CATCH_OBJC_ARC_HPP_INCLUDED - -#import <Foundation/Foundation.h> - -#ifdef __has_feature -#define CATCH_ARC_ENABLED __has_feature(objc_arc) -#else -#define CATCH_ARC_ENABLED 0 -#endif - -void arcSafeRelease( NSObject* obj ); -id performOptionalSelector( id obj, SEL sel ); - -#if !CATCH_ARC_ENABLED -inline void arcSafeRelease( NSObject* obj ) { - [obj release]; -} -inline id performOptionalSelector( id obj, SEL sel ) { - if( [obj respondsToSelector: sel] ) - return [obj performSelector: sel]; - return nil; -} -#define CATCH_UNSAFE_UNRETAINED -#define CATCH_ARC_STRONG -#else -inline void arcSafeRelease( NSObject* ){} -inline id performOptionalSelector( id obj, SEL sel ) { -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Warc-performSelector-leaks" -#endif - if( [obj respondsToSelector: sel] ) - return [obj performSelector: sel]; -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - return nil; -} -#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained -#define CATCH_ARC_STRONG __strong -#endif - -#endif - -#ifdef CATCH_CONFIG_CPP11_TUPLE -#include <tuple> -#endif - -#ifdef CATCH_CONFIG_CPP11_IS_ENUM -#include <type_traits> -#endif - -namespace Catch { - -// Why we're here. -template<typename T> -std::string toString( T const& value ); - -// Built in overloads - -std::string toString( std::string const& value ); -std::string toString( std::wstring const& value ); -std::string toString( const char* const value ); -std::string toString( char* const value ); -std::string toString( const wchar_t* const value ); -std::string toString( wchar_t* const value ); -std::string toString( int value ); -std::string toString( unsigned long value ); -std::string toString( unsigned int value ); -std::string toString( const double value ); -std::string toString( const float value ); -std::string toString( bool value ); -std::string toString( char value ); -std::string toString( signed char value ); -std::string toString( unsigned char value ); - -#ifdef CATCH_CONFIG_CPP11_NULLPTR -std::string toString( std::nullptr_t ); -#endif - -#ifdef __OBJC__ - std::string toString( NSString const * const& nsstring ); - std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ); - std::string toString( NSObject* const& nsObject ); -#endif - -namespace Detail { - - extern std::string unprintableString; - -// SFINAE is currently disabled by default for all compilers. -// If the non SFINAE version of IsStreamInsertable is ambiguous for you -// and your compiler supports SFINAE, try #defining CATCH_CONFIG_SFINAE -#ifdef CATCH_CONFIG_SFINAE - - template<typename T> - class IsStreamInsertableHelper { - template<int N> struct TrueIfSizeable : TrueType {}; - - template<typename T2> - static TrueIfSizeable<sizeof((*(std::ostream*)0) << *((T2 const*)0))> dummy(T2*); - static FalseType dummy(...); - - public: - typedef SizedIf<sizeof(dummy((T*)0))> type; - }; - - template<typename T> - struct IsStreamInsertable : IsStreamInsertableHelper<T>::type {}; - -#else - - struct BorgType { - template<typename T> BorgType( T const& ); - }; - - TrueType& testStreamable( std::ostream& ); - FalseType testStreamable( FalseType ); - - FalseType operator<<( std::ostream const&, BorgType const& ); - - template<typename T> - struct IsStreamInsertable { - static std::ostream &s; - static T const&t; - enum { value = sizeof( testStreamable(s << t) ) == sizeof( TrueType ) }; - }; - -#endif - -#if defined(CATCH_CONFIG_CPP11_IS_ENUM) - template<typename T, - bool IsEnum = std::is_enum<T>::value - > - struct EnumStringMaker - { - static std::string convert( T const& ) { return unprintableString; } - }; - - template<typename T> - struct EnumStringMaker<T,true> - { - static std::string convert( T const& v ) - { - return ::Catch::toString( - static_cast<typename std::underlying_type<T>::type>(v) - ); - } - }; -#endif - template<bool C> - struct StringMakerBase { -#if defined(CATCH_CONFIG_CPP11_IS_ENUM) - template<typename T> - static std::string convert( T const& v ) - { - return EnumStringMaker<T>::convert( v ); - } -#else - template<typename T> - static std::string convert( T const& ) { return unprintableString; } -#endif - }; - - template<> - struct StringMakerBase<true> { - template<typename T> - static std::string convert( T const& _value ) { - std::ostringstream oss; - oss << _value; - return oss.str(); - } - }; - - std::string rawMemoryToString( const void *object, std::size_t size ); - - template<typename T> - inline std::string rawMemoryToString( const T& object ) { - return rawMemoryToString( &object, sizeof(object) ); - } - -} // end namespace Detail - -template<typename T> -struct StringMaker : - Detail::StringMakerBase<Detail::IsStreamInsertable<T>::value> {}; - -template<typename T> -struct StringMaker<T*> { - template<typename U> - static std::string convert( U* p ) { - if( !p ) - return INTERNAL_CATCH_STRINGIFY( NULL ); - else - return Detail::rawMemoryToString( p ); - } -}; - -template<typename R, typename C> -struct StringMaker<R C::*> { - static std::string convert( R C::* p ) { - if( !p ) - return INTERNAL_CATCH_STRINGIFY( NULL ); - else - return Detail::rawMemoryToString( p ); - } -}; - -namespace Detail { - template<typename InputIterator> - std::string rangeToString( InputIterator first, InputIterator last ); -} - -//template<typename T, typename Allocator> -//struct StringMaker<std::vector<T, Allocator> > { -// static std::string convert( std::vector<T,Allocator> const& v ) { -// return Detail::rangeToString( v.begin(), v.end() ); -// } -//}; - -template<typename T, typename Allocator> -std::string toString( std::vector<T,Allocator> const& v ) { - return Detail::rangeToString( v.begin(), v.end() ); -} - -#ifdef CATCH_CONFIG_CPP11_TUPLE - -// toString for tuples -namespace TupleDetail { - template< - typename Tuple, - std::size_t N = 0, - bool = (N < std::tuple_size<Tuple>::value) - > - struct ElementPrinter { - static void print( const Tuple& tuple, std::ostream& os ) - { - os << ( N ? ", " : " " ) - << Catch::toString(std::get<N>(tuple)); - ElementPrinter<Tuple,N+1>::print(tuple,os); - } - }; - - template< - typename Tuple, - std::size_t N - > - struct ElementPrinter<Tuple,N,false> { - static void print( const Tuple&, std::ostream& ) {} - }; - -} - -template<typename ...Types> -struct StringMaker<std::tuple<Types...>> { - - static std::string convert( const std::tuple<Types...>& tuple ) - { - std::ostringstream os; - os << '{'; - TupleDetail::ElementPrinter<std::tuple<Types...>>::print( tuple, os ); - os << " }"; - return os.str(); - } -}; -#endif // CATCH_CONFIG_CPP11_TUPLE - -namespace Detail { - template<typename T> - std::string makeString( T const& value ) { - return StringMaker<T>::convert( value ); - } -} // end namespace Detail - -/// \brief converts any type to a string -/// -/// The default template forwards on to ostringstream - except when an -/// ostringstream overload does not exist - in which case it attempts to detect -/// that and writes {?}. -/// Overload (not specialise) this template for custom typs that you don't want -/// to provide an ostream overload for. -template<typename T> -std::string toString( T const& value ) { - return StringMaker<T>::convert( value ); -} - - namespace Detail { - template<typename InputIterator> - std::string rangeToString( InputIterator first, InputIterator last ) { - std::ostringstream oss; - oss << "{ "; - if( first != last ) { - oss << Catch::toString( *first ); - for( ++first ; first != last ; ++first ) - oss << ", " << Catch::toString( *first ); - } - oss << " }"; - return oss.str(); - } -} - -} // end namespace Catch - -namespace Catch { - -// Wraps the LHS of an expression and captures the operator and RHS (if any) - -// wrapping them all in a ResultBuilder object -template<typename T> -class ExpressionLhs { - ExpressionLhs& operator = ( ExpressionLhs const& ); -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - ExpressionLhs& operator = ( ExpressionLhs && ) = delete; -# endif - -public: - ExpressionLhs( ResultBuilder& rb, T lhs ) : m_rb( rb ), m_lhs( lhs ) {} -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - ExpressionLhs( ExpressionLhs const& ) = default; - ExpressionLhs( ExpressionLhs && ) = default; -# endif - - template<typename RhsT> - ResultBuilder& operator == ( RhsT const& rhs ) { - return captureExpression<Internal::IsEqualTo>( rhs ); - } - - template<typename RhsT> - ResultBuilder& operator != ( RhsT const& rhs ) { - return captureExpression<Internal::IsNotEqualTo>( rhs ); - } - - template<typename RhsT> - ResultBuilder& operator < ( RhsT const& rhs ) { - return captureExpression<Internal::IsLessThan>( rhs ); - } - - template<typename RhsT> - ResultBuilder& operator > ( RhsT const& rhs ) { - return captureExpression<Internal::IsGreaterThan>( rhs ); - } - - template<typename RhsT> - ResultBuilder& operator <= ( RhsT const& rhs ) { - return captureExpression<Internal::IsLessThanOrEqualTo>( rhs ); - } - - template<typename RhsT> - ResultBuilder& operator >= ( RhsT const& rhs ) { - return captureExpression<Internal::IsGreaterThanOrEqualTo>( rhs ); - } - - ResultBuilder& operator == ( bool rhs ) { - return captureExpression<Internal::IsEqualTo>( rhs ); - } - - ResultBuilder& operator != ( bool rhs ) { - return captureExpression<Internal::IsNotEqualTo>( rhs ); - } - - void endExpression() { - bool value = m_lhs ? true : false; - m_rb - .setLhs( Catch::toString( value ) ) - .setResultType( value ) - .endExpression(); - } - - // Only simple binary expressions are allowed on the LHS. - // If more complex compositions are required then place the sub expression in parentheses - template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator + ( RhsT const& ); - template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator - ( RhsT const& ); - template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator / ( RhsT const& ); - template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator * ( RhsT const& ); - template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator && ( RhsT const& ); - template<typename RhsT> STATIC_ASSERT_Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison& operator || ( RhsT const& ); - -private: - template<Internal::Operator Op, typename RhsT> - ResultBuilder& captureExpression( RhsT const& rhs ) { - return m_rb - .setResultType( Internal::compare<Op>( m_lhs, rhs ) ) - .setLhs( Catch::toString( m_lhs ) ) - .setRhs( Catch::toString( rhs ) ) - .setOp( Internal::OperatorTraits<Op>::getName() ); - } - -private: - ResultBuilder& m_rb; - T m_lhs; -}; - -} // end namespace Catch - - -namespace Catch { - - template<typename T> - inline ExpressionLhs<T const&> ResultBuilder::operator->* ( T const& operand ) { - return ExpressionLhs<T const&>( *this, operand ); - } - - inline ExpressionLhs<bool> ResultBuilder::operator->* ( bool value ) { - return ExpressionLhs<bool>( *this, value ); - } - -} // namespace Catch - -// #included from: catch_message.h -#define TWOBLUECUBES_CATCH_MESSAGE_H_INCLUDED - -#include <string> - -namespace Catch { - - struct MessageInfo { - MessageInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - ResultWas::OfType _type ); - - std::string macroName; - SourceLineInfo lineInfo; - ResultWas::OfType type; - std::string message; - unsigned int sequence; - - bool operator == ( MessageInfo const& other ) const { - return sequence == other.sequence; - } - bool operator < ( MessageInfo const& other ) const { - return sequence < other.sequence; - } - private: - static unsigned int globalCount; - }; - - struct MessageBuilder { - MessageBuilder( std::string const& macroName, - SourceLineInfo const& lineInfo, - ResultWas::OfType type ) - : m_info( macroName, lineInfo, type ) - {} - - template<typename T> - MessageBuilder& operator << ( T const& value ) { - m_stream << value; - return *this; - } - - MessageInfo m_info; - std::ostringstream m_stream; - }; - - class ScopedMessage { - public: - ScopedMessage( MessageBuilder const& builder ); - ScopedMessage( ScopedMessage const& other ); - ~ScopedMessage(); - - MessageInfo m_info; - }; - -} // end namespace Catch - -// #included from: catch_interfaces_capture.h -#define TWOBLUECUBES_CATCH_INTERFACES_CAPTURE_H_INCLUDED - -#include <string> - -namespace Catch { - - class TestCase; - class AssertionResult; - struct AssertionInfo; - struct SectionInfo; - struct MessageInfo; - class ScopedMessageBuilder; - struct Counts; - - struct IResultCapture { - - virtual ~IResultCapture(); - - virtual void assertionEnded( AssertionResult const& result ) = 0; - virtual bool sectionStarted( SectionInfo const& sectionInfo, - Counts& assertions ) = 0; - virtual void sectionEnded( SectionInfo const& name, Counts const& assertions, double _durationInSeconds ) = 0; - virtual void pushScopedMessage( MessageInfo const& message ) = 0; - virtual void popScopedMessage( MessageInfo const& message ) = 0; - - virtual std::string getCurrentTestName() const = 0; - virtual const AssertionResult* getLastResult() const = 0; - - virtual void handleFatalErrorCondition( std::string const& message ) = 0; - }; - - IResultCapture& getResultCapture(); -} - -// #included from: catch_debugger.h -#define TWOBLUECUBES_CATCH_DEBUGGER_H_INCLUDED - -// #included from: catch_platform.h -#define TWOBLUECUBES_CATCH_PLATFORM_H_INCLUDED - -#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) -#define CATCH_PLATFORM_MAC -#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) -#define CATCH_PLATFORM_IPHONE -#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) -#define CATCH_PLATFORM_WINDOWS -#endif - -#include <csignal> -#include <string> - -namespace Catch{ - - bool isDebuggerActive(); - void writeToDebugConsole( std::string const& text ); -} - -#ifdef CATCH_PLATFORM_MAC - - // The following code snippet based on: - // http://cocoawithlove.com/2008/03/break-into-debugger.html - #ifdef DEBUG - #if defined(__ppc64__) || defined(__ppc__) - #define CATCH_BREAK_INTO_DEBUGGER() \ - if( Catch::isDebuggerActive() ) { \ - __asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \ - : : : "memory","r0","r3","r4" ); \ - } - #else - #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) {__asm__("int $3\n" : : );} - #endif - #endif - -#elif defined(_MSC_VER) - #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { __debugbreak(); } -#elif defined(__MINGW32__) - extern "C" __declspec(dllimport) void __stdcall DebugBreak(); - #define CATCH_BREAK_INTO_DEBUGGER() if( Catch::isDebuggerActive() ) { DebugBreak(); } -#else - #define CATCH_BREAK_INTO_DEBUGGER() raise(SIGTRAP); -#endif - -#ifndef CATCH_BREAK_INTO_DEBUGGER -#define CATCH_BREAK_INTO_DEBUGGER() Catch::alwaysTrue(); -#endif - -// #included from: catch_interfaces_runner.h -#define TWOBLUECUBES_CATCH_INTERFACES_RUNNER_H_INCLUDED - -namespace Catch { - class TestCase; - - struct IRunner { - virtual ~IRunner(); - virtual bool aborting() const = 0; - }; -} - -/////////////////////////////////////////////////////////////////////////////// -// In the event of a failure works out if the debugger needs to be invoked -// and/or an exception thrown and takes appropriate action. -// This needs to be done as a macro so the debugger will stop in the user -// source code rather than in Catch library code -#define INTERNAL_CATCH_REACT( resultBuilder ) \ - if( resultBuilder.shouldDebugBreak() ) CATCH_BREAK_INTO_DEBUGGER(); \ - resultBuilder.react(); - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ - try { \ - ( __catchResult->*expr ).endExpression(); \ - } \ - catch( ... ) { \ - __catchResult.useActiveException( Catch::ResultDisposition::Normal ); \ - } \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::isTrue( false && (expr) ) ) // expr here is never evaluated at runtime but it forces the compiler to give it a look - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_IF( expr, resultDisposition, macroName ) \ - INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ - if( Catch::getResultCapture().getLastResult()->succeeded() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_ELSE( expr, resultDisposition, macroName ) \ - INTERNAL_CATCH_TEST( expr, resultDisposition, macroName ); \ - if( !Catch::getResultCapture().getLastResult()->succeeded() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_NO_THROW( expr, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ - try { \ - expr; \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - } \ - catch( ... ) { \ - __catchResult.useActiveException( resultDisposition ); \ - } \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_THROWS( expr, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ - if( __catchResult.allowThrows() ) \ - try { \ - expr; \ - __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ - } \ - catch( ... ) { \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - } \ - else \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_THROWS_AS( expr, exceptionType, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #expr, resultDisposition ); \ - if( __catchResult.allowThrows() ) \ - try { \ - expr; \ - __catchResult.captureResult( Catch::ResultWas::DidntThrowException ); \ - } \ - catch( exceptionType ) { \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - } \ - catch( ... ) { \ - __catchResult.useActiveException( resultDisposition ); \ - } \ - else \ - __catchResult.captureResult( Catch::ResultWas::Ok ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -/////////////////////////////////////////////////////////////////////////////// -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, ... ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ - __catchResult << __VA_ARGS__ + ::Catch::StreamEndStop(); \ - __catchResult.captureResult( messageType ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) -#else - #define INTERNAL_CATCH_MSG( messageType, resultDisposition, macroName, log ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition ); \ - __catchResult << log + ::Catch::StreamEndStop(); \ - __catchResult.captureResult( messageType ); \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) -#endif - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_INFO( log, macroName ) \ - Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME( scopedMessage ) = Catch::MessageBuilder( macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info ) << log; - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CHECK_THAT( arg, matcher, resultDisposition, macroName ) \ - do { \ - Catch::ResultBuilder __catchResult( macroName, CATCH_INTERNAL_LINEINFO, #arg " " #matcher, resultDisposition ); \ - try { \ - std::string matcherAsString = ::Catch::Matchers::matcher.toString(); \ - __catchResult \ - .setLhs( Catch::toString( arg ) ) \ - .setRhs( matcherAsString == Catch::Detail::unprintableString ? #matcher : matcherAsString ) \ - .setOp( "matches" ) \ - .setResultType( ::Catch::Matchers::matcher.match( arg ) ); \ - __catchResult.captureExpression(); \ - } catch( ... ) { \ - __catchResult.useActiveException( resultDisposition | Catch::ResultDisposition::ContinueOnFailure ); \ - } \ - INTERNAL_CATCH_REACT( __catchResult ) \ - } while( Catch::alwaysFalse() ) - -// #included from: internal/catch_section.h -#define TWOBLUECUBES_CATCH_SECTION_H_INCLUDED - -// #included from: catch_section_info.h -#define TWOBLUECUBES_CATCH_SECTION_INFO_H_INCLUDED - -namespace Catch { - - struct SectionInfo { - SectionInfo - ( SourceLineInfo const& _lineInfo, - std::string const& _name, - std::string const& _description = std::string() ); - - std::string name; - std::string description; - SourceLineInfo lineInfo; - }; - -} // end namespace Catch - -// #included from: catch_totals.hpp -#define TWOBLUECUBES_CATCH_TOTALS_HPP_INCLUDED - -#include <cstddef> - -namespace Catch { - - struct Counts { - Counts() : passed( 0 ), failed( 0 ), failedButOk( 0 ) {} - - Counts operator - ( Counts const& other ) const { - Counts diff; - diff.passed = passed - other.passed; - diff.failed = failed - other.failed; - diff.failedButOk = failedButOk - other.failedButOk; - return diff; - } - Counts& operator += ( Counts const& other ) { - passed += other.passed; - failed += other.failed; - failedButOk += other.failedButOk; - return *this; - } - - std::size_t total() const { - return passed + failed + failedButOk; - } - bool allPassed() const { - return failed == 0 && failedButOk == 0; - } - bool allOk() const { - return failed == 0; - } - - std::size_t passed; - std::size_t failed; - std::size_t failedButOk; - }; - - struct Totals { - - Totals operator - ( Totals const& other ) const { - Totals diff; - diff.assertions = assertions - other.assertions; - diff.testCases = testCases - other.testCases; - return diff; - } - - Totals delta( Totals const& prevTotals ) const { - Totals diff = *this - prevTotals; - if( diff.assertions.failed > 0 ) - ++diff.testCases.failed; - else if( diff.assertions.failedButOk > 0 ) - ++diff.testCases.failedButOk; - else - ++diff.testCases.passed; - return diff; - } - - Totals& operator += ( Totals const& other ) { - assertions += other.assertions; - testCases += other.testCases; - return *this; - } - - Counts assertions; - Counts testCases; - }; -} - -// #included from: catch_timer.h -#define TWOBLUECUBES_CATCH_TIMER_H_INCLUDED - -#ifdef CATCH_PLATFORM_WINDOWS -typedef unsigned long long uint64_t; -#else -#include <stdint.h> -#endif - -namespace Catch { - - class Timer { - public: - Timer() : m_ticks( 0 ) {} - void start(); - unsigned int getElapsedMicroseconds() const; - unsigned int getElapsedMilliseconds() const; - double getElapsedSeconds() const; - - private: - uint64_t m_ticks; - }; - -} // namespace Catch - -#include <string> - -namespace Catch { - - class Section : NonCopyable { - public: - Section( SectionInfo const& info ); - ~Section(); - - // This indicates whether the section should be executed or not - operator bool() const; - - private: - SectionInfo m_info; - - std::string m_name; - Counts m_assertions; - bool m_sectionIncluded; - Timer m_timer; - }; - -} // end namespace Catch - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define INTERNAL_CATCH_SECTION( ... ) \ - if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, __VA_ARGS__ ) ) -#else - #define INTERNAL_CATCH_SECTION( name, desc ) \ - if( Catch::Section const& INTERNAL_CATCH_UNIQUE_NAME( catch_internal_Section ) = Catch::SectionInfo( CATCH_INTERNAL_LINEINFO, name, desc ) ) -#endif - -// #included from: internal/catch_generators.hpp -#define TWOBLUECUBES_CATCH_GENERATORS_HPP_INCLUDED - -#include <iterator> -#include <vector> -#include <string> -#include <stdlib.h> - -namespace Catch { - -template<typename T> -struct IGenerator { - virtual ~IGenerator() {} - virtual T getValue( std::size_t index ) const = 0; - virtual std::size_t size () const = 0; -}; - -template<typename T> -class BetweenGenerator : public IGenerator<T> { -public: - BetweenGenerator( T from, T to ) : m_from( from ), m_to( to ){} - - virtual T getValue( std::size_t index ) const { - return m_from+static_cast<int>( index ); - } - - virtual std::size_t size() const { - return static_cast<std::size_t>( 1+m_to-m_from ); - } - -private: - - T m_from; - T m_to; -}; - -template<typename T> -class ValuesGenerator : public IGenerator<T> { -public: - ValuesGenerator(){} - - void add( T value ) { - m_values.push_back( value ); - } - - virtual T getValue( std::size_t index ) const { - return m_values[index]; - } - - virtual std::size_t size() const { - return m_values.size(); - } - -private: - std::vector<T> m_values; -}; - -template<typename T> -class CompositeGenerator { -public: - CompositeGenerator() : m_totalSize( 0 ) {} - - // *** Move semantics, similar to auto_ptr *** - CompositeGenerator( CompositeGenerator& other ) - : m_fileInfo( other.m_fileInfo ), - m_totalSize( 0 ) - { - move( other ); - } - - CompositeGenerator& setFileInfo( const char* fileInfo ) { - m_fileInfo = fileInfo; - return *this; - } - - ~CompositeGenerator() { - deleteAll( m_composed ); - } - - operator T () const { - size_t overallIndex = getCurrentContext().getGeneratorIndex( m_fileInfo, m_totalSize ); - - typename std::vector<const IGenerator<T>*>::const_iterator it = m_composed.begin(); - typename std::vector<const IGenerator<T>*>::const_iterator itEnd = m_composed.end(); - for( size_t index = 0; it != itEnd; ++it ) - { - const IGenerator<T>* generator = *it; - if( overallIndex >= index && overallIndex < index + generator->size() ) - { - return generator->getValue( overallIndex-index ); - } - index += generator->size(); - } - CATCH_INTERNAL_ERROR( "Indexed past end of generated range" ); - return T(); // Suppress spurious "not all control paths return a value" warning in Visual Studio - if you know how to fix this please do so - } - - void add( const IGenerator<T>* generator ) { - m_totalSize += generator->size(); - m_composed.push_back( generator ); - } - - CompositeGenerator& then( CompositeGenerator& other ) { - move( other ); - return *this; - } - - CompositeGenerator& then( T value ) { - ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); - valuesGen->add( value ); - add( valuesGen ); - return *this; - } - -private: - - void move( CompositeGenerator& other ) { - std::copy( other.m_composed.begin(), other.m_composed.end(), std::back_inserter( m_composed ) ); - m_totalSize += other.m_totalSize; - other.m_composed.clear(); - } - - std::vector<const IGenerator<T>*> m_composed; - std::string m_fileInfo; - size_t m_totalSize; -}; - -namespace Generators -{ - template<typename T> - CompositeGenerator<T> between( T from, T to ) { - CompositeGenerator<T> generators; - generators.add( new BetweenGenerator<T>( from, to ) ); - return generators; - } - - template<typename T> - CompositeGenerator<T> values( T val1, T val2 ) { - CompositeGenerator<T> generators; - ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); - valuesGen->add( val1 ); - valuesGen->add( val2 ); - generators.add( valuesGen ); - return generators; - } - - template<typename T> - CompositeGenerator<T> values( T val1, T val2, T val3 ){ - CompositeGenerator<T> generators; - ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); - valuesGen->add( val1 ); - valuesGen->add( val2 ); - valuesGen->add( val3 ); - generators.add( valuesGen ); - return generators; - } - - template<typename T> - CompositeGenerator<T> values( T val1, T val2, T val3, T val4 ) { - CompositeGenerator<T> generators; - ValuesGenerator<T>* valuesGen = new ValuesGenerator<T>(); - valuesGen->add( val1 ); - valuesGen->add( val2 ); - valuesGen->add( val3 ); - valuesGen->add( val4 ); - generators.add( valuesGen ); - return generators; - } - -} // end namespace Generators - -using namespace Generators; - -} // end namespace Catch - -#define INTERNAL_CATCH_LINESTR2( line ) #line -#define INTERNAL_CATCH_LINESTR( line ) INTERNAL_CATCH_LINESTR2( line ) - -#define INTERNAL_CATCH_GENERATE( expr ) expr.setFileInfo( __FILE__ "(" INTERNAL_CATCH_LINESTR( __LINE__ ) ")" ) - -// #included from: internal/catch_interfaces_exception.h -#define TWOBLUECUBES_CATCH_INTERFACES_EXCEPTION_H_INCLUDED - -#include <string> -// #included from: catch_interfaces_registry_hub.h -#define TWOBLUECUBES_CATCH_INTERFACES_REGISTRY_HUB_H_INCLUDED - -#include <string> - -namespace Catch { - - class TestCase; - struct ITestCaseRegistry; - struct IExceptionTranslatorRegistry; - struct IExceptionTranslator; - struct IReporterRegistry; - struct IReporterFactory; - - struct IRegistryHub { - virtual ~IRegistryHub(); - - virtual IReporterRegistry const& getReporterRegistry() const = 0; - virtual ITestCaseRegistry const& getTestCaseRegistry() const = 0; - virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() = 0; - }; - - struct IMutableRegistryHub { - virtual ~IMutableRegistryHub(); - virtual void registerReporter( std::string const& name, IReporterFactory* factory ) = 0; - virtual void registerTest( TestCase const& testInfo ) = 0; - virtual void registerTranslator( const IExceptionTranslator* translator ) = 0; - }; - - IRegistryHub& getRegistryHub(); - IMutableRegistryHub& getMutableRegistryHub(); - void cleanUp(); - std::string translateActiveException(); - -} - - -namespace Catch { - - typedef std::string(*exceptionTranslateFunction)(); - - struct IExceptionTranslator { - virtual ~IExceptionTranslator(); - virtual std::string translate() const = 0; - }; - - struct IExceptionTranslatorRegistry { - virtual ~IExceptionTranslatorRegistry(); - - virtual std::string translateActiveException() const = 0; - }; - - class ExceptionTranslatorRegistrar { - template<typename T> - class ExceptionTranslator : public IExceptionTranslator { - public: - - ExceptionTranslator( std::string(*translateFunction)( T& ) ) - : m_translateFunction( translateFunction ) - {} - - virtual std::string translate() const { - try { - throw; - } - catch( T& ex ) { - return m_translateFunction( ex ); - } - } - - protected: - std::string(*m_translateFunction)( T& ); - }; - - public: - template<typename T> - ExceptionTranslatorRegistrar( std::string(*translateFunction)( T& ) ) { - getMutableRegistryHub().registerTranslator - ( new ExceptionTranslator<T>( translateFunction ) ); - } - }; -} - -/////////////////////////////////////////////////////////////////////////////// -#define INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) \ - static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ); \ - namespace{ Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionRegistrar )( &INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator ) ); }\ - static std::string INTERNAL_CATCH_UNIQUE_NAME( catch_internal_ExceptionTranslator )( signature ) - -// #included from: internal/catch_approx.hpp -#define TWOBLUECUBES_CATCH_APPROX_HPP_INCLUDED - -#include <cmath> -#include <limits> - -namespace Catch { -namespace Detail { - - class Approx { - public: - explicit Approx ( double value ) - : m_epsilon( std::numeric_limits<float>::epsilon()*100 ), - m_scale( 1.0 ), - m_value( value ) - {} - - Approx( Approx const& other ) - : m_epsilon( other.m_epsilon ), - m_scale( other.m_scale ), - m_value( other.m_value ) - {} - - static Approx custom() { - return Approx( 0 ); - } - - Approx operator()( double value ) { - Approx approx( value ); - approx.epsilon( m_epsilon ); - approx.scale( m_scale ); - return approx; - } - - friend bool operator == ( double lhs, Approx const& rhs ) { - // Thanks to Richard Harris for his help refining this formula - return fabs( lhs - rhs.m_value ) < rhs.m_epsilon * (rhs.m_scale + (std::max)( fabs(lhs), fabs(rhs.m_value) ) ); - } - - friend bool operator == ( Approx const& lhs, double rhs ) { - return operator==( rhs, lhs ); - } - - friend bool operator != ( double lhs, Approx const& rhs ) { - return !operator==( lhs, rhs ); - } - - friend bool operator != ( Approx const& lhs, double rhs ) { - return !operator==( rhs, lhs ); - } - - Approx& epsilon( double newEpsilon ) { - m_epsilon = newEpsilon; - return *this; - } - - Approx& scale( double newScale ) { - m_scale = newScale; - return *this; - } - - std::string toString() const { - std::ostringstream oss; - oss << "Approx( " << Catch::toString( m_value ) << " )"; - return oss.str(); - } - - private: - double m_epsilon; - double m_scale; - double m_value; - }; -} - -template<> -inline std::string toString<Detail::Approx>( Detail::Approx const& value ) { - return value.toString(); -} - -} // end namespace Catch - -// #included from: internal/catch_matchers.hpp -#define TWOBLUECUBES_CATCH_MATCHERS_HPP_INCLUDED - -namespace Catch { -namespace Matchers { - namespace Impl { - - template<typename ExpressionT> - struct Matcher : SharedImpl<IShared> - { - typedef ExpressionT ExpressionType; - - virtual ~Matcher() {} - virtual Ptr<Matcher> clone() const = 0; - virtual bool match( ExpressionT const& expr ) const = 0; - virtual std::string toString() const = 0; - }; - - template<typename DerivedT, typename ExpressionT> - struct MatcherImpl : Matcher<ExpressionT> { - - virtual Ptr<Matcher<ExpressionT> > clone() const { - return Ptr<Matcher<ExpressionT> >( new DerivedT( static_cast<DerivedT const&>( *this ) ) ); - } - }; - - namespace Generic { - - template<typename ExpressionT> - class AllOf : public MatcherImpl<AllOf<ExpressionT>, ExpressionT> { - public: - - AllOf() {} - AllOf( AllOf const& other ) : m_matchers( other.m_matchers ) {} - - AllOf& add( Matcher<ExpressionT> const& matcher ) { - m_matchers.push_back( matcher.clone() ); - return *this; - } - virtual bool match( ExpressionT const& expr ) const - { - for( std::size_t i = 0; i < m_matchers.size(); ++i ) - if( !m_matchers[i]->match( expr ) ) - return false; - return true; - } - virtual std::string toString() const { - std::ostringstream oss; - oss << "( "; - for( std::size_t i = 0; i < m_matchers.size(); ++i ) { - if( i != 0 ) - oss << " and "; - oss << m_matchers[i]->toString(); - } - oss << " )"; - return oss.str(); - } - - private: - std::vector<Ptr<Matcher<ExpressionT> > > m_matchers; - }; - - template<typename ExpressionT> - class AnyOf : public MatcherImpl<AnyOf<ExpressionT>, ExpressionT> { - public: - - AnyOf() {} - AnyOf( AnyOf const& other ) : m_matchers( other.m_matchers ) {} - - AnyOf& add( Matcher<ExpressionT> const& matcher ) { - m_matchers.push_back( matcher.clone() ); - return *this; - } - virtual bool match( ExpressionT const& expr ) const - { - for( std::size_t i = 0; i < m_matchers.size(); ++i ) - if( m_matchers[i]->match( expr ) ) - return true; - return false; - } - virtual std::string toString() const { - std::ostringstream oss; - oss << "( "; - for( std::size_t i = 0; i < m_matchers.size(); ++i ) { - if( i != 0 ) - oss << " or "; - oss << m_matchers[i]->toString(); - } - oss << " )"; - return oss.str(); - } - - private: - std::vector<Ptr<Matcher<ExpressionT> > > m_matchers; - }; - - } - - namespace StdString { - - inline std::string makeString( std::string const& str ) { return str; } - inline std::string makeString( const char* str ) { return str ? std::string( str ) : std::string(); } - - struct Equals : MatcherImpl<Equals, std::string> { - Equals( std::string const& str ) : m_str( str ){} - Equals( Equals const& other ) : m_str( other.m_str ){} - - virtual ~Equals(); - - virtual bool match( std::string const& expr ) const { - return m_str == expr; - } - virtual std::string toString() const { - return "equals: \"" + m_str + "\""; - } - - std::string m_str; - }; - - struct Contains : MatcherImpl<Contains, std::string> { - Contains( std::string const& substr ) : m_substr( substr ){} - Contains( Contains const& other ) : m_substr( other.m_substr ){} - - virtual ~Contains(); - - virtual bool match( std::string const& expr ) const { - return expr.find( m_substr ) != std::string::npos; - } - virtual std::string toString() const { - return "contains: \"" + m_substr + "\""; - } - - std::string m_substr; - }; - - struct StartsWith : MatcherImpl<StartsWith, std::string> { - StartsWith( std::string const& substr ) : m_substr( substr ){} - StartsWith( StartsWith const& other ) : m_substr( other.m_substr ){} - - virtual ~StartsWith(); - - virtual bool match( std::string const& expr ) const { - return expr.find( m_substr ) == 0; - } - virtual std::string toString() const { - return "starts with: \"" + m_substr + "\""; - } - - std::string m_substr; - }; - - struct EndsWith : MatcherImpl<EndsWith, std::string> { - EndsWith( std::string const& substr ) : m_substr( substr ){} - EndsWith( EndsWith const& other ) : m_substr( other.m_substr ){} - - virtual ~EndsWith(); - - virtual bool match( std::string const& expr ) const { - return expr.find( m_substr ) == expr.size() - m_substr.size(); - } - virtual std::string toString() const { - return "ends with: \"" + m_substr + "\""; - } - - std::string m_substr; - }; - } // namespace StdString - } // namespace Impl - - // The following functions create the actual matcher objects. - // This allows the types to be inferred - template<typename ExpressionT> - inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1, - Impl::Matcher<ExpressionT> const& m2 ) { - return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ); - } - template<typename ExpressionT> - inline Impl::Generic::AllOf<ExpressionT> AllOf( Impl::Matcher<ExpressionT> const& m1, - Impl::Matcher<ExpressionT> const& m2, - Impl::Matcher<ExpressionT> const& m3 ) { - return Impl::Generic::AllOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 ); - } - template<typename ExpressionT> - inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1, - Impl::Matcher<ExpressionT> const& m2 ) { - return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ); - } - template<typename ExpressionT> - inline Impl::Generic::AnyOf<ExpressionT> AnyOf( Impl::Matcher<ExpressionT> const& m1, - Impl::Matcher<ExpressionT> const& m2, - Impl::Matcher<ExpressionT> const& m3 ) { - return Impl::Generic::AnyOf<ExpressionT>().add( m1 ).add( m2 ).add( m3 ); - } - - inline Impl::StdString::Equals Equals( std::string const& str ) { - return Impl::StdString::Equals( str ); - } - inline Impl::StdString::Equals Equals( const char* str ) { - return Impl::StdString::Equals( Impl::StdString::makeString( str ) ); - } - inline Impl::StdString::Contains Contains( std::string const& substr ) { - return Impl::StdString::Contains( substr ); - } - inline Impl::StdString::Contains Contains( const char* substr ) { - return Impl::StdString::Contains( Impl::StdString::makeString( substr ) ); - } - inline Impl::StdString::StartsWith StartsWith( std::string const& substr ) { - return Impl::StdString::StartsWith( substr ); - } - inline Impl::StdString::StartsWith StartsWith( const char* substr ) { - return Impl::StdString::StartsWith( Impl::StdString::makeString( substr ) ); - } - inline Impl::StdString::EndsWith EndsWith( std::string const& substr ) { - return Impl::StdString::EndsWith( substr ); - } - inline Impl::StdString::EndsWith EndsWith( const char* substr ) { - return Impl::StdString::EndsWith( Impl::StdString::makeString( substr ) ); - } - -} // namespace Matchers - -using namespace Matchers; - -} // namespace Catch - -// #included from: internal/catch_interfaces_tag_alias_registry.h -#define TWOBLUECUBES_CATCH_INTERFACES_TAG_ALIAS_REGISTRY_H_INCLUDED - -// #included from: catch_tag_alias.h -#define TWOBLUECUBES_CATCH_TAG_ALIAS_H_INCLUDED - -#include <string> - -namespace Catch { - - struct TagAlias { - TagAlias( std::string _tag, SourceLineInfo _lineInfo ) : tag( _tag ), lineInfo( _lineInfo ) {} - - std::string tag; - SourceLineInfo lineInfo; - }; - - struct RegistrarForTagAliases { - RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - }; - -} // end namespace Catch - -#define CATCH_REGISTER_TAG_ALIAS( alias, spec ) namespace{ Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME( AutoRegisterTagAlias )( alias, spec, CATCH_INTERNAL_LINEINFO ); } -// #included from: catch_option.hpp -#define TWOBLUECUBES_CATCH_OPTION_HPP_INCLUDED - -namespace Catch { - - // An optional type - template<typename T> - class Option { - public: - Option() : nullableValue( NULL ) {} - Option( T const& _value ) - : nullableValue( new( storage ) T( _value ) ) - {} - Option( Option const& _other ) - : nullableValue( _other ? new( storage ) T( *_other ) : NULL ) - {} - - ~Option() { - reset(); - } - - Option& operator= ( Option const& _other ) { - if( &_other != this ) { - reset(); - if( _other ) - nullableValue = new( storage ) T( *_other ); - } - return *this; - } - Option& operator = ( T const& _value ) { - reset(); - nullableValue = new( storage ) T( _value ); - return *this; - } - - void reset() { - if( nullableValue ) - nullableValue->~T(); - nullableValue = NULL; - } - - T& operator*() { return *nullableValue; } - T const& operator*() const { return *nullableValue; } - T* operator->() { return nullableValue; } - const T* operator->() const { return nullableValue; } - - T valueOr( T const& defaultValue ) const { - return nullableValue ? *nullableValue : defaultValue; - } - - bool some() const { return nullableValue != NULL; } - bool none() const { return nullableValue == NULL; } - - bool operator !() const { return nullableValue == NULL; } - operator SafeBool::type() const { - return SafeBool::makeSafe( some() ); - } - - private: - T* nullableValue; - char storage[sizeof(T)]; - }; - -} // end namespace Catch - -namespace Catch { - - struct ITagAliasRegistry { - virtual ~ITagAliasRegistry(); - virtual Option<TagAlias> find( std::string const& alias ) const = 0; - virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const = 0; - - static ITagAliasRegistry const& get(); - }; - -} // end namespace Catch - -// These files are included here so the single_include script doesn't put them -// in the conditionally compiled sections -// #included from: internal/catch_test_case_info.h -#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_H_INCLUDED - -#include <string> -#include <set> - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -namespace Catch { - - struct ITestCase; - - struct TestCaseInfo { - enum SpecialProperties{ - None = 0, - IsHidden = 1 << 1, - ShouldFail = 1 << 2, - MayFail = 1 << 3, - Throws = 1 << 4 - }; - - TestCaseInfo( std::string const& _name, - std::string const& _className, - std::string const& _description, - std::set<std::string> const& _tags, - SourceLineInfo const& _lineInfo ); - - TestCaseInfo( TestCaseInfo const& other ); - - bool isHidden() const; - bool throws() const; - bool okToFail() const; - bool expectedToFail() const; - - std::string name; - std::string className; - std::string description; - std::set<std::string> tags; - std::set<std::string> lcaseTags; - std::string tagsAsString; - SourceLineInfo lineInfo; - SpecialProperties properties; - }; - - class TestCase : public TestCaseInfo { - public: - - TestCase( ITestCase* testCase, TestCaseInfo const& info ); - TestCase( TestCase const& other ); - - TestCase withName( std::string const& _newName ) const; - - void invoke() const; - - TestCaseInfo const& getTestCaseInfo() const; - - void swap( TestCase& other ); - bool operator == ( TestCase const& other ) const; - bool operator < ( TestCase const& other ) const; - TestCase& operator = ( TestCase const& other ); - - private: - Ptr<ITestCase> test; - }; - - TestCase makeTestCase( ITestCase* testCase, - std::string const& className, - std::string const& name, - std::string const& description, - SourceLineInfo const& lineInfo ); -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - - -#ifdef __OBJC__ -// #included from: internal/catch_objc.hpp -#define TWOBLUECUBES_CATCH_OBJC_HPP_INCLUDED - -#import <objc/runtime.h> - -#include <string> - -// NB. Any general catch headers included here must be included -// in catch.hpp first to make sure they are included by the single -// header for non obj-usage - -/////////////////////////////////////////////////////////////////////////////// -// This protocol is really only here for (self) documenting purposes, since -// all its methods are optional. -@protocol OcFixture - -@optional - --(void) setUp; --(void) tearDown; - -@end - -namespace Catch { - - class OcMethod : public SharedImpl<ITestCase> { - - public: - OcMethod( Class cls, SEL sel ) : m_cls( cls ), m_sel( sel ) {} - - virtual void invoke() const { - id obj = [[m_cls alloc] init]; - - performOptionalSelector( obj, @selector(setUp) ); - performOptionalSelector( obj, m_sel ); - performOptionalSelector( obj, @selector(tearDown) ); - - arcSafeRelease( obj ); - } - private: - virtual ~OcMethod() {} - - Class m_cls; - SEL m_sel; - }; - - namespace Detail{ - - inline std::string getAnnotation( Class cls, - std::string const& annotationName, - std::string const& testCaseName ) { - NSString* selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; - SEL sel = NSSelectorFromString( selStr ); - arcSafeRelease( selStr ); - id value = performOptionalSelector( cls, sel ); - if( value ) - return [(NSString*)value UTF8String]; - return ""; - } - } - - inline size_t registerTestMethods() { - size_t noTestMethods = 0; - int noClasses = objc_getClassList( NULL, 0 ); - - Class* classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc( sizeof(Class) * noClasses); - objc_getClassList( classes, noClasses ); - - for( int c = 0; c < noClasses; c++ ) { - Class cls = classes[c]; - { - u_int count; - Method* methods = class_copyMethodList( cls, &count ); - for( u_int m = 0; m < count ; m++ ) { - SEL selector = method_getName(methods[m]); - std::string methodName = sel_getName(selector); - if( startsWith( methodName, "Catch_TestCase_" ) ) { - std::string testCaseName = methodName.substr( 15 ); - std::string name = Detail::getAnnotation( cls, "Name", testCaseName ); - std::string desc = Detail::getAnnotation( cls, "Description", testCaseName ); - const char* className = class_getName( cls ); - - getMutableRegistryHub().registerTest( makeTestCase( new OcMethod( cls, selector ), className, name.c_str(), desc.c_str(), SourceLineInfo() ) ); - noTestMethods++; - } - } - free(methods); - } - } - return noTestMethods; - } - - namespace Matchers { - namespace Impl { - namespace NSStringMatchers { - - template<typename MatcherT> - struct StringHolder : MatcherImpl<MatcherT, NSString*>{ - StringHolder( NSString* substr ) : m_substr( [substr copy] ){} - StringHolder( StringHolder const& other ) : m_substr( [other.m_substr copy] ){} - StringHolder() { - arcSafeRelease( m_substr ); - } - - NSString* m_substr; - }; - - struct Equals : StringHolder<Equals> { - Equals( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( ExpressionType const& str ) const { - return (str != nil || m_substr == nil ) && - [str isEqualToString:m_substr]; - } - - virtual std::string toString() const { - return "equals string: " + Catch::toString( m_substr ); - } - }; - - struct Contains : StringHolder<Contains> { - Contains( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( ExpressionType const& str ) const { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location != NSNotFound; - } - - virtual std::string toString() const { - return "contains string: " + Catch::toString( m_substr ); - } - }; - - struct StartsWith : StringHolder<StartsWith> { - StartsWith( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( ExpressionType const& str ) const { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location == 0; - } - - virtual std::string toString() const { - return "starts with: " + Catch::toString( m_substr ); - } - }; - struct EndsWith : StringHolder<EndsWith> { - EndsWith( NSString* substr ) : StringHolder( substr ){} - - virtual bool match( ExpressionType const& str ) const { - return (str != nil || m_substr == nil ) && - [str rangeOfString:m_substr].location == [str length] - [m_substr length]; - } - - virtual std::string toString() const { - return "ends with: " + Catch::toString( m_substr ); - } - }; - - } // namespace NSStringMatchers - } // namespace Impl - - inline Impl::NSStringMatchers::Equals - Equals( NSString* substr ){ return Impl::NSStringMatchers::Equals( substr ); } - - inline Impl::NSStringMatchers::Contains - Contains( NSString* substr ){ return Impl::NSStringMatchers::Contains( substr ); } - - inline Impl::NSStringMatchers::StartsWith - StartsWith( NSString* substr ){ return Impl::NSStringMatchers::StartsWith( substr ); } - - inline Impl::NSStringMatchers::EndsWith - EndsWith( NSString* substr ){ return Impl::NSStringMatchers::EndsWith( substr ); } - - } // namespace Matchers - - using namespace Matchers; - -} // namespace Catch - -/////////////////////////////////////////////////////////////////////////////// -#define OC_TEST_CASE( name, desc )\ -+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Name_test ) \ -{\ -return @ name; \ -}\ -+(NSString*) INTERNAL_CATCH_UNIQUE_NAME( Catch_Description_test ) \ -{ \ -return @ desc; \ -} \ --(void) INTERNAL_CATCH_UNIQUE_NAME( Catch_TestCase_test ) - -#endif - -#ifdef CATCH_IMPL -// #included from: internal/catch_impl.hpp -#define TWOBLUECUBES_CATCH_IMPL_HPP_INCLUDED - -// Collect all the implementation files together here -// These are the equivalent of what would usually be cpp files - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wweak-vtables" -#endif - -// #included from: ../catch_runner.hpp -#define TWOBLUECUBES_CATCH_RUNNER_HPP_INCLUDED - -// #included from: internal/catch_commandline.hpp -#define TWOBLUECUBES_CATCH_COMMANDLINE_HPP_INCLUDED - -// #included from: catch_config.hpp -#define TWOBLUECUBES_CATCH_CONFIG_HPP_INCLUDED - -// #included from: catch_test_spec_parser.hpp -#define TWOBLUECUBES_CATCH_TEST_SPEC_PARSER_HPP_INCLUDED - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -// #included from: catch_test_spec.hpp -#define TWOBLUECUBES_CATCH_TEST_SPEC_HPP_INCLUDED - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wpadded" -#endif - -#include <string> -#include <vector> - -namespace Catch { - - class TestSpec { - struct Pattern : SharedImpl<> { - virtual ~Pattern(); - virtual bool matches( TestCaseInfo const& testCase ) const = 0; - }; - class NamePattern : public Pattern { - enum WildcardPosition { - NoWildcard = 0, - WildcardAtStart = 1, - WildcardAtEnd = 2, - WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd - }; - - public: - NamePattern( std::string const& name ) : m_name( toLower( name ) ), m_wildcard( NoWildcard ) { - if( startsWith( m_name, "*" ) ) { - m_name = m_name.substr( 1 ); - m_wildcard = WildcardAtStart; - } - if( endsWith( m_name, "*" ) ) { - m_name = m_name.substr( 0, m_name.size()-1 ); - m_wildcard = static_cast<WildcardPosition>( m_wildcard | WildcardAtEnd ); - } - } - virtual ~NamePattern(); - virtual bool matches( TestCaseInfo const& testCase ) const { - switch( m_wildcard ) { - case NoWildcard: - return m_name == toLower( testCase.name ); - case WildcardAtStart: - return endsWith( toLower( testCase.name ), m_name ); - case WildcardAtEnd: - return startsWith( toLower( testCase.name ), m_name ); - case WildcardAtBothEnds: - return contains( toLower( testCase.name ), m_name ); - } - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunreachable-code" -#endif - throw std::logic_error( "Unknown enum" ); -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - } - private: - std::string m_name; - WildcardPosition m_wildcard; - }; - class TagPattern : public Pattern { - public: - TagPattern( std::string const& tag ) : m_tag( toLower( tag ) ) {} - virtual ~TagPattern(); - virtual bool matches( TestCaseInfo const& testCase ) const { - return testCase.lcaseTags.find( m_tag ) != testCase.lcaseTags.end(); - } - private: - std::string m_tag; - }; - class ExcludedPattern : public Pattern { - public: - ExcludedPattern( Ptr<Pattern> const& underlyingPattern ) : m_underlyingPattern( underlyingPattern ) {} - virtual ~ExcludedPattern(); - virtual bool matches( TestCaseInfo const& testCase ) const { return !m_underlyingPattern->matches( testCase ); } - private: - Ptr<Pattern> m_underlyingPattern; - }; - - struct Filter { - std::vector<Ptr<Pattern> > m_patterns; - - bool matches( TestCaseInfo const& testCase ) const { - // All patterns in a filter must match for the filter to be a match - for( std::vector<Ptr<Pattern> >::const_iterator it = m_patterns.begin(), itEnd = m_patterns.end(); it != itEnd; ++it ) - if( !(*it)->matches( testCase ) ) - return false; - return true; - } - }; - - public: - bool hasFilters() const { - return !m_filters.empty(); - } - bool matches( TestCaseInfo const& testCase ) const { - // A TestSpec matches if any filter matches - for( std::vector<Filter>::const_iterator it = m_filters.begin(), itEnd = m_filters.end(); it != itEnd; ++it ) - if( it->matches( testCase ) ) - return true; - return false; - } - - private: - std::vector<Filter> m_filters; - - friend class TestSpecParser; - }; -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -namespace Catch { - - class TestSpecParser { - enum Mode{ None, Name, QuotedName, Tag }; - Mode m_mode; - bool m_exclusion; - std::size_t m_start, m_pos; - std::string m_arg; - TestSpec::Filter m_currentFilter; - TestSpec m_testSpec; - ITagAliasRegistry const* m_tagAliases; - - public: - TestSpecParser( ITagAliasRegistry const& tagAliases ) : m_tagAliases( &tagAliases ) {} - - TestSpecParser& parse( std::string const& arg ) { - m_mode = None; - m_exclusion = false; - m_start = std::string::npos; - m_arg = m_tagAliases->expandAliases( arg ); - for( m_pos = 0; m_pos < m_arg.size(); ++m_pos ) - visitChar( m_arg[m_pos] ); - if( m_mode == Name ) - addPattern<TestSpec::NamePattern>(); - return *this; - } - TestSpec testSpec() { - addFilter(); - return m_testSpec; - } - private: - void visitChar( char c ) { - if( m_mode == None ) { - switch( c ) { - case ' ': return; - case '~': m_exclusion = true; return; - case '[': return startNewMode( Tag, ++m_pos ); - case '"': return startNewMode( QuotedName, ++m_pos ); - default: startNewMode( Name, m_pos ); break; - } - } - if( m_mode == Name ) { - if( c == ',' ) { - addPattern<TestSpec::NamePattern>(); - addFilter(); - } - else if( c == '[' ) { - if( subString() == "exclude:" ) - m_exclusion = true; - else - addPattern<TestSpec::NamePattern>(); - startNewMode( Tag, ++m_pos ); - } - } - else if( m_mode == QuotedName && c == '"' ) - addPattern<TestSpec::NamePattern>(); - else if( m_mode == Tag && c == ']' ) - addPattern<TestSpec::TagPattern>(); - } - void startNewMode( Mode mode, std::size_t start ) { - m_mode = mode; - m_start = start; - } - std::string subString() const { return m_arg.substr( m_start, m_pos - m_start ); } - template<typename T> - void addPattern() { - std::string token = subString(); - if( startsWith( token, "exclude:" ) ) { - m_exclusion = true; - token = token.substr( 8 ); - } - if( !token.empty() ) { - Ptr<TestSpec::Pattern> pattern = new T( token ); - if( m_exclusion ) - pattern = new TestSpec::ExcludedPattern( pattern ); - m_currentFilter.m_patterns.push_back( pattern ); - } - m_exclusion = false; - m_mode = None; - } - void addFilter() { - if( !m_currentFilter.m_patterns.empty() ) { - m_testSpec.m_filters.push_back( m_currentFilter ); - m_currentFilter = TestSpec::Filter(); - } - } - }; - inline TestSpec parseTestSpec( std::string const& arg ) { - return TestSpecParser( ITagAliasRegistry::get() ).parse( arg ).testSpec(); - } - -} // namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -// #included from: catch_interfaces_config.h -#define TWOBLUECUBES_CATCH_INTERFACES_CONFIG_H_INCLUDED - -#include <iostream> -#include <string> -#include <vector> - -namespace Catch { - - struct Verbosity { enum Level { - NoOutput = 0, - Quiet, - Normal - }; }; - - struct WarnAbout { enum What { - Nothing = 0x00, - NoAssertions = 0x01 - }; }; - - struct ShowDurations { enum OrNot { - DefaultForReporter, - Always, - Never - }; }; - struct RunTests { enum InWhatOrder { - InDeclarationOrder, - InLexicographicalOrder, - InRandomOrder - }; }; - - class TestSpec; - - struct IConfig : IShared { - - virtual ~IConfig(); - - virtual bool allowThrows() const = 0; - virtual std::ostream& stream() const = 0; - virtual std::string name() const = 0; - virtual bool includeSuccessfulResults() const = 0; - virtual bool shouldDebugBreak() const = 0; - virtual bool warnAboutMissingAssertions() const = 0; - virtual int abortAfter() const = 0; - virtual bool showInvisibles() const = 0; - virtual ShowDurations::OrNot showDurations() const = 0; - virtual TestSpec const& testSpec() const = 0; - virtual RunTests::InWhatOrder runOrder() const = 0; - virtual unsigned int rngSeed() const = 0; - virtual bool forceColour() const = 0; - }; -} - -// #included from: catch_stream.h -#define TWOBLUECUBES_CATCH_STREAM_H_INCLUDED - -#include <streambuf> - -#ifdef __clang__ -#pragma clang diagnostic ignored "-Wpadded" -#endif - -namespace Catch { - - class Stream { - public: - Stream(); - Stream( std::streambuf* _streamBuf, bool _isOwned ); - void release(); - - std::streambuf* streamBuf; - - private: - bool isOwned; - }; - - std::ostream& cout(); - std::ostream& cerr(); -} - -#include <memory> -#include <vector> -#include <string> -#include <iostream> -#include <ctime> - -#ifndef CATCH_CONFIG_CONSOLE_WIDTH -#define CATCH_CONFIG_CONSOLE_WIDTH 80 -#endif - -namespace Catch { - - struct ConfigData { - - ConfigData() - : listTests( false ), - listTags( false ), - listReporters( false ), - listTestNamesOnly( false ), - showSuccessfulTests( false ), - shouldDebugBreak( false ), - noThrow( false ), - showHelp( false ), - showInvisibles( false ), - forceColour( false ), - abortAfter( -1 ), - rngSeed( 0 ), - verbosity( Verbosity::Normal ), - warnings( WarnAbout::Nothing ), - showDurations( ShowDurations::DefaultForReporter ), - runOrder( RunTests::InDeclarationOrder ) - {} - - bool listTests; - bool listTags; - bool listReporters; - bool listTestNamesOnly; - - bool showSuccessfulTests; - bool shouldDebugBreak; - bool noThrow; - bool showHelp; - bool showInvisibles; - bool forceColour; - - int abortAfter; - unsigned int rngSeed; - - Verbosity::Level verbosity; - WarnAbout::What warnings; - ShowDurations::OrNot showDurations; - RunTests::InWhatOrder runOrder; - - std::string reporterName; - std::string outputFilename; - std::string name; - std::string processName; - - std::vector<std::string> testsOrTags; - }; - - class Config : public SharedImpl<IConfig> { - private: - Config( Config const& other ); - Config& operator = ( Config const& other ); - virtual void dummy(); - public: - - Config() - : m_os( Catch::cout().rdbuf() ) - {} - - Config( ConfigData const& data ) - : m_data( data ), - m_os( Catch::cout().rdbuf() ) - { - if( !data.testsOrTags.empty() ) { - TestSpecParser parser( ITagAliasRegistry::get() ); - for( std::size_t i = 0; i < data.testsOrTags.size(); ++i ) - parser.parse( data.testsOrTags[i] ); - m_testSpec = parser.testSpec(); - } - } - - virtual ~Config() { - m_os.rdbuf( Catch::cout().rdbuf() ); - m_stream.release(); - } - - void setFilename( std::string const& filename ) { - m_data.outputFilename = filename; - } - - std::string const& getFilename() const { - return m_data.outputFilename ; - } - - bool listTests() const { return m_data.listTests; } - bool listTestNamesOnly() const { return m_data.listTestNamesOnly; } - bool listTags() const { return m_data.listTags; } - bool listReporters() const { return m_data.listReporters; } - - std::string getProcessName() const { return m_data.processName; } - - bool shouldDebugBreak() const { return m_data.shouldDebugBreak; } - - void setStreamBuf( std::streambuf* buf ) { - m_os.rdbuf( buf ? buf : Catch::cout().rdbuf() ); - } - - void useStream( std::string const& streamName ) { - Stream stream = createStream( streamName ); - setStreamBuf( stream.streamBuf ); - m_stream.release(); - m_stream = stream; - } - - std::string getReporterName() const { return m_data.reporterName; } - - int abortAfter() const { return m_data.abortAfter; } - - TestSpec const& testSpec() const { return m_testSpec; } - - bool showHelp() const { return m_data.showHelp; } - bool showInvisibles() const { return m_data.showInvisibles; } - - // IConfig interface - virtual bool allowThrows() const { return !m_data.noThrow; } - virtual std::ostream& stream() const { return m_os; } - virtual std::string name() const { return m_data.name.empty() ? m_data.processName : m_data.name; } - virtual bool includeSuccessfulResults() const { return m_data.showSuccessfulTests; } - virtual bool warnAboutMissingAssertions() const { return m_data.warnings & WarnAbout::NoAssertions; } - virtual ShowDurations::OrNot showDurations() const { return m_data.showDurations; } - virtual RunTests::InWhatOrder runOrder() const { return m_data.runOrder; } - virtual unsigned int rngSeed() const { return m_data.rngSeed; } - virtual bool forceColour() const { return m_data.forceColour; } - - private: - ConfigData m_data; - - Stream m_stream; - mutable std::ostream m_os; - TestSpec m_testSpec; - }; - -} // end namespace Catch - -// #included from: catch_clara.h -#define TWOBLUECUBES_CATCH_CLARA_H_INCLUDED - -// Use Catch's value for console width (store Clara's off to the side, if present) -#ifdef CLARA_CONFIG_CONSOLE_WIDTH -#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CLARA_CONFIG_CONSOLE_WIDTH -#undef CLARA_CONFIG_CONSOLE_WIDTH -#endif -#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH - -// Declare Clara inside the Catch namespace -#define STITCH_CLARA_OPEN_NAMESPACE namespace Catch { -// #included from: ../external/clara.h - -// Only use header guard if we are not using an outer namespace -#if !defined(TWOBLUECUBES_CLARA_H_INCLUDED) || defined(STITCH_CLARA_OPEN_NAMESPACE) - -#ifndef STITCH_CLARA_OPEN_NAMESPACE -#define TWOBLUECUBES_CLARA_H_INCLUDED -#define STITCH_CLARA_OPEN_NAMESPACE -#define STITCH_CLARA_CLOSE_NAMESPACE -#else -#define STITCH_CLARA_CLOSE_NAMESPACE } -#endif - -#define STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE STITCH_CLARA_OPEN_NAMESPACE - -// ----------- #included from tbc_text_format.h ----------- - -// Only use header guard if we are not using an outer namespace -#if !defined(TBC_TEXT_FORMAT_H_INCLUDED) || defined(STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE) -#ifndef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE -#define TBC_TEXT_FORMAT_H_INCLUDED -#endif - -#include <string> -#include <vector> -#include <sstream> - -// Use optional outer namespace -#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE -namespace STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE { -#endif - -namespace Tbc { - -#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH - const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; -#else - const unsigned int consoleWidth = 80; -#endif - - struct TextAttributes { - TextAttributes() - : initialIndent( std::string::npos ), - indent( 0 ), - width( consoleWidth-1 ), - tabChar( '\t' ) - {} - - TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } - TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } - TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } - TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } - - std::size_t initialIndent; // indent of first line, or npos - std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos - std::size_t width; // maximum width of text, including indent. Longer text will wrap - char tabChar; // If this char is seen the indent is changed to current pos - }; - - class Text { - public: - Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) - : attr( _attr ) - { - std::string wrappableChars = " [({.,/|\\-"; - std::size_t indent = _attr.initialIndent != std::string::npos - ? _attr.initialIndent - : _attr.indent; - std::string remainder = _str; - - while( !remainder.empty() ) { - if( lines.size() >= 1000 ) { - lines.push_back( "... message truncated due to excessive size" ); - return; - } - std::size_t tabPos = std::string::npos; - std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); - std::size_t pos = remainder.find_first_of( '\n' ); - if( pos <= width ) { - width = pos; - } - pos = remainder.find_last_of( _attr.tabChar, width ); - if( pos != std::string::npos ) { - tabPos = pos; - if( remainder[width] == '\n' ) - width--; - remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); - } - - if( width == remainder.size() ) { - spliceLine( indent, remainder, width ); - } - else if( remainder[width] == '\n' ) { - spliceLine( indent, remainder, width ); - if( width <= 1 || remainder.size() != 1 ) - remainder = remainder.substr( 1 ); - indent = _attr.indent; - } - else { - pos = remainder.find_last_of( wrappableChars, width ); - if( pos != std::string::npos && pos > 0 ) { - spliceLine( indent, remainder, pos ); - if( remainder[0] == ' ' ) - remainder = remainder.substr( 1 ); - } - else { - spliceLine( indent, remainder, width-1 ); - lines.back() += "-"; - } - if( lines.size() == 1 ) - indent = _attr.indent; - if( tabPos != std::string::npos ) - indent += tabPos; - } - } - } - - void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { - lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); - _remainder = _remainder.substr( _pos ); - } - - typedef std::vector<std::string>::const_iterator const_iterator; - - const_iterator begin() const { return lines.begin(); } - const_iterator end() const { return lines.end(); } - std::string const& last() const { return lines.back(); } - std::size_t size() const { return lines.size(); } - std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } - std::string toString() const { - std::ostringstream oss; - oss << *this; - return oss.str(); - } - - inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { - for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); - it != itEnd; ++it ) { - if( it != _text.begin() ) - _stream << "\n"; - _stream << *it; - } - return _stream; - } - - private: - std::string str; - TextAttributes attr; - std::vector<std::string> lines; - }; - -} // end namespace Tbc - -#ifdef STITCH_TBC_TEXT_FORMAT_OUTER_NAMESPACE -} // end outer namespace -#endif - -#endif // TBC_TEXT_FORMAT_H_INCLUDED - -// ----------- end of #include from tbc_text_format.h ----------- -// ........... back in /Users/philnash/Dev/OSS/Clara/srcs/clara.h - -#undef STITCH_TBC_TEXT_FORMAT_OPEN_NAMESPACE - -#include <map> -#include <algorithm> -#include <stdexcept> -#include <memory> - -// Use optional outer namespace -#ifdef STITCH_CLARA_OPEN_NAMESPACE -STITCH_CLARA_OPEN_NAMESPACE -#endif - -namespace Clara { - - struct UnpositionalTag {}; - - extern UnpositionalTag _; - -#ifdef CLARA_CONFIG_MAIN - UnpositionalTag _; -#endif - - namespace Detail { - -#ifdef CLARA_CONSOLE_WIDTH - const unsigned int consoleWidth = CLARA_CONFIG_CONSOLE_WIDTH; -#else - const unsigned int consoleWidth = 80; -#endif - - using namespace Tbc; - - inline bool startsWith( std::string const& str, std::string const& prefix ) { - return str.size() >= prefix.size() && str.substr( 0, prefix.size() ) == prefix; - } - - template<typename T> struct RemoveConstRef{ typedef T type; }; - template<typename T> struct RemoveConstRef<T&>{ typedef T type; }; - template<typename T> struct RemoveConstRef<T const&>{ typedef T type; }; - template<typename T> struct RemoveConstRef<T const>{ typedef T type; }; - - template<typename T> struct IsBool { static const bool value = false; }; - template<> struct IsBool<bool> { static const bool value = true; }; - - template<typename T> - void convertInto( std::string const& _source, T& _dest ) { - std::stringstream ss; - ss << _source; - ss >> _dest; - if( ss.fail() ) - throw std::runtime_error( "Unable to convert " + _source + " to destination type" ); - } - inline void convertInto( std::string const& _source, std::string& _dest ) { - _dest = _source; - } - inline void convertInto( std::string const& _source, bool& _dest ) { - std::string sourceLC = _source; - std::transform( sourceLC.begin(), sourceLC.end(), sourceLC.begin(), ::tolower ); - if( sourceLC == "y" || sourceLC == "1" || sourceLC == "true" || sourceLC == "yes" || sourceLC == "on" ) - _dest = true; - else if( sourceLC == "n" || sourceLC == "0" || sourceLC == "false" || sourceLC == "no" || sourceLC == "off" ) - _dest = false; - else - throw std::runtime_error( "Expected a boolean value but did not recognise:\n '" + _source + "'" ); - } - inline void convertInto( bool _source, bool& _dest ) { - _dest = _source; - } - template<typename T> - inline void convertInto( bool, T& ) { - throw std::runtime_error( "Invalid conversion" ); - } - - template<typename ConfigT> - struct IArgFunction { - virtual ~IArgFunction() {} -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - IArgFunction() = default; - IArgFunction( IArgFunction const& ) = default; -# endif - virtual void set( ConfigT& config, std::string const& value ) const = 0; - virtual void setFlag( ConfigT& config ) const = 0; - virtual bool takesArg() const = 0; - virtual IArgFunction* clone() const = 0; - }; - - template<typename ConfigT> - class BoundArgFunction { - public: - BoundArgFunction() : functionObj( NULL ) {} - BoundArgFunction( IArgFunction<ConfigT>* _functionObj ) : functionObj( _functionObj ) {} - BoundArgFunction( BoundArgFunction const& other ) : functionObj( other.functionObj ? other.functionObj->clone() : NULL ) {} - BoundArgFunction& operator = ( BoundArgFunction const& other ) { - IArgFunction<ConfigT>* newFunctionObj = other.functionObj ? other.functionObj->clone() : NULL; - delete functionObj; - functionObj = newFunctionObj; - return *this; - } - ~BoundArgFunction() { delete functionObj; } - - void set( ConfigT& config, std::string const& value ) const { - functionObj->set( config, value ); - } - void setFlag( ConfigT& config ) const { - functionObj->setFlag( config ); - } - bool takesArg() const { return functionObj->takesArg(); } - - bool isSet() const { - return functionObj != NULL; - } - private: - IArgFunction<ConfigT>* functionObj; - }; - - template<typename C> - struct NullBinder : IArgFunction<C>{ - virtual void set( C&, std::string const& ) const {} - virtual void setFlag( C& ) const {} - virtual bool takesArg() const { return true; } - virtual IArgFunction<C>* clone() const { return new NullBinder( *this ); } - }; - - template<typename C, typename M> - struct BoundDataMember : IArgFunction<C>{ - BoundDataMember( M C::* _member ) : member( _member ) {} - virtual void set( C& p, std::string const& stringValue ) const { - convertInto( stringValue, p.*member ); - } - virtual void setFlag( C& p ) const { - convertInto( true, p.*member ); - } - virtual bool takesArg() const { return !IsBool<M>::value; } - virtual IArgFunction<C>* clone() const { return new BoundDataMember( *this ); } - M C::* member; - }; - template<typename C, typename M> - struct BoundUnaryMethod : IArgFunction<C>{ - BoundUnaryMethod( void (C::*_member)( M ) ) : member( _member ) {} - virtual void set( C& p, std::string const& stringValue ) const { - typename RemoveConstRef<M>::type value; - convertInto( stringValue, value ); - (p.*member)( value ); - } - virtual void setFlag( C& p ) const { - typename RemoveConstRef<M>::type value; - convertInto( true, value ); - (p.*member)( value ); - } - virtual bool takesArg() const { return !IsBool<M>::value; } - virtual IArgFunction<C>* clone() const { return new BoundUnaryMethod( *this ); } - void (C::*member)( M ); - }; - template<typename C> - struct BoundNullaryMethod : IArgFunction<C>{ - BoundNullaryMethod( void (C::*_member)() ) : member( _member ) {} - virtual void set( C& p, std::string const& stringValue ) const { - bool value; - convertInto( stringValue, value ); - if( value ) - (p.*member)(); - } - virtual void setFlag( C& p ) const { - (p.*member)(); - } - virtual bool takesArg() const { return false; } - virtual IArgFunction<C>* clone() const { return new BoundNullaryMethod( *this ); } - void (C::*member)(); - }; - - template<typename C> - struct BoundUnaryFunction : IArgFunction<C>{ - BoundUnaryFunction( void (*_function)( C& ) ) : function( _function ) {} - virtual void set( C& obj, std::string const& stringValue ) const { - bool value; - convertInto( stringValue, value ); - if( value ) - function( obj ); - } - virtual void setFlag( C& p ) const { - function( p ); - } - virtual bool takesArg() const { return false; } - virtual IArgFunction<C>* clone() const { return new BoundUnaryFunction( *this ); } - void (*function)( C& ); - }; - - template<typename C, typename T> - struct BoundBinaryFunction : IArgFunction<C>{ - BoundBinaryFunction( void (*_function)( C&, T ) ) : function( _function ) {} - virtual void set( C& obj, std::string const& stringValue ) const { - typename RemoveConstRef<T>::type value; - convertInto( stringValue, value ); - function( obj, value ); - } - virtual void setFlag( C& obj ) const { - typename RemoveConstRef<T>::type value; - convertInto( true, value ); - function( obj, value ); - } - virtual bool takesArg() const { return !IsBool<T>::value; } - virtual IArgFunction<C>* clone() const { return new BoundBinaryFunction( *this ); } - void (*function)( C&, T ); - }; - - } // namespace Detail - - struct Parser { - Parser() : separators( " \t=:" ) {} - - struct Token { - enum Type { Positional, ShortOpt, LongOpt }; - Token( Type _type, std::string const& _data ) : type( _type ), data( _data ) {} - Type type; - std::string data; - }; - - void parseIntoTokens( int argc, char const * const * argv, std::vector<Parser::Token>& tokens ) const { - const std::string doubleDash = "--"; - for( int i = 1; i < argc && argv[i] != doubleDash; ++i ) - parseIntoTokens( argv[i] , tokens); - } - void parseIntoTokens( std::string arg, std::vector<Parser::Token>& tokens ) const { - while( !arg.empty() ) { - Parser::Token token( Parser::Token::Positional, arg ); - arg = ""; - if( token.data[0] == '-' ) { - if( token.data.size() > 1 && token.data[1] == '-' ) { - token = Parser::Token( Parser::Token::LongOpt, token.data.substr( 2 ) ); - } - else { - token = Parser::Token( Parser::Token::ShortOpt, token.data.substr( 1 ) ); - if( token.data.size() > 1 && separators.find( token.data[1] ) == std::string::npos ) { - arg = "-" + token.data.substr( 1 ); - token.data = token.data.substr( 0, 1 ); - } - } - } - if( token.type != Parser::Token::Positional ) { - std::size_t pos = token.data.find_first_of( separators ); - if( pos != std::string::npos ) { - arg = token.data.substr( pos+1 ); - token.data = token.data.substr( 0, pos ); - } - } - tokens.push_back( token ); - } - } - std::string separators; - }; - - template<typename ConfigT> - struct CommonArgProperties { - CommonArgProperties() {} - CommonArgProperties( Detail::BoundArgFunction<ConfigT> const& _boundField ) : boundField( _boundField ) {} - - Detail::BoundArgFunction<ConfigT> boundField; - std::string description; - std::string detail; - std::string placeholder; // Only value if boundField takes an arg - - bool takesArg() const { - return !placeholder.empty(); - } - void validate() const { - if( !boundField.isSet() ) - throw std::logic_error( "option not bound" ); - } - }; - struct OptionArgProperties { - std::vector<std::string> shortNames; - std::string longName; - - bool hasShortName( std::string const& shortName ) const { - return std::find( shortNames.begin(), shortNames.end(), shortName ) != shortNames.end(); - } - bool hasLongName( std::string const& _longName ) const { - return _longName == longName; - } - }; - struct PositionalArgProperties { - PositionalArgProperties() : position( -1 ) {} - int position; // -1 means non-positional (floating) - - bool isFixedPositional() const { - return position != -1; - } - }; - - template<typename ConfigT> - class CommandLine { - - struct Arg : CommonArgProperties<ConfigT>, OptionArgProperties, PositionalArgProperties { - Arg() {} - Arg( Detail::BoundArgFunction<ConfigT> const& _boundField ) : CommonArgProperties<ConfigT>( _boundField ) {} - - using CommonArgProperties<ConfigT>::placeholder; // !TBD - - std::string dbgName() const { - if( !longName.empty() ) - return "--" + longName; - if( !shortNames.empty() ) - return "-" + shortNames[0]; - return "positional args"; - } - std::string commands() const { - std::ostringstream oss; - bool first = true; - std::vector<std::string>::const_iterator it = shortNames.begin(), itEnd = shortNames.end(); - for(; it != itEnd; ++it ) { - if( first ) - first = false; - else - oss << ", "; - oss << "-" << *it; - } - if( !longName.empty() ) { - if( !first ) - oss << ", "; - oss << "--" << longName; - } - if( !placeholder.empty() ) - oss << " <" << placeholder << ">"; - return oss.str(); - } - }; - - // NOTE: std::auto_ptr is deprecated in c++11/c++0x -#if defined(__cplusplus) && __cplusplus > 199711L - typedef std::unique_ptr<Arg> ArgAutoPtr; -#else - typedef std::auto_ptr<Arg> ArgAutoPtr; -#endif - - friend void addOptName( Arg& arg, std::string const& optName ) - { - if( optName.empty() ) - return; - if( Detail::startsWith( optName, "--" ) ) { - if( !arg.longName.empty() ) - throw std::logic_error( "Only one long opt may be specified. '" - + arg.longName - + "' already specified, now attempting to add '" - + optName + "'" ); - arg.longName = optName.substr( 2 ); - } - else if( Detail::startsWith( optName, "-" ) ) - arg.shortNames.push_back( optName.substr( 1 ) ); - else - throw std::logic_error( "option must begin with - or --. Option was: '" + optName + "'" ); - } - friend void setPositionalArg( Arg& arg, int position ) - { - arg.position = position; - } - - class ArgBuilder { - public: - ArgBuilder( Arg* arg ) : m_arg( arg ) {} - - // Bind a non-boolean data member (requires placeholder string) - template<typename C, typename M> - void bind( M C::* field, std::string const& placeholder ) { - m_arg->boundField = new Detail::BoundDataMember<C,M>( field ); - m_arg->placeholder = placeholder; - } - // Bind a boolean data member (no placeholder required) - template<typename C> - void bind( bool C::* field ) { - m_arg->boundField = new Detail::BoundDataMember<C,bool>( field ); - } - - // Bind a method taking a single, non-boolean argument (requires a placeholder string) - template<typename C, typename M> - void bind( void (C::* unaryMethod)( M ), std::string const& placeholder ) { - m_arg->boundField = new Detail::BoundUnaryMethod<C,M>( unaryMethod ); - m_arg->placeholder = placeholder; - } - - // Bind a method taking a single, boolean argument (no placeholder string required) - template<typename C> - void bind( void (C::* unaryMethod)( bool ) ) { - m_arg->boundField = new Detail::BoundUnaryMethod<C,bool>( unaryMethod ); - } - - // Bind a method that takes no arguments (will be called if opt is present) - template<typename C> - void bind( void (C::* nullaryMethod)() ) { - m_arg->boundField = new Detail::BoundNullaryMethod<C>( nullaryMethod ); - } - - // Bind a free function taking a single argument - the object to operate on (no placeholder string required) - template<typename C> - void bind( void (* unaryFunction)( C& ) ) { - m_arg->boundField = new Detail::BoundUnaryFunction<C>( unaryFunction ); - } - - // Bind a free function taking a single argument - the object to operate on (requires a placeholder string) - template<typename C, typename T> - void bind( void (* binaryFunction)( C&, T ), std::string const& placeholder ) { - m_arg->boundField = new Detail::BoundBinaryFunction<C, T>( binaryFunction ); - m_arg->placeholder = placeholder; - } - - ArgBuilder& describe( std::string const& description ) { - m_arg->description = description; - return *this; - } - ArgBuilder& detail( std::string const& detail ) { - m_arg->detail = detail; - return *this; - } - - protected: - Arg* m_arg; - }; - - class OptBuilder : public ArgBuilder { - public: - OptBuilder( Arg* arg ) : ArgBuilder( arg ) {} - OptBuilder( OptBuilder& other ) : ArgBuilder( other ) {} - - OptBuilder& operator[]( std::string const& optName ) { - addOptName( *ArgBuilder::m_arg, optName ); - return *this; - } - }; - - public: - - CommandLine() - : m_boundProcessName( new Detail::NullBinder<ConfigT>() ), - m_highestSpecifiedArgPosition( 0 ), - m_throwOnUnrecognisedTokens( false ) - {} - CommandLine( CommandLine const& other ) - : m_boundProcessName( other.m_boundProcessName ), - m_options ( other.m_options ), - m_positionalArgs( other.m_positionalArgs ), - m_highestSpecifiedArgPosition( other.m_highestSpecifiedArgPosition ), - m_throwOnUnrecognisedTokens( other.m_throwOnUnrecognisedTokens ) - { - if( other.m_floatingArg.get() ) - m_floatingArg.reset( new Arg( *other.m_floatingArg ) ); - } - - CommandLine& setThrowOnUnrecognisedTokens( bool shouldThrow = true ) { - m_throwOnUnrecognisedTokens = shouldThrow; - return *this; - } - - OptBuilder operator[]( std::string const& optName ) { - m_options.push_back( Arg() ); - addOptName( m_options.back(), optName ); - OptBuilder builder( &m_options.back() ); - return builder; - } - - ArgBuilder operator[]( int position ) { - m_positionalArgs.insert( std::make_pair( position, Arg() ) ); - if( position > m_highestSpecifiedArgPosition ) - m_highestSpecifiedArgPosition = position; - setPositionalArg( m_positionalArgs[position], position ); - ArgBuilder builder( &m_positionalArgs[position] ); - return builder; - } - - // Invoke this with the _ instance - ArgBuilder operator[]( UnpositionalTag ) { - if( m_floatingArg.get() ) - throw std::logic_error( "Only one unpositional argument can be added" ); - m_floatingArg.reset( new Arg() ); - ArgBuilder builder( m_floatingArg.get() ); - return builder; - } - - template<typename C, typename M> - void bindProcessName( M C::* field ) { - m_boundProcessName = new Detail::BoundDataMember<C,M>( field ); - } - template<typename C, typename M> - void bindProcessName( void (C::*_unaryMethod)( M ) ) { - m_boundProcessName = new Detail::BoundUnaryMethod<C,M>( _unaryMethod ); - } - - void optUsage( std::ostream& os, std::size_t indent = 0, std::size_t width = Detail::consoleWidth ) const { - typename std::vector<Arg>::const_iterator itBegin = m_options.begin(), itEnd = m_options.end(), it; - std::size_t maxWidth = 0; - for( it = itBegin; it != itEnd; ++it ) - maxWidth = (std::max)( maxWidth, it->commands().size() ); - - for( it = itBegin; it != itEnd; ++it ) { - Detail::Text usage( it->commands(), Detail::TextAttributes() - .setWidth( maxWidth+indent ) - .setIndent( indent ) ); - Detail::Text desc( it->description, Detail::TextAttributes() - .setWidth( width - maxWidth - 3 ) ); - - for( std::size_t i = 0; i < (std::max)( usage.size(), desc.size() ); ++i ) { - std::string usageCol = i < usage.size() ? usage[i] : ""; - os << usageCol; - - if( i < desc.size() && !desc[i].empty() ) - os << std::string( indent + 2 + maxWidth - usageCol.size(), ' ' ) - << desc[i]; - os << "\n"; - } - } - } - std::string optUsage() const { - std::ostringstream oss; - optUsage( oss ); - return oss.str(); - } - - void argSynopsis( std::ostream& os ) const { - for( int i = 1; i <= m_highestSpecifiedArgPosition; ++i ) { - if( i > 1 ) - os << " "; - typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( i ); - if( it != m_positionalArgs.end() ) - os << "<" << it->second.placeholder << ">"; - else if( m_floatingArg.get() ) - os << "<" << m_floatingArg->placeholder << ">"; - else - throw std::logic_error( "non consecutive positional arguments with no floating args" ); - } - // !TBD No indication of mandatory args - if( m_floatingArg.get() ) { - if( m_highestSpecifiedArgPosition > 1 ) - os << " "; - os << "[<" << m_floatingArg->placeholder << "> ...]"; - } - } - std::string argSynopsis() const { - std::ostringstream oss; - argSynopsis( oss ); - return oss.str(); - } - - void usage( std::ostream& os, std::string const& procName ) const { - validate(); - os << "usage:\n " << procName << " "; - argSynopsis( os ); - if( !m_options.empty() ) { - os << " [options]\n\nwhere options are: \n"; - optUsage( os, 2 ); - } - os << "\n"; - } - std::string usage( std::string const& procName ) const { - std::ostringstream oss; - usage( oss, procName ); - return oss.str(); - } - - ConfigT parse( int argc, char const * const * argv ) const { - ConfigT config; - parseInto( argc, argv, config ); - return config; - } - - std::vector<Parser::Token> parseInto( int argc, char const * const * argv, ConfigT& config ) const { - std::string processName = argv[0]; - std::size_t lastSlash = processName.find_last_of( "/\\" ); - if( lastSlash != std::string::npos ) - processName = processName.substr( lastSlash+1 ); - m_boundProcessName.set( config, processName ); - std::vector<Parser::Token> tokens; - Parser parser; - parser.parseIntoTokens( argc, argv, tokens ); - return populate( tokens, config ); - } - - std::vector<Parser::Token> populate( std::vector<Parser::Token> const& tokens, ConfigT& config ) const { - validate(); - std::vector<Parser::Token> unusedTokens = populateOptions( tokens, config ); - unusedTokens = populateFixedArgs( unusedTokens, config ); - unusedTokens = populateFloatingArgs( unusedTokens, config ); - return unusedTokens; - } - - std::vector<Parser::Token> populateOptions( std::vector<Parser::Token> const& tokens, ConfigT& config ) const { - std::vector<Parser::Token> unusedTokens; - std::vector<std::string> errors; - for( std::size_t i = 0; i < tokens.size(); ++i ) { - Parser::Token const& token = tokens[i]; - typename std::vector<Arg>::const_iterator it = m_options.begin(), itEnd = m_options.end(); - for(; it != itEnd; ++it ) { - Arg const& arg = *it; - - try { - if( ( token.type == Parser::Token::ShortOpt && arg.hasShortName( token.data ) ) || - ( token.type == Parser::Token::LongOpt && arg.hasLongName( token.data ) ) ) { - if( arg.takesArg() ) { - if( i == tokens.size()-1 || tokens[i+1].type != Parser::Token::Positional ) - errors.push_back( "Expected argument to option: " + token.data ); - else - arg.boundField.set( config, tokens[++i].data ); - } - else { - arg.boundField.setFlag( config ); - } - break; - } - } - catch( std::exception& ex ) { - errors.push_back( std::string( ex.what() ) + "\n- while parsing: (" + arg.commands() + ")" ); - } - } - if( it == itEnd ) { - if( token.type == Parser::Token::Positional || !m_throwOnUnrecognisedTokens ) - unusedTokens.push_back( token ); - else if( errors.empty() && m_throwOnUnrecognisedTokens ) - errors.push_back( "unrecognised option: " + token.data ); - } - } - if( !errors.empty() ) { - std::ostringstream oss; - for( std::vector<std::string>::const_iterator it = errors.begin(), itEnd = errors.end(); - it != itEnd; - ++it ) { - if( it != errors.begin() ) - oss << "\n"; - oss << *it; - } - throw std::runtime_error( oss.str() ); - } - return unusedTokens; - } - std::vector<Parser::Token> populateFixedArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const { - std::vector<Parser::Token> unusedTokens; - int position = 1; - for( std::size_t i = 0; i < tokens.size(); ++i ) { - Parser::Token const& token = tokens[i]; - typename std::map<int, Arg>::const_iterator it = m_positionalArgs.find( position ); - if( it != m_positionalArgs.end() ) - it->second.boundField.set( config, token.data ); - else - unusedTokens.push_back( token ); - if( token.type == Parser::Token::Positional ) - position++; - } - return unusedTokens; - } - std::vector<Parser::Token> populateFloatingArgs( std::vector<Parser::Token> const& tokens, ConfigT& config ) const { - if( !m_floatingArg.get() ) - return tokens; - std::vector<Parser::Token> unusedTokens; - for( std::size_t i = 0; i < tokens.size(); ++i ) { - Parser::Token const& token = tokens[i]; - if( token.type == Parser::Token::Positional ) - m_floatingArg->boundField.set( config, token.data ); - else - unusedTokens.push_back( token ); - } - return unusedTokens; - } - - void validate() const - { - if( m_options.empty() && m_positionalArgs.empty() && !m_floatingArg.get() ) - throw std::logic_error( "No options or arguments specified" ); - - for( typename std::vector<Arg>::const_iterator it = m_options.begin(), - itEnd = m_options.end(); - it != itEnd; ++it ) - it->validate(); - } - - private: - Detail::BoundArgFunction<ConfigT> m_boundProcessName; - std::vector<Arg> m_options; - std::map<int, Arg> m_positionalArgs; - ArgAutoPtr m_floatingArg; - int m_highestSpecifiedArgPosition; - bool m_throwOnUnrecognisedTokens; - }; - -} // end namespace Clara - -STITCH_CLARA_CLOSE_NAMESPACE -#undef STITCH_CLARA_OPEN_NAMESPACE -#undef STITCH_CLARA_CLOSE_NAMESPACE - -#endif // TWOBLUECUBES_CLARA_H_INCLUDED -#undef STITCH_CLARA_OPEN_NAMESPACE - -// Restore Clara's value for console width, if present -#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#define CLARA_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH -#endif - -#include <fstream> - -namespace Catch { - - inline void abortAfterFirst( ConfigData& config ) { config.abortAfter = 1; } - inline void abortAfterX( ConfigData& config, int x ) { - if( x < 1 ) - throw std::runtime_error( "Value after -x or --abortAfter must be greater than zero" ); - config.abortAfter = x; - } - inline void addTestOrTags( ConfigData& config, std::string const& _testSpec ) { config.testsOrTags.push_back( _testSpec ); } - - inline void addWarning( ConfigData& config, std::string const& _warning ) { - if( _warning == "NoAssertions" ) - config.warnings = static_cast<WarnAbout::What>( config.warnings | WarnAbout::NoAssertions ); - else - throw std::runtime_error( "Unrecognised warning: '" + _warning + "'" ); - } - inline void setOrder( ConfigData& config, std::string const& order ) { - if( startsWith( "declared", order ) ) - config.runOrder = RunTests::InDeclarationOrder; - else if( startsWith( "lexical", order ) ) - config.runOrder = RunTests::InLexicographicalOrder; - else if( startsWith( "random", order ) ) - config.runOrder = RunTests::InRandomOrder; - else - throw std::runtime_error( "Unrecognised ordering: '" + order + "'" ); - } - inline void setRngSeed( ConfigData& config, std::string const& seed ) { - if( seed == "time" ) { - config.rngSeed = static_cast<unsigned int>( std::time(0) ); - } - else { - std::stringstream ss; - ss << seed; - ss >> config.rngSeed; - if( ss.fail() ) - throw std::runtime_error( "Argment to --rng-seed should be the word 'time' or a number" ); - } - } - inline void setVerbosity( ConfigData& config, int level ) { - // !TBD: accept strings? - config.verbosity = static_cast<Verbosity::Level>( level ); - } - inline void setShowDurations( ConfigData& config, bool _showDurations ) { - config.showDurations = _showDurations - ? ShowDurations::Always - : ShowDurations::Never; - } - inline void loadTestNamesFromFile( ConfigData& config, std::string const& _filename ) { - std::ifstream f( _filename.c_str() ); - if( !f.is_open() ) - throw std::domain_error( "Unable to load input file: " + _filename ); - - std::string line; - while( std::getline( f, line ) ) { - line = trim(line); - if( !line.empty() && !startsWith( line, "#" ) ) - addTestOrTags( config, "\"" + line + "\"," ); - } - } - - inline Clara::CommandLine<ConfigData> makeCommandLineParser() { - - using namespace Clara; - CommandLine<ConfigData> cli; - - cli.bindProcessName( &ConfigData::processName ); - - cli["-?"]["-h"]["--help"] - .describe( "display usage information" ) - .bind( &ConfigData::showHelp ); - - cli["-l"]["--list-tests"] - .describe( "list all/matching test cases" ) - .bind( &ConfigData::listTests ); - - cli["-t"]["--list-tags"] - .describe( "list all/matching tags" ) - .bind( &ConfigData::listTags ); - - cli["-s"]["--success"] - .describe( "include successful tests in output" ) - .bind( &ConfigData::showSuccessfulTests ); - - cli["-b"]["--break"] - .describe( "break into debugger on failure" ) - .bind( &ConfigData::shouldDebugBreak ); - - cli["-e"]["--nothrow"] - .describe( "skip exception tests" ) - .bind( &ConfigData::noThrow ); - - cli["-i"]["--invisibles"] - .describe( "show invisibles (tabs, newlines)" ) - .bind( &ConfigData::showInvisibles ); - - cli["-o"]["--out"] - .describe( "output filename" ) - .bind( &ConfigData::outputFilename, "filename" ); - - cli["-r"]["--reporter"] -// .placeholder( "name[:filename]" ) - .describe( "reporter to use (defaults to console)" ) - .bind( &ConfigData::reporterName, "name" ); - - cli["-n"]["--name"] - .describe( "suite name" ) - .bind( &ConfigData::name, "name" ); - - cli["-a"]["--abort"] - .describe( "abort at first failure" ) - .bind( &abortAfterFirst ); - - cli["-x"]["--abortx"] - .describe( "abort after x failures" ) - .bind( &abortAfterX, "no. failures" ); - - cli["-w"]["--warn"] - .describe( "enable warnings" ) - .bind( &addWarning, "warning name" ); - -// - needs updating if reinstated -// cli.into( &setVerbosity ) -// .describe( "level of verbosity (0=no output)" ) -// .shortOpt( "v") -// .longOpt( "verbosity" ) -// .placeholder( "level" ); - - cli[_] - .describe( "which test or tests to use" ) - .bind( &addTestOrTags, "test name, pattern or tags" ); - - cli["-d"]["--durations"] - .describe( "show test durations" ) - .bind( &setShowDurations, "yes/no" ); - - cli["-f"]["--input-file"] - .describe( "load test names to run from a file" ) - .bind( &loadTestNamesFromFile, "filename" ); - - // Less common commands which don't have a short form - cli["--list-test-names-only"] - .describe( "list all/matching test cases names only" ) - .bind( &ConfigData::listTestNamesOnly ); - - cli["--list-reporters"] - .describe( "list all reporters" ) - .bind( &ConfigData::listReporters ); - - cli["--order"] - .describe( "test case order (defaults to decl)" ) - .bind( &setOrder, "decl|lex|rand" ); - - cli["--rng-seed"] - .describe( "set a specific seed for random numbers" ) - .bind( &setRngSeed, "'time'|number" ); - - cli["--force-colour"] - .describe( "force colourised output" ) - .bind( &ConfigData::forceColour ); - - return cli; - } - -} // end namespace Catch - -// #included from: internal/catch_list.hpp -#define TWOBLUECUBES_CATCH_LIST_HPP_INCLUDED - -// #included from: catch_text.h -#define TWOBLUECUBES_CATCH_TEXT_H_INCLUDED - -#define TBC_TEXT_FORMAT_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH - -#define CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE Catch -// #included from: ../external/tbc_text_format.h -// Only use header guard if we are not using an outer namespace -#ifndef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE -# ifdef TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED -# ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -# define TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -# endif -# else -# define TWOBLUECUBES_TEXT_FORMAT_H_INCLUDED -# endif -#endif -#ifndef TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -#include <string> -#include <vector> -#include <sstream> - -// Use optional outer namespace -#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE -namespace CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE { -#endif - -namespace Tbc { - -#ifdef TBC_TEXT_FORMAT_CONSOLE_WIDTH - const unsigned int consoleWidth = TBC_TEXT_FORMAT_CONSOLE_WIDTH; -#else - const unsigned int consoleWidth = 80; -#endif - - struct TextAttributes { - TextAttributes() - : initialIndent( std::string::npos ), - indent( 0 ), - width( consoleWidth-1 ), - tabChar( '\t' ) - {} - - TextAttributes& setInitialIndent( std::size_t _value ) { initialIndent = _value; return *this; } - TextAttributes& setIndent( std::size_t _value ) { indent = _value; return *this; } - TextAttributes& setWidth( std::size_t _value ) { width = _value; return *this; } - TextAttributes& setTabChar( char _value ) { tabChar = _value; return *this; } - - std::size_t initialIndent; // indent of first line, or npos - std::size_t indent; // indent of subsequent lines, or all if initialIndent is npos - std::size_t width; // maximum width of text, including indent. Longer text will wrap - char tabChar; // If this char is seen the indent is changed to current pos - }; - - class Text { - public: - Text( std::string const& _str, TextAttributes const& _attr = TextAttributes() ) - : attr( _attr ) - { - std::string wrappableChars = " [({.,/|\\-"; - std::size_t indent = _attr.initialIndent != std::string::npos - ? _attr.initialIndent - : _attr.indent; - std::string remainder = _str; - - while( !remainder.empty() ) { - if( lines.size() >= 1000 ) { - lines.push_back( "... message truncated due to excessive size" ); - return; - } - std::size_t tabPos = std::string::npos; - std::size_t width = (std::min)( remainder.size(), _attr.width - indent ); - std::size_t pos = remainder.find_first_of( '\n' ); - if( pos <= width ) { - width = pos; - } - pos = remainder.find_last_of( _attr.tabChar, width ); - if( pos != std::string::npos ) { - tabPos = pos; - if( remainder[width] == '\n' ) - width--; - remainder = remainder.substr( 0, tabPos ) + remainder.substr( tabPos+1 ); - } - - if( width == remainder.size() ) { - spliceLine( indent, remainder, width ); - } - else if( remainder[width] == '\n' ) { - spliceLine( indent, remainder, width ); - if( width <= 1 || remainder.size() != 1 ) - remainder = remainder.substr( 1 ); - indent = _attr.indent; - } - else { - pos = remainder.find_last_of( wrappableChars, width ); - if( pos != std::string::npos && pos > 0 ) { - spliceLine( indent, remainder, pos ); - if( remainder[0] == ' ' ) - remainder = remainder.substr( 1 ); - } - else { - spliceLine( indent, remainder, width-1 ); - lines.back() += "-"; - } - if( lines.size() == 1 ) - indent = _attr.indent; - if( tabPos != std::string::npos ) - indent += tabPos; - } - } - } - - void spliceLine( std::size_t _indent, std::string& _remainder, std::size_t _pos ) { - lines.push_back( std::string( _indent, ' ' ) + _remainder.substr( 0, _pos ) ); - _remainder = _remainder.substr( _pos ); - } - - typedef std::vector<std::string>::const_iterator const_iterator; - - const_iterator begin() const { return lines.begin(); } - const_iterator end() const { return lines.end(); } - std::string const& last() const { return lines.back(); } - std::size_t size() const { return lines.size(); } - std::string const& operator[]( std::size_t _index ) const { return lines[_index]; } - std::string toString() const { - std::ostringstream oss; - oss << *this; - return oss.str(); - } - - inline friend std::ostream& operator << ( std::ostream& _stream, Text const& _text ) { - for( Text::const_iterator it = _text.begin(), itEnd = _text.end(); - it != itEnd; ++it ) { - if( it != _text.begin() ) - _stream << "\n"; - _stream << *it; - } - return _stream; - } - - private: - std::string str; - TextAttributes attr; - std::vector<std::string> lines; - }; - -} // end namespace Tbc - -#ifdef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE -} // end outer namespace -#endif - -#endif // TWOBLUECUBES_TEXT_FORMAT_H_ALREADY_INCLUDED -#undef CLICHE_TBC_TEXT_FORMAT_OUTER_NAMESPACE - -namespace Catch { - using Tbc::Text; - using Tbc::TextAttributes; -} - -// #included from: catch_console_colour.hpp -#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_HPP_INCLUDED - -namespace Catch { - - struct Colour { - enum Code { - None = 0, - - White, - Red, - Green, - Blue, - Cyan, - Yellow, - Grey, - - Bright = 0x10, - - BrightRed = Bright | Red, - BrightGreen = Bright | Green, - LightGrey = Bright | Grey, - BrightWhite = Bright | White, - - // By intention - FileName = LightGrey, - Warning = Yellow, - ResultError = BrightRed, - ResultSuccess = BrightGreen, - ResultExpectedFailure = Warning, - - Error = BrightRed, - Success = Green, - - OriginalExpression = Cyan, - ReconstructedExpression = Yellow, - - SecondaryText = LightGrey, - Headers = White - }; - - // Use constructed object for RAII guard - Colour( Code _colourCode ); - Colour( Colour const& other ); - ~Colour(); - - // Use static method for one-shot changes - static void use( Code _colourCode ); - - private: - bool m_moved; - }; - - inline std::ostream& operator << ( std::ostream& os, Colour const& ) { return os; } - -} // end namespace Catch - -// #included from: catch_interfaces_reporter.h -#define TWOBLUECUBES_CATCH_INTERFACES_REPORTER_H_INCLUDED - -#include <string> -#include <ostream> -#include <map> -#include <assert.h> - -namespace Catch -{ - struct ReporterConfig { - explicit ReporterConfig( Ptr<IConfig> const& _fullConfig ) - : m_stream( &_fullConfig->stream() ), m_fullConfig( _fullConfig ) {} - - ReporterConfig( Ptr<IConfig> const& _fullConfig, std::ostream& _stream ) - : m_stream( &_stream ), m_fullConfig( _fullConfig ) {} - - std::ostream& stream() const { return *m_stream; } - Ptr<IConfig> fullConfig() const { return m_fullConfig; } - - private: - std::ostream* m_stream; - Ptr<IConfig> m_fullConfig; - }; - - struct ReporterPreferences { - ReporterPreferences() - : shouldRedirectStdOut( false ) - {} - - bool shouldRedirectStdOut; - }; - - template<typename T> - struct LazyStat : Option<T> { - LazyStat() : used( false ) {} - LazyStat& operator=( T const& _value ) { - Option<T>::operator=( _value ); - used = false; - return *this; - } - void reset() { - Option<T>::reset(); - used = false; - } - bool used; - }; - - struct TestRunInfo { - TestRunInfo( std::string const& _name ) : name( _name ) {} - std::string name; - }; - struct GroupInfo { - GroupInfo( std::string const& _name, - std::size_t _groupIndex, - std::size_t _groupsCount ) - : name( _name ), - groupIndex( _groupIndex ), - groupsCounts( _groupsCount ) - {} - - std::string name; - std::size_t groupIndex; - std::size_t groupsCounts; - }; - - struct AssertionStats { - AssertionStats( AssertionResult const& _assertionResult, - std::vector<MessageInfo> const& _infoMessages, - Totals const& _totals ) - : assertionResult( _assertionResult ), - infoMessages( _infoMessages ), - totals( _totals ) - { - if( assertionResult.hasMessage() ) { - // Copy message into messages list. - // !TBD This should have been done earlier, somewhere - MessageBuilder builder( assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), assertionResult.getResultType() ); - builder << assertionResult.getMessage(); - builder.m_info.message = builder.m_stream.str(); - - infoMessages.push_back( builder.m_info ); - } - } - virtual ~AssertionStats(); - -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - AssertionStats( AssertionStats const& ) = default; - AssertionStats( AssertionStats && ) = default; - AssertionStats& operator = ( AssertionStats const& ) = default; - AssertionStats& operator = ( AssertionStats && ) = default; -# endif - - AssertionResult assertionResult; - std::vector<MessageInfo> infoMessages; - Totals totals; - }; - - struct SectionStats { - SectionStats( SectionInfo const& _sectionInfo, - Counts const& _assertions, - double _durationInSeconds, - bool _missingAssertions ) - : sectionInfo( _sectionInfo ), - assertions( _assertions ), - durationInSeconds( _durationInSeconds ), - missingAssertions( _missingAssertions ) - {} - virtual ~SectionStats(); -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - SectionStats( SectionStats const& ) = default; - SectionStats( SectionStats && ) = default; - SectionStats& operator = ( SectionStats const& ) = default; - SectionStats& operator = ( SectionStats && ) = default; -# endif - - SectionInfo sectionInfo; - Counts assertions; - double durationInSeconds; - bool missingAssertions; - }; - - struct TestCaseStats { - TestCaseStats( TestCaseInfo const& _testInfo, - Totals const& _totals, - std::string const& _stdOut, - std::string const& _stdErr, - bool _aborting ) - : testInfo( _testInfo ), - totals( _totals ), - stdOut( _stdOut ), - stdErr( _stdErr ), - aborting( _aborting ) - {} - virtual ~TestCaseStats(); - -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - TestCaseStats( TestCaseStats const& ) = default; - TestCaseStats( TestCaseStats && ) = default; - TestCaseStats& operator = ( TestCaseStats const& ) = default; - TestCaseStats& operator = ( TestCaseStats && ) = default; -# endif - - TestCaseInfo testInfo; - Totals totals; - std::string stdOut; - std::string stdErr; - bool aborting; - }; - - struct TestGroupStats { - TestGroupStats( GroupInfo const& _groupInfo, - Totals const& _totals, - bool _aborting ) - : groupInfo( _groupInfo ), - totals( _totals ), - aborting( _aborting ) - {} - TestGroupStats( GroupInfo const& _groupInfo ) - : groupInfo( _groupInfo ), - aborting( false ) - {} - virtual ~TestGroupStats(); - -# ifdef CATCH_CONFIG_CPP11_GENERATED_METHODS - TestGroupStats( TestGroupStats const& ) = default; - TestGroupStats( TestGroupStats && ) = default; - TestGroupStats& operator = ( TestGroupStats const& ) = default; - TestGroupStats& operator = ( TestGroupStats && ) = default; -# endif - - GroupInfo groupInfo; - Totals totals; - bool aborting; - }; - - struct TestRunStats { - TestRunStats( TestRunInfo const& _runInfo, - Totals const& _totals, - bool _aborting ) - : runInfo( _runInfo ), - totals( _totals ), - aborting( _aborting ) - {} - virtual ~TestRunStats(); - -# ifndef CATCH_CONFIG_CPP11_GENERATED_METHODS - TestRunStats( TestRunStats const& _other ) - : runInfo( _other.runInfo ), - totals( _other.totals ), - aborting( _other.aborting ) - {} -# else - TestRunStats( TestRunStats const& ) = default; - TestRunStats( TestRunStats && ) = default; - TestRunStats& operator = ( TestRunStats const& ) = default; - TestRunStats& operator = ( TestRunStats && ) = default; -# endif - - TestRunInfo runInfo; - Totals totals; - bool aborting; - }; - - struct IStreamingReporter : IShared { - virtual ~IStreamingReporter(); - - // Implementing class must also provide the following static method: - // static std::string getDescription(); - - virtual ReporterPreferences getPreferences() const = 0; - - virtual void noMatchingTestCases( std::string const& spec ) = 0; - - virtual void testRunStarting( TestRunInfo const& testRunInfo ) = 0; - virtual void testGroupStarting( GroupInfo const& groupInfo ) = 0; - - virtual void testCaseStarting( TestCaseInfo const& testInfo ) = 0; - virtual void sectionStarting( SectionInfo const& sectionInfo ) = 0; - - virtual void assertionStarting( AssertionInfo const& assertionInfo ) = 0; - - // The return value indicates if the messages buffer should be cleared: - virtual bool assertionEnded( AssertionStats const& assertionStats ) = 0; - virtual void sectionEnded( SectionStats const& sectionStats ) = 0; - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) = 0; - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) = 0; - virtual void testRunEnded( TestRunStats const& testRunStats ) = 0; - - virtual void skipTest( TestCaseInfo const& testInfo ) = 0; - }; - - struct IReporterFactory { - virtual ~IReporterFactory(); - virtual IStreamingReporter* create( ReporterConfig const& config ) const = 0; - virtual std::string getDescription() const = 0; - }; - - struct IReporterRegistry { - typedef std::map<std::string, IReporterFactory*> FactoryMap; - - virtual ~IReporterRegistry(); - virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const = 0; - virtual FactoryMap const& getFactories() const = 0; - }; - -} - -#include <limits> -#include <algorithm> - -namespace Catch { - - inline std::size_t listTests( Config const& config ) { - - TestSpec testSpec = config.testSpec(); - if( config.testSpec().hasFilters() ) - Catch::cout() << "Matching test cases:\n"; - else { - Catch::cout() << "All available test cases:\n"; - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); - } - - std::size_t matchedTests = 0; - TextAttributes nameAttr, tagsAttr; - nameAttr.setInitialIndent( 2 ).setIndent( 4 ); - tagsAttr.setIndent( 6 ); - - std::vector<TestCase> matchedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases ); - for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); - it != itEnd; - ++it ) { - matchedTests++; - TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); - Colour::Code colour = testCaseInfo.isHidden() - ? Colour::SecondaryText - : Colour::None; - Colour colourGuard( colour ); - - Catch::cout() << Text( testCaseInfo.name, nameAttr ) << std::endl; - if( !testCaseInfo.tags.empty() ) - Catch::cout() << Text( testCaseInfo.tagsAsString, tagsAttr ) << std::endl; - } - - if( !config.testSpec().hasFilters() ) - Catch::cout() << pluralise( matchedTests, "test case" ) << "\n" << std::endl; - else - Catch::cout() << pluralise( matchedTests, "matching test case" ) << "\n" << std::endl; - return matchedTests; - } - - inline std::size_t listTestsNamesOnly( Config const& config ) { - TestSpec testSpec = config.testSpec(); - if( !config.testSpec().hasFilters() ) - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); - std::size_t matchedTests = 0; - std::vector<TestCase> matchedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases ); - for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); - it != itEnd; - ++it ) { - matchedTests++; - TestCaseInfo const& testCaseInfo = it->getTestCaseInfo(); - Catch::cout() << testCaseInfo.name << std::endl; - } - return matchedTests; - } - - struct TagInfo { - TagInfo() : count ( 0 ) {} - void add( std::string const& spelling ) { - ++count; - spellings.insert( spelling ); - } - std::string all() const { - std::string out; - for( std::set<std::string>::const_iterator it = spellings.begin(), itEnd = spellings.end(); - it != itEnd; - ++it ) - out += "[" + *it + "]"; - return out; - } - std::set<std::string> spellings; - std::size_t count; - }; - - inline std::size_t listTags( Config const& config ) { - TestSpec testSpec = config.testSpec(); - if( config.testSpec().hasFilters() ) - Catch::cout() << "Tags for matching test cases:\n"; - else { - Catch::cout() << "All available tags:\n"; - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "*" ).testSpec(); - } - - std::map<std::string, TagInfo> tagCounts; - - std::vector<TestCase> matchedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, config, matchedTestCases ); - for( std::vector<TestCase>::const_iterator it = matchedTestCases.begin(), itEnd = matchedTestCases.end(); - it != itEnd; - ++it ) { - for( std::set<std::string>::const_iterator tagIt = it->getTestCaseInfo().tags.begin(), - tagItEnd = it->getTestCaseInfo().tags.end(); - tagIt != tagItEnd; - ++tagIt ) { - std::string tagName = *tagIt; - std::string lcaseTagName = toLower( tagName ); - std::map<std::string, TagInfo>::iterator countIt = tagCounts.find( lcaseTagName ); - if( countIt == tagCounts.end() ) - countIt = tagCounts.insert( std::make_pair( lcaseTagName, TagInfo() ) ).first; - countIt->second.add( tagName ); - } - } - - for( std::map<std::string, TagInfo>::const_iterator countIt = tagCounts.begin(), - countItEnd = tagCounts.end(); - countIt != countItEnd; - ++countIt ) { - std::ostringstream oss; - oss << " " << std::setw(2) << countIt->second.count << " "; - Text wrapper( countIt->second.all(), TextAttributes() - .setInitialIndent( 0 ) - .setIndent( oss.str().size() ) - .setWidth( CATCH_CONFIG_CONSOLE_WIDTH-10 ) ); - Catch::cout() << oss.str() << wrapper << "\n"; - } - Catch::cout() << pluralise( tagCounts.size(), "tag" ) << "\n" << std::endl; - return tagCounts.size(); - } - - inline std::size_t listReporters( Config const& /*config*/ ) { - Catch::cout() << "Available reporters:\n"; - IReporterRegistry::FactoryMap const& factories = getRegistryHub().getReporterRegistry().getFactories(); - IReporterRegistry::FactoryMap::const_iterator itBegin = factories.begin(), itEnd = factories.end(), it; - std::size_t maxNameLen = 0; - for(it = itBegin; it != itEnd; ++it ) - maxNameLen = (std::max)( maxNameLen, it->first.size() ); - - for(it = itBegin; it != itEnd; ++it ) { - Text wrapper( it->second->getDescription(), TextAttributes() - .setInitialIndent( 0 ) - .setIndent( 7+maxNameLen ) - .setWidth( CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen-8 ) ); - Catch::cout() << " " - << it->first - << ":" - << std::string( maxNameLen - it->first.size() + 2, ' ' ) - << wrapper << "\n"; - } - Catch::cout() << std::endl; - return factories.size(); - } - - inline Option<std::size_t> list( Config const& config ) { - Option<std::size_t> listedCount; - if( config.listTests() ) - listedCount = listedCount.valueOr(0) + listTests( config ); - if( config.listTestNamesOnly() ) - listedCount = listedCount.valueOr(0) + listTestsNamesOnly( config ); - if( config.listTags() ) - listedCount = listedCount.valueOr(0) + listTags( config ); - if( config.listReporters() ) - listedCount = listedCount.valueOr(0) + listReporters( config ); - return listedCount; - } - -} // end namespace Catch - -// #included from: internal/catch_runner_impl.hpp -#define TWOBLUECUBES_CATCH_RUNNER_IMPL_HPP_INCLUDED - -// #included from: catch_test_case_tracker.hpp -#define TWOBLUECUBES_CATCH_TEST_CASE_TRACKER_HPP_INCLUDED - -#include <map> -#include <string> -#include <assert.h> - -namespace Catch { -namespace SectionTracking { - - class TrackedSection { - - typedef std::map<std::string, TrackedSection> TrackedSections; - - public: - enum RunState { - NotStarted, - Executing, - ExecutingChildren, - Completed - }; - - TrackedSection( std::string const& name, TrackedSection* parent ) - : m_name( name ), m_runState( NotStarted ), m_parent( parent ) - {} - - RunState runState() const { return m_runState; } - - TrackedSection* findChild( std::string const& childName ) { - TrackedSections::iterator it = m_children.find( childName ); - return it != m_children.end() - ? &it->second - : NULL; - } - TrackedSection* acquireChild( std::string const& childName ) { - if( TrackedSection* child = findChild( childName ) ) - return child; - m_children.insert( std::make_pair( childName, TrackedSection( childName, this ) ) ); - return findChild( childName ); - } - void enter() { - if( m_runState == NotStarted ) - m_runState = Executing; - } - void leave() { - for( TrackedSections::const_iterator it = m_children.begin(), itEnd = m_children.end(); - it != itEnd; - ++it ) - if( it->second.runState() != Completed ) { - m_runState = ExecutingChildren; - return; - } - m_runState = Completed; - } - TrackedSection* getParent() { - return m_parent; - } - bool hasChildren() const { - return !m_children.empty(); - } - - private: - std::string m_name; - RunState m_runState; - TrackedSections m_children; - TrackedSection* m_parent; - - }; - - class TestCaseTracker { - public: - TestCaseTracker( std::string const& testCaseName ) - : m_testCase( testCaseName, NULL ), - m_currentSection( &m_testCase ), - m_completedASectionThisRun( false ) - {} - - bool enterSection( std::string const& name ) { - TrackedSection* child = m_currentSection->acquireChild( name ); - if( m_completedASectionThisRun || child->runState() == TrackedSection::Completed ) - return false; - - m_currentSection = child; - m_currentSection->enter(); - return true; - } - void leaveSection() { - m_currentSection->leave(); - m_currentSection = m_currentSection->getParent(); - assert( m_currentSection != NULL ); - m_completedASectionThisRun = true; - } - - bool currentSectionHasChildren() const { - return m_currentSection->hasChildren(); - } - bool isCompleted() const { - return m_testCase.runState() == TrackedSection::Completed; - } - - class Guard { - public: - Guard( TestCaseTracker& tracker ) : m_tracker( tracker ) { - m_tracker.enterTestCase(); - } - ~Guard() { - m_tracker.leaveTestCase(); - } - private: - Guard( Guard const& ); - void operator = ( Guard const& ); - TestCaseTracker& m_tracker; - }; - - private: - void enterTestCase() { - m_currentSection = &m_testCase; - m_completedASectionThisRun = false; - m_testCase.enter(); - } - void leaveTestCase() { - m_testCase.leave(); - } - - TrackedSection m_testCase; - TrackedSection* m_currentSection; - bool m_completedASectionThisRun; - }; - -} // namespace SectionTracking - -using SectionTracking::TestCaseTracker; - -} // namespace Catch - -// #included from: catch_fatal_condition.hpp -#define TWOBLUECUBES_CATCH_FATAL_CONDITION_H_INCLUDED - -namespace Catch { - - // Report the error condition then exit the process - inline void fatal( std::string const& message, int exitCode ) { - IContext& context = Catch::getCurrentContext(); - IResultCapture* resultCapture = context.getResultCapture(); - resultCapture->handleFatalErrorCondition( message ); - - if( Catch::alwaysTrue() ) // avoids "no return" warnings - exit( exitCode ); - } - -} // namespace Catch - -#if defined ( CATCH_PLATFORM_WINDOWS ) ///////////////////////////////////////// - -namespace Catch { - - struct FatalConditionHandler { - void reset() {} - }; - -} // namespace Catch - -#else // Not Windows - assumed to be POSIX compatible ////////////////////////// - -#include <signal.h> - -namespace Catch { - - struct SignalDefs { int id; const char* name; }; - extern SignalDefs signalDefs[]; - SignalDefs signalDefs[] = { - { SIGINT, "SIGINT - Terminal interrupt signal" }, - { SIGILL, "SIGILL - Illegal instruction signal" }, - { SIGFPE, "SIGFPE - Floating point error signal" }, - { SIGSEGV, "SIGSEGV - Segmentation violation signal" }, - { SIGTERM, "SIGTERM - Termination request signal" }, - { SIGABRT, "SIGABRT - Abort (abnormal termination) signal" } - }; - - struct FatalConditionHandler { - - static void handleSignal( int sig ) { - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) - if( sig == signalDefs[i].id ) - fatal( signalDefs[i].name, -sig ); - fatal( "<unknown signal>", -sig ); - } - - FatalConditionHandler() : m_isSet( true ) { - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) - signal( signalDefs[i].id, handleSignal ); - } - ~FatalConditionHandler() { - reset(); - } - void reset() { - if( m_isSet ) { - for( std::size_t i = 0; i < sizeof(signalDefs)/sizeof(SignalDefs); ++i ) - signal( signalDefs[i].id, SIG_DFL ); - m_isSet = false; - } - } - - bool m_isSet; - }; - -} // namespace Catch - -#endif // not Windows - -#include <set> -#include <string> - -namespace Catch { - - class StreamRedirect { - - public: - StreamRedirect( std::ostream& stream, std::string& targetString ) - : m_stream( stream ), - m_prevBuf( stream.rdbuf() ), - m_targetString( targetString ) - { - stream.rdbuf( m_oss.rdbuf() ); - } - - ~StreamRedirect() { - m_targetString += m_oss.str(); - m_stream.rdbuf( m_prevBuf ); - } - - private: - std::ostream& m_stream; - std::streambuf* m_prevBuf; - std::ostringstream m_oss; - std::string& m_targetString; - }; - - /////////////////////////////////////////////////////////////////////////// - - class RunContext : public IResultCapture, public IRunner { - - RunContext( RunContext const& ); - void operator =( RunContext const& ); - - public: - - explicit RunContext( Ptr<IConfig const> const& config, Ptr<IStreamingReporter> const& reporter ) - : m_runInfo( config->name() ), - m_context( getCurrentMutableContext() ), - m_activeTestCase( NULL ), - m_config( config ), - m_reporter( reporter ), - m_prevRunner( m_context.getRunner() ), - m_prevResultCapture( m_context.getResultCapture() ), - m_prevConfig( m_context.getConfig() ) - { - m_context.setRunner( this ); - m_context.setConfig( m_config ); - m_context.setResultCapture( this ); - m_reporter->testRunStarting( m_runInfo ); - } - - virtual ~RunContext() { - m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, aborting() ) ); - m_context.setRunner( m_prevRunner ); - m_context.setConfig( NULL ); - m_context.setResultCapture( m_prevResultCapture ); - m_context.setConfig( m_prevConfig ); - } - - void testGroupStarting( std::string const& testSpec, std::size_t groupIndex, std::size_t groupsCount ) { - m_reporter->testGroupStarting( GroupInfo( testSpec, groupIndex, groupsCount ) ); - } - void testGroupEnded( std::string const& testSpec, Totals const& totals, std::size_t groupIndex, std::size_t groupsCount ) { - m_reporter->testGroupEnded( TestGroupStats( GroupInfo( testSpec, groupIndex, groupsCount ), totals, aborting() ) ); - } - - Totals runTest( TestCase const& testCase ) { - Totals prevTotals = m_totals; - - std::string redirectedCout; - std::string redirectedCerr; - - TestCaseInfo testInfo = testCase.getTestCaseInfo(); - - m_reporter->testCaseStarting( testInfo ); - - m_activeTestCase = &testCase; - m_testCaseTracker = TestCaseTracker( testInfo.name ); - - do { - do { - runCurrentTest( redirectedCout, redirectedCerr ); - } - while( !m_testCaseTracker->isCompleted() && !aborting() ); - } - while( getCurrentContext().advanceGeneratorsForCurrentTest() && !aborting() ); - - Totals deltaTotals = m_totals.delta( prevTotals ); - m_totals.testCases += deltaTotals.testCases; - m_reporter->testCaseEnded( TestCaseStats( testInfo, - deltaTotals, - redirectedCout, - redirectedCerr, - aborting() ) ); - - m_activeTestCase = NULL; - m_testCaseTracker.reset(); - - return deltaTotals; - } - - Ptr<IConfig const> config() const { - return m_config; - } - - private: // IResultCapture - - virtual void assertionEnded( AssertionResult const& result ) { - if( result.getResultType() == ResultWas::Ok ) { - m_totals.assertions.passed++; - } - else if( !result.isOk() ) { - m_totals.assertions.failed++; - } - - if( m_reporter->assertionEnded( AssertionStats( result, m_messages, m_totals ) ) ) - m_messages.clear(); - - // Reset working state - m_lastAssertionInfo = AssertionInfo( "", m_lastAssertionInfo.lineInfo, "{Unknown expression after the reported line}" , m_lastAssertionInfo.resultDisposition ); - m_lastResult = result; - } - - virtual bool sectionStarted ( - SectionInfo const& sectionInfo, - Counts& assertions - ) - { - std::ostringstream oss; - oss << sectionInfo.name << "@" << sectionInfo.lineInfo; - - if( !m_testCaseTracker->enterSection( oss.str() ) ) - return false; - - m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; - - m_reporter->sectionStarting( sectionInfo ); - - assertions = m_totals.assertions; - - return true; - } - bool testForMissingAssertions( Counts& assertions ) { - if( assertions.total() != 0 || - !m_config->warnAboutMissingAssertions() || - m_testCaseTracker->currentSectionHasChildren() ) - return false; - m_totals.assertions.failed++; - assertions.failed++; - return true; - } - - virtual void sectionEnded( SectionInfo const& info, Counts const& prevAssertions, double _durationInSeconds ) { - if( std::uncaught_exception() ) { - m_unfinishedSections.push_back( UnfinishedSections( info, prevAssertions, _durationInSeconds ) ); - return; - } - - Counts assertions = m_totals.assertions - prevAssertions; - bool missingAssertions = testForMissingAssertions( assertions ); - - m_testCaseTracker->leaveSection(); - - m_reporter->sectionEnded( SectionStats( info, assertions, _durationInSeconds, missingAssertions ) ); - m_messages.clear(); - } - - virtual void pushScopedMessage( MessageInfo const& message ) { - m_messages.push_back( message ); - } - - virtual void popScopedMessage( MessageInfo const& message ) { - m_messages.erase( std::remove( m_messages.begin(), m_messages.end(), message ), m_messages.end() ); - } - - virtual std::string getCurrentTestName() const { - return m_activeTestCase - ? m_activeTestCase->getTestCaseInfo().name - : ""; - } - - virtual const AssertionResult* getLastResult() const { - return &m_lastResult; - } - - virtual void handleFatalErrorCondition( std::string const& message ) { - ResultBuilder resultBuilder = makeUnexpectedResultBuilder(); - resultBuilder.setResultType( ResultWas::FatalErrorCondition ); - resultBuilder << message; - resultBuilder.captureExpression(); - - handleUnfinishedSections(); - - // Recreate section for test case (as we will lose the one that was in scope) - TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); - SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); - - Counts assertions; - assertions.failed = 1; - SectionStats testCaseSectionStats( testCaseSection, assertions, 0, false ); - m_reporter->sectionEnded( testCaseSectionStats ); - - TestCaseInfo testInfo = m_activeTestCase->getTestCaseInfo(); - - Totals deltaTotals; - deltaTotals.testCases.failed = 1; - m_reporter->testCaseEnded( TestCaseStats( testInfo, - deltaTotals, - "", - "", - false ) ); - m_totals.testCases.failed++; - testGroupEnded( "", m_totals, 1, 1 ); - m_reporter->testRunEnded( TestRunStats( m_runInfo, m_totals, false ) ); - } - - public: - // !TBD We need to do this another way! - bool aborting() const { - return m_totals.assertions.failed == static_cast<std::size_t>( m_config->abortAfter() ); - } - - private: - - void runCurrentTest( std::string& redirectedCout, std::string& redirectedCerr ) { - TestCaseInfo const& testCaseInfo = m_activeTestCase->getTestCaseInfo(); - SectionInfo testCaseSection( testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description ); - m_reporter->sectionStarting( testCaseSection ); - Counts prevAssertions = m_totals.assertions; - double duration = 0; - try { - m_lastAssertionInfo = AssertionInfo( "TEST_CASE", testCaseInfo.lineInfo, "", ResultDisposition::Normal ); - TestCaseTracker::Guard guard( *m_testCaseTracker ); - - Timer timer; - timer.start(); - if( m_reporter->getPreferences().shouldRedirectStdOut ) { - StreamRedirect coutRedir( Catch::cout(), redirectedCout ); - StreamRedirect cerrRedir( Catch::cerr(), redirectedCerr ); - invokeActiveTestCase(); - } - else { - invokeActiveTestCase(); - } - duration = timer.getElapsedSeconds(); - } - catch( TestFailureException& ) { - // This just means the test was aborted due to failure - } - catch(...) { - makeUnexpectedResultBuilder().useActiveException(); - } - handleUnfinishedSections(); - m_messages.clear(); - - Counts assertions = m_totals.assertions - prevAssertions; - bool missingAssertions = testForMissingAssertions( assertions ); - - if( testCaseInfo.okToFail() ) { - std::swap( assertions.failedButOk, assertions.failed ); - m_totals.assertions.failed -= assertions.failedButOk; - m_totals.assertions.failedButOk += assertions.failedButOk; - } - - SectionStats testCaseSectionStats( testCaseSection, assertions, duration, missingAssertions ); - m_reporter->sectionEnded( testCaseSectionStats ); - } - - void invokeActiveTestCase() { - FatalConditionHandler fatalConditionHandler; // Handle signals - m_activeTestCase->invoke(); - fatalConditionHandler.reset(); - } - - private: - - ResultBuilder makeUnexpectedResultBuilder() const { - return ResultBuilder( m_lastAssertionInfo.macroName.c_str(), - m_lastAssertionInfo.lineInfo, - m_lastAssertionInfo.capturedExpression.c_str(), - m_lastAssertionInfo.resultDisposition ); - } - - void handleUnfinishedSections() { - // If sections ended prematurely due to an exception we stored their - // infos here so we can tear them down outside the unwind process. - for( std::vector<UnfinishedSections>::const_reverse_iterator it = m_unfinishedSections.rbegin(), - itEnd = m_unfinishedSections.rend(); - it != itEnd; - ++it ) - sectionEnded( it->info, it->prevAssertions, it->durationInSeconds ); - m_unfinishedSections.clear(); - } - - struct UnfinishedSections { - UnfinishedSections( SectionInfo const& _info, Counts const& _prevAssertions, double _durationInSeconds ) - : info( _info ), prevAssertions( _prevAssertions ), durationInSeconds( _durationInSeconds ) - {} - - SectionInfo info; - Counts prevAssertions; - double durationInSeconds; - }; - - TestRunInfo m_runInfo; - IMutableContext& m_context; - TestCase const* m_activeTestCase; - Option<TestCaseTracker> m_testCaseTracker; - AssertionResult m_lastResult; - - Ptr<IConfig const> m_config; - Totals m_totals; - Ptr<IStreamingReporter> m_reporter; - std::vector<MessageInfo> m_messages; - IRunner* m_prevRunner; - IResultCapture* m_prevResultCapture; - Ptr<IConfig const> m_prevConfig; - AssertionInfo m_lastAssertionInfo; - std::vector<UnfinishedSections> m_unfinishedSections; - }; - - IResultCapture& getResultCapture() { - if( IResultCapture* capture = getCurrentContext().getResultCapture() ) - return *capture; - else - throw std::logic_error( "No result capture instance" ); - } - -} // end namespace Catch - -// #included from: internal/catch_version.h -#define TWOBLUECUBES_CATCH_VERSION_H_INCLUDED - -namespace Catch { - - // Versioning information - struct Version { - Version( unsigned int _majorVersion, - unsigned int _minorVersion, - unsigned int _buildNumber, - char const* const _branchName ) - : majorVersion( _majorVersion ), - minorVersion( _minorVersion ), - buildNumber( _buildNumber ), - branchName( _branchName ) - {} - - unsigned int const majorVersion; - unsigned int const minorVersion; - unsigned int const buildNumber; - char const* const branchName; - - private: - void operator=( Version const& ); - }; - - extern Version libraryVersion; -} - -#include <fstream> -#include <stdlib.h> -#include <limits> - -namespace Catch { - - class Runner { - - public: - Runner( Ptr<Config> const& config ) - : m_config( config ) - { - openStream(); - makeReporter(); - } - - Totals runTests() { - - RunContext context( m_config.get(), m_reporter ); - - Totals totals; - - context.testGroupStarting( "all tests", 1, 1 ); // deprecated? - - TestSpec testSpec = m_config->testSpec(); - if( !testSpec.hasFilters() ) - testSpec = TestSpecParser( ITagAliasRegistry::get() ).parse( "~[.]" ).testSpec(); // All not hidden tests - - std::vector<TestCase> testCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, testCases ); - - int testsRunForGroup = 0; - for( std::vector<TestCase>::const_iterator it = testCases.begin(), itEnd = testCases.end(); - it != itEnd; - ++it ) { - testsRunForGroup++; - if( m_testsAlreadyRun.find( *it ) == m_testsAlreadyRun.end() ) { - - if( context.aborting() ) - break; - - totals += context.runTest( *it ); - m_testsAlreadyRun.insert( *it ); - } - } - std::vector<TestCase> skippedTestCases; - getRegistryHub().getTestCaseRegistry().getFilteredTests( testSpec, *m_config, skippedTestCases, true ); - - for( std::vector<TestCase>::const_iterator it = skippedTestCases.begin(), itEnd = skippedTestCases.end(); - it != itEnd; - ++it ) - m_reporter->skipTest( *it ); - - context.testGroupEnded( "all tests", totals, 1, 1 ); - return totals; - } - - private: - void openStream() { - // Open output file, if specified - if( !m_config->getFilename().empty() ) { - m_ofs.open( m_config->getFilename().c_str() ); - if( m_ofs.fail() ) { - std::ostringstream oss; - oss << "Unable to open file: '" << m_config->getFilename() << "'"; - throw std::domain_error( oss.str() ); - } - m_config->setStreamBuf( m_ofs.rdbuf() ); - } - } - void makeReporter() { - std::string reporterName = m_config->getReporterName().empty() - ? "console" - : m_config->getReporterName(); - - m_reporter = getRegistryHub().getReporterRegistry().create( reporterName, m_config.get() ); - if( !m_reporter ) { - std::ostringstream oss; - oss << "No reporter registered with name: '" << reporterName << "'"; - throw std::domain_error( oss.str() ); - } - } - - private: - Ptr<Config> m_config; - std::ofstream m_ofs; - Ptr<IStreamingReporter> m_reporter; - std::set<TestCase> m_testsAlreadyRun; - }; - - class Session : NonCopyable { - static bool alreadyInstantiated; - - public: - - struct OnUnusedOptions { enum DoWhat { Ignore, Fail }; }; - - Session() - : m_cli( makeCommandLineParser() ) { - if( alreadyInstantiated ) { - std::string msg = "Only one instance of Catch::Session can ever be used"; - Catch::cerr() << msg << std::endl; - throw std::logic_error( msg ); - } - alreadyInstantiated = true; - } - ~Session() { - Catch::cleanUp(); - } - - void showHelp( std::string const& processName ) { - Catch::cout() << "\nCatch v" << libraryVersion.majorVersion << "." - << libraryVersion.minorVersion << " build " - << libraryVersion.buildNumber; - if( libraryVersion.branchName != std::string( "master" ) ) - Catch::cout() << " (" << libraryVersion.branchName << " branch)"; - Catch::cout() << "\n"; - - m_cli.usage( Catch::cout(), processName ); - Catch::cout() << "For more detail usage please see the project docs\n" << std::endl; - } - - int applyCommandLine( int argc, char* const argv[], OnUnusedOptions::DoWhat unusedOptionBehaviour = OnUnusedOptions::Fail ) { - try { - m_cli.setThrowOnUnrecognisedTokens( unusedOptionBehaviour == OnUnusedOptions::Fail ); - m_unusedTokens = m_cli.parseInto( argc, argv, m_configData ); - if( m_configData.showHelp ) - showHelp( m_configData.processName ); - m_config.reset(); - } - catch( std::exception& ex ) { - { - Colour colourGuard( Colour::Red ); - Catch::cerr() << "\nError(s) in input:\n" - << Text( ex.what(), TextAttributes().setIndent(2) ) - << "\n\n"; - } - m_cli.usage( Catch::cout(), m_configData.processName ); - return (std::numeric_limits<int>::max)(); - } - return 0; - } - - void useConfigData( ConfigData const& _configData ) { - m_configData = _configData; - m_config.reset(); - } - - int run( int argc, char* const argv[] ) { - - int returnCode = applyCommandLine( argc, argv ); - if( returnCode == 0 ) - returnCode = run(); - return returnCode; - } - - int run() { - if( m_configData.showHelp ) - return 0; - - try - { - config(); // Force config to be constructed - - std::srand( m_configData.rngSeed ); - - Runner runner( m_config ); - - // Handle list request - if( Option<std::size_t> listed = list( config() ) ) - return static_cast<int>( *listed ); - - return static_cast<int>( runner.runTests().assertions.failed ); - } - catch( std::exception& ex ) { - Catch::cerr() << ex.what() << std::endl; - return (std::numeric_limits<int>::max)(); - } - } - - Clara::CommandLine<ConfigData> const& cli() const { - return m_cli; - } - std::vector<Clara::Parser::Token> const& unusedTokens() const { - return m_unusedTokens; - } - ConfigData& configData() { - return m_configData; - } - Config& config() { - if( !m_config ) - m_config = new Config( m_configData ); - return *m_config; - } - - private: - Clara::CommandLine<ConfigData> m_cli; - std::vector<Clara::Parser::Token> m_unusedTokens; - ConfigData m_configData; - Ptr<Config> m_config; - }; - - bool Session::alreadyInstantiated = false; - -} // end namespace Catch - -// #included from: catch_registry_hub.hpp -#define TWOBLUECUBES_CATCH_REGISTRY_HUB_HPP_INCLUDED - -// #included from: catch_test_case_registry_impl.hpp -#define TWOBLUECUBES_CATCH_TEST_CASE_REGISTRY_IMPL_HPP_INCLUDED - -#include <vector> -#include <set> -#include <sstream> -#include <iostream> -#include <algorithm> - -namespace Catch { - - class TestRegistry : public ITestCaseRegistry { - struct LexSort { - bool operator() (TestCase i,TestCase j) const { return (i<j);} - }; - struct RandomNumberGenerator { - int operator()( int n ) const { return std::rand() % n; } - }; - - public: - TestRegistry() : m_unnamedCount( 0 ) {} - virtual ~TestRegistry(); - - virtual void registerTest( TestCase const& testCase ) { - std::string name = testCase.getTestCaseInfo().name; - if( name == "" ) { - std::ostringstream oss; - oss << "Anonymous test case " << ++m_unnamedCount; - return registerTest( testCase.withName( oss.str() ) ); - } - - if( m_functions.find( testCase ) == m_functions.end() ) { - m_functions.insert( testCase ); - m_functionsInOrder.push_back( testCase ); - if( !testCase.isHidden() ) - m_nonHiddenFunctions.push_back( testCase ); - } - else { - TestCase const& prev = *m_functions.find( testCase ); - { - Colour colourGuard( Colour::Red ); - Catch::cerr() << "error: TEST_CASE( \"" << name << "\" ) already defined.\n" - << "\tFirst seen at " << prev.getTestCaseInfo().lineInfo << "\n" - << "\tRedefined at " << testCase.getTestCaseInfo().lineInfo << std::endl; - } - exit(1); - } - } - - virtual std::vector<TestCase> const& getAllTests() const { - return m_functionsInOrder; - } - - virtual std::vector<TestCase> const& getAllNonHiddenTests() const { - return m_nonHiddenFunctions; - } - - virtual void getFilteredTests( TestSpec const& testSpec, IConfig const& config, std::vector<TestCase>& matchingTestCases, bool negated = false ) const { - - for( std::vector<TestCase>::const_iterator it = m_functionsInOrder.begin(), - itEnd = m_functionsInOrder.end(); - it != itEnd; - ++it ) { - bool includeTest = testSpec.matches( *it ) && ( config.allowThrows() || !it->throws() ); - if( includeTest != negated ) - matchingTestCases.push_back( *it ); - } - sortTests( config, matchingTestCases ); - } - - private: - - static void sortTests( IConfig const& config, std::vector<TestCase>& matchingTestCases ) { - - switch( config.runOrder() ) { - case RunTests::InLexicographicalOrder: - std::sort( matchingTestCases.begin(), matchingTestCases.end(), LexSort() ); - break; - case RunTests::InRandomOrder: - { - RandomNumberGenerator rng; - std::random_shuffle( matchingTestCases.begin(), matchingTestCases.end(), rng ); - } - break; - case RunTests::InDeclarationOrder: - // already in declaration order - break; - } - } - std::set<TestCase> m_functions; - std::vector<TestCase> m_functionsInOrder; - std::vector<TestCase> m_nonHiddenFunctions; - size_t m_unnamedCount; - }; - - /////////////////////////////////////////////////////////////////////////// - - class FreeFunctionTestCase : public SharedImpl<ITestCase> { - public: - - FreeFunctionTestCase( TestFunction fun ) : m_fun( fun ) {} - - virtual void invoke() const { - m_fun(); - } - - private: - virtual ~FreeFunctionTestCase(); - - TestFunction m_fun; - }; - - inline std::string extractClassName( std::string const& classOrQualifiedMethodName ) { - std::string className = classOrQualifiedMethodName; - if( startsWith( className, "&" ) ) - { - std::size_t lastColons = className.rfind( "::" ); - std::size_t penultimateColons = className.rfind( "::", lastColons-1 ); - if( penultimateColons == std::string::npos ) - penultimateColons = 1; - className = className.substr( penultimateColons, lastColons-penultimateColons ); - } - return className; - } - - /////////////////////////////////////////////////////////////////////////// - - AutoReg::AutoReg( TestFunction function, - SourceLineInfo const& lineInfo, - NameAndDesc const& nameAndDesc ) { - registerTestCase( new FreeFunctionTestCase( function ), "", nameAndDesc, lineInfo ); - } - - AutoReg::~AutoReg() {} - - void AutoReg::registerTestCase( ITestCase* testCase, - char const* classOrQualifiedMethodName, - NameAndDesc const& nameAndDesc, - SourceLineInfo const& lineInfo ) { - - getMutableRegistryHub().registerTest - ( makeTestCase( testCase, - extractClassName( classOrQualifiedMethodName ), - nameAndDesc.name, - nameAndDesc.description, - lineInfo ) ); - } - -} // end namespace Catch - -// #included from: catch_reporter_registry.hpp -#define TWOBLUECUBES_CATCH_REPORTER_REGISTRY_HPP_INCLUDED - -#include <map> - -namespace Catch { - - class ReporterRegistry : public IReporterRegistry { - - public: - - virtual ~ReporterRegistry() { - deleteAllValues( m_factories ); - } - - virtual IStreamingReporter* create( std::string const& name, Ptr<IConfig> const& config ) const { - FactoryMap::const_iterator it = m_factories.find( name ); - if( it == m_factories.end() ) - return NULL; - return it->second->create( ReporterConfig( config ) ); - } - - void registerReporter( std::string const& name, IReporterFactory* factory ) { - m_factories.insert( std::make_pair( name, factory ) ); - } - - FactoryMap const& getFactories() const { - return m_factories; - } - - private: - FactoryMap m_factories; - }; -} - -// #included from: catch_exception_translator_registry.hpp -#define TWOBLUECUBES_CATCH_EXCEPTION_TRANSLATOR_REGISTRY_HPP_INCLUDED - -#ifdef __OBJC__ -#import "Foundation/Foundation.h" -#endif - -namespace Catch { - - class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { - public: - ~ExceptionTranslatorRegistry() { - deleteAll( m_translators ); - } - - virtual void registerTranslator( const IExceptionTranslator* translator ) { - m_translators.push_back( translator ); - } - - virtual std::string translateActiveException() const { - try { -#ifdef __OBJC__ - // In Objective-C try objective-c exceptions first - @try { - throw; - } - @catch (NSException *exception) { - return Catch::toString( [exception description] ); - } -#else - throw; -#endif - } - catch( TestFailureException& ) { - throw; - } - catch( std::exception& ex ) { - return ex.what(); - } - catch( std::string& msg ) { - return msg; - } - catch( const char* msg ) { - return msg; - } - catch(...) { - return tryTranslators( m_translators.begin() ); - } - } - - std::string tryTranslators( std::vector<const IExceptionTranslator*>::const_iterator it ) const { - if( it == m_translators.end() ) - return "Unknown exception"; - - try { - return (*it)->translate(); - } - catch(...) { - return tryTranslators( it+1 ); - } - } - - private: - std::vector<const IExceptionTranslator*> m_translators; - }; -} - -namespace Catch { - - namespace { - - class RegistryHub : public IRegistryHub, public IMutableRegistryHub { - - RegistryHub( RegistryHub const& ); - void operator=( RegistryHub const& ); - - public: // IRegistryHub - RegistryHub() { - } - virtual IReporterRegistry const& getReporterRegistry() const { - return m_reporterRegistry; - } - virtual ITestCaseRegistry const& getTestCaseRegistry() const { - return m_testCaseRegistry; - } - virtual IExceptionTranslatorRegistry& getExceptionTranslatorRegistry() { - return m_exceptionTranslatorRegistry; - } - - public: // IMutableRegistryHub - virtual void registerReporter( std::string const& name, IReporterFactory* factory ) { - m_reporterRegistry.registerReporter( name, factory ); - } - virtual void registerTest( TestCase const& testInfo ) { - m_testCaseRegistry.registerTest( testInfo ); - } - virtual void registerTranslator( const IExceptionTranslator* translator ) { - m_exceptionTranslatorRegistry.registerTranslator( translator ); - } - - private: - TestRegistry m_testCaseRegistry; - ReporterRegistry m_reporterRegistry; - ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; - }; - - // Single, global, instance - inline RegistryHub*& getTheRegistryHub() { - static RegistryHub* theRegistryHub = NULL; - if( !theRegistryHub ) - theRegistryHub = new RegistryHub(); - return theRegistryHub; - } - } - - IRegistryHub& getRegistryHub() { - return *getTheRegistryHub(); - } - IMutableRegistryHub& getMutableRegistryHub() { - return *getTheRegistryHub(); - } - void cleanUp() { - delete getTheRegistryHub(); - getTheRegistryHub() = NULL; - cleanUpContext(); - } - std::string translateActiveException() { - return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); - } - -} // end namespace Catch - -// #included from: catch_notimplemented_exception.hpp -#define TWOBLUECUBES_CATCH_NOTIMPLEMENTED_EXCEPTION_HPP_INCLUDED - -#include <ostream> - -namespace Catch { - - NotImplementedException::NotImplementedException( SourceLineInfo const& lineInfo ) - : m_lineInfo( lineInfo ) { - std::ostringstream oss; - oss << lineInfo << ": function "; - oss << "not implemented"; - m_what = oss.str(); - } - - const char* NotImplementedException::what() const CATCH_NOEXCEPT { - return m_what.c_str(); - } - -} // end namespace Catch - -// #included from: catch_context_impl.hpp -#define TWOBLUECUBES_CATCH_CONTEXT_IMPL_HPP_INCLUDED - -// #included from: catch_stream.hpp -#define TWOBLUECUBES_CATCH_STREAM_HPP_INCLUDED - -// #included from: catch_streambuf.h -#define TWOBLUECUBES_CATCH_STREAMBUF_H_INCLUDED - -#include <streambuf> - -namespace Catch { - - class StreamBufBase : public std::streambuf { - public: - virtual ~StreamBufBase() CATCH_NOEXCEPT; - }; -} - -#include <stdexcept> -#include <cstdio> -#include <iostream> - -namespace Catch { - - template<typename WriterF, size_t bufferSize=256> - class StreamBufImpl : public StreamBufBase { - char data[bufferSize]; - WriterF m_writer; - - public: - StreamBufImpl() { - setp( data, data + sizeof(data) ); - } - - ~StreamBufImpl() CATCH_NOEXCEPT { - sync(); - } - - private: - int overflow( int c ) { - sync(); - - if( c != EOF ) { - if( pbase() == epptr() ) - m_writer( std::string( 1, static_cast<char>( c ) ) ); - else - sputc( static_cast<char>( c ) ); - } - return 0; - } - - int sync() { - if( pbase() != pptr() ) { - m_writer( std::string( pbase(), static_cast<std::string::size_type>( pptr() - pbase() ) ) ); - setp( pbase(), epptr() ); - } - return 0; - } - }; - - /////////////////////////////////////////////////////////////////////////// - - struct OutputDebugWriter { - - void operator()( std::string const&str ) { - writeToDebugConsole( str ); - } - }; - - Stream::Stream() - : streamBuf( NULL ), isOwned( false ) - {} - - Stream::Stream( std::streambuf* _streamBuf, bool _isOwned ) - : streamBuf( _streamBuf ), isOwned( _isOwned ) - {} - - void Stream::release() { - if( isOwned ) { - delete streamBuf; - streamBuf = NULL; - isOwned = false; - } - } - -#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement this functions - std::ostream& cout() { - return std::cout; - } - std::ostream& cerr() { - return std::cerr; - } -#endif -} - -namespace Catch { - - class Context : public IMutableContext { - - Context() : m_config( NULL ), m_runner( NULL ), m_resultCapture( NULL ) {} - Context( Context const& ); - void operator=( Context const& ); - - public: // IContext - virtual IResultCapture* getResultCapture() { - return m_resultCapture; - } - virtual IRunner* getRunner() { - return m_runner; - } - virtual size_t getGeneratorIndex( std::string const& fileInfo, size_t totalSize ) { - return getGeneratorsForCurrentTest() - .getGeneratorInfo( fileInfo, totalSize ) - .getCurrentIndex(); - } - virtual bool advanceGeneratorsForCurrentTest() { - IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); - return generators && generators->moveNext(); - } - - virtual Ptr<IConfig const> getConfig() const { - return m_config; - } - - public: // IMutableContext - virtual void setResultCapture( IResultCapture* resultCapture ) { - m_resultCapture = resultCapture; - } - virtual void setRunner( IRunner* runner ) { - m_runner = runner; - } - virtual void setConfig( Ptr<IConfig const> const& config ) { - m_config = config; - } - - friend IMutableContext& getCurrentMutableContext(); - - private: - IGeneratorsForTest* findGeneratorsForCurrentTest() { - std::string testName = getResultCapture()->getCurrentTestName(); - - std::map<std::string, IGeneratorsForTest*>::const_iterator it = - m_generatorsByTestName.find( testName ); - return it != m_generatorsByTestName.end() - ? it->second - : NULL; - } - - IGeneratorsForTest& getGeneratorsForCurrentTest() { - IGeneratorsForTest* generators = findGeneratorsForCurrentTest(); - if( !generators ) { - std::string testName = getResultCapture()->getCurrentTestName(); - generators = createGeneratorsForTest(); - m_generatorsByTestName.insert( std::make_pair( testName, generators ) ); - } - return *generators; - } - - private: - Ptr<IConfig const> m_config; - IRunner* m_runner; - IResultCapture* m_resultCapture; - std::map<std::string, IGeneratorsForTest*> m_generatorsByTestName; - }; - - namespace { - Context* currentContext = NULL; - } - IMutableContext& getCurrentMutableContext() { - if( !currentContext ) - currentContext = new Context(); - return *currentContext; - } - IContext& getCurrentContext() { - return getCurrentMutableContext(); - } - - Stream createStream( std::string const& streamName ) { - if( streamName == "stdout" ) return Stream( Catch::cout().rdbuf(), false ); - if( streamName == "stderr" ) return Stream( Catch::cerr().rdbuf(), false ); - if( streamName == "debug" ) return Stream( new StreamBufImpl<OutputDebugWriter>, true ); - - throw std::domain_error( "Unknown stream: " + streamName ); - } - - void cleanUpContext() { - delete currentContext; - currentContext = NULL; - } -} - -// #included from: catch_console_colour_impl.hpp -#define TWOBLUECUBES_CATCH_CONSOLE_COLOUR_IMPL_HPP_INCLUDED - -namespace Catch { - namespace { - - struct IColourImpl { - virtual ~IColourImpl() {} - virtual void use( Colour::Code _colourCode ) = 0; - }; - - struct NoColourImpl : IColourImpl { - void use( Colour::Code ) {} - - static IColourImpl* instance() { - static NoColourImpl s_instance; - return &s_instance; - } - }; - - } // anon namespace -} // namespace Catch - -#if !defined( CATCH_CONFIG_COLOUR_NONE ) && !defined( CATCH_CONFIG_COLOUR_WINDOWS ) && !defined( CATCH_CONFIG_COLOUR_ANSI ) -# ifdef CATCH_PLATFORM_WINDOWS -# define CATCH_CONFIG_COLOUR_WINDOWS -# else -# define CATCH_CONFIG_COLOUR_ANSI -# endif -#endif - -#if defined ( CATCH_CONFIG_COLOUR_WINDOWS ) ///////////////////////////////////////// - -#ifndef NOMINMAX -#define NOMINMAX -#endif - -#ifdef __AFXDLL -#include <AfxWin.h> -#else -#include <windows.h> -#endif - -namespace Catch { -namespace { - - class Win32ColourImpl : public IColourImpl { - public: - Win32ColourImpl() : stdoutHandle( GetStdHandle(STD_OUTPUT_HANDLE) ) - { - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo( stdoutHandle, &csbiInfo ); - originalAttributes = csbiInfo.wAttributes; - } - - virtual void use( Colour::Code _colourCode ) { - switch( _colourCode ) { - case Colour::None: return setTextAttribute( originalAttributes ); - case Colour::White: return setTextAttribute( FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); - case Colour::Red: return setTextAttribute( FOREGROUND_RED ); - case Colour::Green: return setTextAttribute( FOREGROUND_GREEN ); - case Colour::Blue: return setTextAttribute( FOREGROUND_BLUE ); - case Colour::Cyan: return setTextAttribute( FOREGROUND_BLUE | FOREGROUND_GREEN ); - case Colour::Yellow: return setTextAttribute( FOREGROUND_RED | FOREGROUND_GREEN ); - case Colour::Grey: return setTextAttribute( 0 ); - - case Colour::LightGrey: return setTextAttribute( FOREGROUND_INTENSITY ); - case Colour::BrightRed: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_RED ); - case Colour::BrightGreen: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN ); - case Colour::BrightWhite: return setTextAttribute( FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE ); - - case Colour::Bright: throw std::logic_error( "not a colour" ); - } - } - - private: - void setTextAttribute( WORD _textAttribute ) { - SetConsoleTextAttribute( stdoutHandle, _textAttribute ); - } - HANDLE stdoutHandle; - WORD originalAttributes; - }; - - IColourImpl* platformColourInstance() { - static Win32ColourImpl s_instance; - return &s_instance; - } - -} // end anon namespace -} // end namespace Catch - -#elif defined( CATCH_CONFIG_COLOUR_ANSI ) ////////////////////////////////////// - -#include <unistd.h> - -namespace Catch { -namespace { - - // use POSIX/ ANSI console terminal codes - // Thanks to Adam Strzelecki for original contribution - // (http://github.com/nanoant) - // https://github.com/philsquared/Catch/pull/131 - class PosixColourImpl : public IColourImpl { - public: - virtual void use( Colour::Code _colourCode ) { - switch( _colourCode ) { - case Colour::None: - case Colour::White: return setColour( "[0m" ); - case Colour::Red: return setColour( "[0;31m" ); - case Colour::Green: return setColour( "[0;32m" ); - case Colour::Blue: return setColour( "[0:34m" ); - case Colour::Cyan: return setColour( "[0;36m" ); - case Colour::Yellow: return setColour( "[0;33m" ); - case Colour::Grey: return setColour( "[1;30m" ); - - case Colour::LightGrey: return setColour( "[0;37m" ); - case Colour::BrightRed: return setColour( "[1;31m" ); - case Colour::BrightGreen: return setColour( "[1;32m" ); - case Colour::BrightWhite: return setColour( "[1;37m" ); - - case Colour::Bright: throw std::logic_error( "not a colour" ); - } - } - static IColourImpl* instance() { - static PosixColourImpl s_instance; - return &s_instance; - } - - private: - void setColour( const char* _escapeCode ) { - Catch::cout() << '\033' << _escapeCode; - } - }; - - IColourImpl* platformColourInstance() { - Ptr<IConfig const> config = getCurrentContext().getConfig(); - return (config && config->forceColour()) || isatty(STDOUT_FILENO) - ? PosixColourImpl::instance() - : NoColourImpl::instance(); - } - -} // end anon namespace -} // end namespace Catch - -#else // not Windows or ANSI /////////////////////////////////////////////// - -namespace Catch { - - static IColourImpl* platformColourInstance() { return NoColourImpl::instance(); } - -} // end namespace Catch - -#endif // Windows/ ANSI/ None - -namespace Catch { - - Colour::Colour( Code _colourCode ) : m_moved( false ) { use( _colourCode ); } - Colour::Colour( Colour const& _other ) : m_moved( false ) { const_cast<Colour&>( _other ).m_moved = true; } - Colour::~Colour(){ if( !m_moved ) use( None ); } - - void Colour::use( Code _colourCode ) { - static IColourImpl* impl = isDebuggerActive() - ? NoColourImpl::instance() - : platformColourInstance(); - impl->use( _colourCode ); - } - -} // end namespace Catch - -// #included from: catch_generators_impl.hpp -#define TWOBLUECUBES_CATCH_GENERATORS_IMPL_HPP_INCLUDED - -#include <vector> -#include <string> -#include <map> - -namespace Catch { - - struct GeneratorInfo : IGeneratorInfo { - - GeneratorInfo( std::size_t size ) - : m_size( size ), - m_currentIndex( 0 ) - {} - - bool moveNext() { - if( ++m_currentIndex == m_size ) { - m_currentIndex = 0; - return false; - } - return true; - } - - std::size_t getCurrentIndex() const { - return m_currentIndex; - } - - std::size_t m_size; - std::size_t m_currentIndex; - }; - - /////////////////////////////////////////////////////////////////////////// - - class GeneratorsForTest : public IGeneratorsForTest { - - public: - ~GeneratorsForTest() { - deleteAll( m_generatorsInOrder ); - } - - IGeneratorInfo& getGeneratorInfo( std::string const& fileInfo, std::size_t size ) { - std::map<std::string, IGeneratorInfo*>::const_iterator it = m_generatorsByName.find( fileInfo ); - if( it == m_generatorsByName.end() ) { - IGeneratorInfo* info = new GeneratorInfo( size ); - m_generatorsByName.insert( std::make_pair( fileInfo, info ) ); - m_generatorsInOrder.push_back( info ); - return *info; - } - return *it->second; - } - - bool moveNext() { - std::vector<IGeneratorInfo*>::const_iterator it = m_generatorsInOrder.begin(); - std::vector<IGeneratorInfo*>::const_iterator itEnd = m_generatorsInOrder.end(); - for(; it != itEnd; ++it ) { - if( (*it)->moveNext() ) - return true; - } - return false; - } - - private: - std::map<std::string, IGeneratorInfo*> m_generatorsByName; - std::vector<IGeneratorInfo*> m_generatorsInOrder; - }; - - IGeneratorsForTest* createGeneratorsForTest() - { - return new GeneratorsForTest(); - } - -} // end namespace Catch - -// #included from: catch_assertionresult.hpp -#define TWOBLUECUBES_CATCH_ASSERTIONRESULT_HPP_INCLUDED - -namespace Catch { - - AssertionInfo::AssertionInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - std::string const& _capturedExpression, - ResultDisposition::Flags _resultDisposition ) - : macroName( _macroName ), - lineInfo( _lineInfo ), - capturedExpression( _capturedExpression ), - resultDisposition( _resultDisposition ) - {} - - AssertionResult::AssertionResult() {} - - AssertionResult::AssertionResult( AssertionInfo const& info, AssertionResultData const& data ) - : m_info( info ), - m_resultData( data ) - {} - - AssertionResult::~AssertionResult() {} - - // Result was a success - bool AssertionResult::succeeded() const { - return Catch::isOk( m_resultData.resultType ); - } - - // Result was a success, or failure is suppressed - bool AssertionResult::isOk() const { - return Catch::isOk( m_resultData.resultType ) || shouldSuppressFailure( m_info.resultDisposition ); - } - - ResultWas::OfType AssertionResult::getResultType() const { - return m_resultData.resultType; - } - - bool AssertionResult::hasExpression() const { - return !m_info.capturedExpression.empty(); - } - - bool AssertionResult::hasMessage() const { - return !m_resultData.message.empty(); - } - - std::string AssertionResult::getExpression() const { - if( isFalseTest( m_info.resultDisposition ) ) - return "!" + m_info.capturedExpression; - else - return m_info.capturedExpression; - } - std::string AssertionResult::getExpressionInMacro() const { - if( m_info.macroName.empty() ) - return m_info.capturedExpression; - else - return m_info.macroName + "( " + m_info.capturedExpression + " )"; - } - - bool AssertionResult::hasExpandedExpression() const { - return hasExpression() && getExpandedExpression() != getExpression(); - } - - std::string AssertionResult::getExpandedExpression() const { - return m_resultData.reconstructedExpression; - } - - std::string AssertionResult::getMessage() const { - return m_resultData.message; - } - SourceLineInfo AssertionResult::getSourceInfo() const { - return m_info.lineInfo; - } - - std::string AssertionResult::getTestMacroName() const { - return m_info.macroName; - } - -} // end namespace Catch - -// #included from: catch_test_case_info.hpp -#define TWOBLUECUBES_CATCH_TEST_CASE_INFO_HPP_INCLUDED - -namespace Catch { - - inline TestCaseInfo::SpecialProperties parseSpecialTag( std::string const& tag ) { - if( startsWith( tag, "." ) || - tag == "hide" || - tag == "!hide" ) - return TestCaseInfo::IsHidden; - else if( tag == "!throws" ) - return TestCaseInfo::Throws; - else if( tag == "!shouldfail" ) - return TestCaseInfo::ShouldFail; - else if( tag == "!mayfail" ) - return TestCaseInfo::MayFail; - else - return TestCaseInfo::None; - } - inline bool isReservedTag( std::string const& tag ) { - return parseSpecialTag( tag ) == TestCaseInfo::None && tag.size() > 0 && !isalnum( tag[0] ); - } - inline void enforceNotReservedTag( std::string const& tag, SourceLineInfo const& _lineInfo ) { - if( isReservedTag( tag ) ) { - { - Colour colourGuard( Colour::Red ); - Catch::cerr() - << "Tag name [" << tag << "] not allowed.\n" - << "Tag names starting with non alpha-numeric characters are reserved\n"; - } - { - Colour colourGuard( Colour::FileName ); - Catch::cerr() << _lineInfo << std::endl; - } - exit(1); - } - } - - TestCase makeTestCase( ITestCase* _testCase, - std::string const& _className, - std::string const& _name, - std::string const& _descOrTags, - SourceLineInfo const& _lineInfo ) - { - bool isHidden( startsWith( _name, "./" ) ); // Legacy support - - // Parse out tags - std::set<std::string> tags; - std::string desc, tag; - bool inTag = false; - for( std::size_t i = 0; i < _descOrTags.size(); ++i ) { - char c = _descOrTags[i]; - if( !inTag ) { - if( c == '[' ) - inTag = true; - else - desc += c; - } - else { - if( c == ']' ) { - TestCaseInfo::SpecialProperties prop = parseSpecialTag( tag ); - if( prop == TestCaseInfo::IsHidden ) - isHidden = true; - else if( prop == TestCaseInfo::None ) - enforceNotReservedTag( tag, _lineInfo ); - - tags.insert( tag ); - tag.clear(); - inTag = false; - } - else - tag += c; - } - } - if( isHidden ) { - tags.insert( "hide" ); - tags.insert( "." ); - } - - TestCaseInfo info( _name, _className, desc, tags, _lineInfo ); - return TestCase( _testCase, info ); - } - - TestCaseInfo::TestCaseInfo( std::string const& _name, - std::string const& _className, - std::string const& _description, - std::set<std::string> const& _tags, - SourceLineInfo const& _lineInfo ) - : name( _name ), - className( _className ), - description( _description ), - tags( _tags ), - lineInfo( _lineInfo ), - properties( None ) - { - std::ostringstream oss; - for( std::set<std::string>::const_iterator it = _tags.begin(), itEnd = _tags.end(); it != itEnd; ++it ) { - oss << "[" << *it << "]"; - std::string lcaseTag = toLower( *it ); - properties = static_cast<SpecialProperties>( properties | parseSpecialTag( lcaseTag ) ); - lcaseTags.insert( lcaseTag ); - } - tagsAsString = oss.str(); - } - - TestCaseInfo::TestCaseInfo( TestCaseInfo const& other ) - : name( other.name ), - className( other.className ), - description( other.description ), - tags( other.tags ), - lcaseTags( other.lcaseTags ), - tagsAsString( other.tagsAsString ), - lineInfo( other.lineInfo ), - properties( other.properties ) - {} - - bool TestCaseInfo::isHidden() const { - return ( properties & IsHidden ) != 0; - } - bool TestCaseInfo::throws() const { - return ( properties & Throws ) != 0; - } - bool TestCaseInfo::okToFail() const { - return ( properties & (ShouldFail | MayFail ) ) != 0; - } - bool TestCaseInfo::expectedToFail() const { - return ( properties & (ShouldFail ) ) != 0; - } - - TestCase::TestCase( ITestCase* testCase, TestCaseInfo const& info ) : TestCaseInfo( info ), test( testCase ) {} - - TestCase::TestCase( TestCase const& other ) - : TestCaseInfo( other ), - test( other.test ) - {} - - TestCase TestCase::withName( std::string const& _newName ) const { - TestCase other( *this ); - other.name = _newName; - return other; - } - - void TestCase::swap( TestCase& other ) { - test.swap( other.test ); - name.swap( other.name ); - className.swap( other.className ); - description.swap( other.description ); - tags.swap( other.tags ); - lcaseTags.swap( other.lcaseTags ); - tagsAsString.swap( other.tagsAsString ); - std::swap( TestCaseInfo::properties, static_cast<TestCaseInfo&>( other ).properties ); - std::swap( lineInfo, other.lineInfo ); - } - - void TestCase::invoke() const { - test->invoke(); - } - - bool TestCase::operator == ( TestCase const& other ) const { - return test.get() == other.test.get() && - name == other.name && - className == other.className; - } - - bool TestCase::operator < ( TestCase const& other ) const { - return name < other.name; - } - TestCase& TestCase::operator = ( TestCase const& other ) { - TestCase temp( other ); - swap( temp ); - return *this; - } - - TestCaseInfo const& TestCase::getTestCaseInfo() const - { - return *this; - } - -} // end namespace Catch - -// #included from: catch_version.hpp -#define TWOBLUECUBES_CATCH_VERSION_HPP_INCLUDED - -namespace Catch { - - // These numbers are maintained by a script - Version libraryVersion( 1, 1, 3, "master" ); -} - -// #included from: catch_message.hpp -#define TWOBLUECUBES_CATCH_MESSAGE_HPP_INCLUDED - -namespace Catch { - - MessageInfo::MessageInfo( std::string const& _macroName, - SourceLineInfo const& _lineInfo, - ResultWas::OfType _type ) - : macroName( _macroName ), - lineInfo( _lineInfo ), - type( _type ), - sequence( ++globalCount ) - {} - - // This may need protecting if threading support is added - unsigned int MessageInfo::globalCount = 0; - - //////////////////////////////////////////////////////////////////////////// - - ScopedMessage::ScopedMessage( MessageBuilder const& builder ) - : m_info( builder.m_info ) - { - m_info.message = builder.m_stream.str(); - getResultCapture().pushScopedMessage( m_info ); - } - ScopedMessage::ScopedMessage( ScopedMessage const& other ) - : m_info( other.m_info ) - {} - - ScopedMessage::~ScopedMessage() { - getResultCapture().popScopedMessage( m_info ); - } - -} // end namespace Catch - -// #included from: catch_legacy_reporter_adapter.hpp -#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_HPP_INCLUDED - -// #included from: catch_legacy_reporter_adapter.h -#define TWOBLUECUBES_CATCH_LEGACY_REPORTER_ADAPTER_H_INCLUDED - -namespace Catch -{ - // Deprecated - struct IReporter : IShared { - virtual ~IReporter(); - - virtual bool shouldRedirectStdout() const = 0; - - virtual void StartTesting() = 0; - virtual void EndTesting( Totals const& totals ) = 0; - virtual void StartGroup( std::string const& groupName ) = 0; - virtual void EndGroup( std::string const& groupName, Totals const& totals ) = 0; - virtual void StartTestCase( TestCaseInfo const& testInfo ) = 0; - virtual void EndTestCase( TestCaseInfo const& testInfo, Totals const& totals, std::string const& stdOut, std::string const& stdErr ) = 0; - virtual void StartSection( std::string const& sectionName, std::string const& description ) = 0; - virtual void EndSection( std::string const& sectionName, Counts const& assertions ) = 0; - virtual void NoAssertionsInSection( std::string const& sectionName ) = 0; - virtual void NoAssertionsInTestCase( std::string const& testName ) = 0; - virtual void Aborted() = 0; - virtual void Result( AssertionResult const& result ) = 0; - }; - - class LegacyReporterAdapter : public SharedImpl<IStreamingReporter> - { - public: - LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter ); - virtual ~LegacyReporterAdapter(); - - virtual ReporterPreferences getPreferences() const; - virtual void noMatchingTestCases( std::string const& ); - virtual void testRunStarting( TestRunInfo const& ); - virtual void testGroupStarting( GroupInfo const& groupInfo ); - virtual void testCaseStarting( TestCaseInfo const& testInfo ); - virtual void sectionStarting( SectionInfo const& sectionInfo ); - virtual void assertionStarting( AssertionInfo const& ); - virtual bool assertionEnded( AssertionStats const& assertionStats ); - virtual void sectionEnded( SectionStats const& sectionStats ); - virtual void testCaseEnded( TestCaseStats const& testCaseStats ); - virtual void testGroupEnded( TestGroupStats const& testGroupStats ); - virtual void testRunEnded( TestRunStats const& testRunStats ); - virtual void skipTest( TestCaseInfo const& ); - - private: - Ptr<IReporter> m_legacyReporter; - }; -} - -namespace Catch -{ - LegacyReporterAdapter::LegacyReporterAdapter( Ptr<IReporter> const& legacyReporter ) - : m_legacyReporter( legacyReporter ) - {} - LegacyReporterAdapter::~LegacyReporterAdapter() {} - - ReporterPreferences LegacyReporterAdapter::getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = m_legacyReporter->shouldRedirectStdout(); - return prefs; - } - - void LegacyReporterAdapter::noMatchingTestCases( std::string const& ) {} - void LegacyReporterAdapter::testRunStarting( TestRunInfo const& ) { - m_legacyReporter->StartTesting(); - } - void LegacyReporterAdapter::testGroupStarting( GroupInfo const& groupInfo ) { - m_legacyReporter->StartGroup( groupInfo.name ); - } - void LegacyReporterAdapter::testCaseStarting( TestCaseInfo const& testInfo ) { - m_legacyReporter->StartTestCase( testInfo ); - } - void LegacyReporterAdapter::sectionStarting( SectionInfo const& sectionInfo ) { - m_legacyReporter->StartSection( sectionInfo.name, sectionInfo.description ); - } - void LegacyReporterAdapter::assertionStarting( AssertionInfo const& ) { - // Not on legacy interface - } - - bool LegacyReporterAdapter::assertionEnded( AssertionStats const& assertionStats ) { - if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { - for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); - it != itEnd; - ++it ) { - if( it->type == ResultWas::Info ) { - ResultBuilder rb( it->macroName.c_str(), it->lineInfo, "", ResultDisposition::Normal ); - rb << it->message; - rb.setResultType( ResultWas::Info ); - AssertionResult result = rb.build(); - m_legacyReporter->Result( result ); - } - } - } - m_legacyReporter->Result( assertionStats.assertionResult ); - return true; - } - void LegacyReporterAdapter::sectionEnded( SectionStats const& sectionStats ) { - if( sectionStats.missingAssertions ) - m_legacyReporter->NoAssertionsInSection( sectionStats.sectionInfo.name ); - m_legacyReporter->EndSection( sectionStats.sectionInfo.name, sectionStats.assertions ); - } - void LegacyReporterAdapter::testCaseEnded( TestCaseStats const& testCaseStats ) { - m_legacyReporter->EndTestCase - ( testCaseStats.testInfo, - testCaseStats.totals, - testCaseStats.stdOut, - testCaseStats.stdErr ); - } - void LegacyReporterAdapter::testGroupEnded( TestGroupStats const& testGroupStats ) { - if( testGroupStats.aborting ) - m_legacyReporter->Aborted(); - m_legacyReporter->EndGroup( testGroupStats.groupInfo.name, testGroupStats.totals ); - } - void LegacyReporterAdapter::testRunEnded( TestRunStats const& testRunStats ) { - m_legacyReporter->EndTesting( testRunStats.totals ); - } - void LegacyReporterAdapter::skipTest( TestCaseInfo const& ) { - } -} - -// #included from: catch_timer.hpp - -#ifdef __clang__ -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wc++11-long-long" -#endif - -#ifdef CATCH_PLATFORM_WINDOWS -#include <windows.h> -#else -#include <sys/time.h> -#endif - -namespace Catch { - - namespace { -#ifdef CATCH_PLATFORM_WINDOWS - uint64_t getCurrentTicks() { - static uint64_t hz=0, hzo=0; - if (!hz) { - QueryPerformanceFrequency( reinterpret_cast<LARGE_INTEGER*>( &hz ) ); - QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &hzo ) ); - } - uint64_t t; - QueryPerformanceCounter( reinterpret_cast<LARGE_INTEGER*>( &t ) ); - return ((t-hzo)*1000000)/hz; - } -#else - uint64_t getCurrentTicks() { - timeval t; - gettimeofday(&t,NULL); - return static_cast<uint64_t>( t.tv_sec ) * 1000000ull + static_cast<uint64_t>( t.tv_usec ); - } -#endif - } - - void Timer::start() { - m_ticks = getCurrentTicks(); - } - unsigned int Timer::getElapsedMicroseconds() const { - return static_cast<unsigned int>(getCurrentTicks() - m_ticks); - } - unsigned int Timer::getElapsedMilliseconds() const { - return static_cast<unsigned int>(getElapsedMicroseconds()/1000); - } - double Timer::getElapsedSeconds() const { - return getElapsedMicroseconds()/1000000.0; - } - -} // namespace Catch - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif -// #included from: catch_common.hpp -#define TWOBLUECUBES_CATCH_COMMON_HPP_INCLUDED - -namespace Catch { - - bool startsWith( std::string const& s, std::string const& prefix ) { - return s.size() >= prefix.size() && s.substr( 0, prefix.size() ) == prefix; - } - bool endsWith( std::string const& s, std::string const& suffix ) { - return s.size() >= suffix.size() && s.substr( s.size()-suffix.size(), suffix.size() ) == suffix; - } - bool contains( std::string const& s, std::string const& infix ) { - return s.find( infix ) != std::string::npos; - } - void toLowerInPlace( std::string& s ) { - std::transform( s.begin(), s.end(), s.begin(), ::tolower ); - } - std::string toLower( std::string const& s ) { - std::string lc = s; - toLowerInPlace( lc ); - return lc; - } - std::string trim( std::string const& str ) { - static char const* whitespaceChars = "\n\r\t "; - std::string::size_type start = str.find_first_not_of( whitespaceChars ); - std::string::size_type end = str.find_last_not_of( whitespaceChars ); - - return start != std::string::npos ? str.substr( start, 1+end-start ) : ""; - } - - bool replaceInPlace( std::string& str, std::string const& replaceThis, std::string const& withThis ) { - bool replaced = false; - std::size_t i = str.find( replaceThis ); - while( i != std::string::npos ) { - replaced = true; - str = str.substr( 0, i ) + withThis + str.substr( i+replaceThis.size() ); - if( i < str.size()-withThis.size() ) - i = str.find( replaceThis, i+withThis.size() ); - else - i = std::string::npos; - } - return replaced; - } - - pluralise::pluralise( std::size_t count, std::string const& label ) - : m_count( count ), - m_label( label ) - {} - - std::ostream& operator << ( std::ostream& os, pluralise const& pluraliser ) { - os << pluraliser.m_count << " " << pluraliser.m_label; - if( pluraliser.m_count != 1 ) - os << "s"; - return os; - } - - SourceLineInfo::SourceLineInfo() : line( 0 ){} - SourceLineInfo::SourceLineInfo( char const* _file, std::size_t _line ) - : file( _file ), - line( _line ) - {} - SourceLineInfo::SourceLineInfo( SourceLineInfo const& other ) - : file( other.file ), - line( other.line ) - {} - bool SourceLineInfo::empty() const { - return file.empty(); - } - bool SourceLineInfo::operator == ( SourceLineInfo const& other ) const { - return line == other.line && file == other.file; - } - bool SourceLineInfo::operator < ( SourceLineInfo const& other ) const { - return line < other.line || ( line == other.line && file < other.file ); - } - - std::ostream& operator << ( std::ostream& os, SourceLineInfo const& info ) { -#ifndef __GNUG__ - os << info.file << "(" << info.line << ")"; -#else - os << info.file << ":" << info.line; -#endif - return os; - } - - void throwLogicError( std::string const& message, SourceLineInfo const& locationInfo ) { - std::ostringstream oss; - oss << locationInfo << ": Internal Catch error: '" << message << "'"; - if( alwaysTrue() ) - throw std::logic_error( oss.str() ); - } -} - -// #included from: catch_section.hpp -#define TWOBLUECUBES_CATCH_SECTION_HPP_INCLUDED - -namespace Catch { - - SectionInfo::SectionInfo - ( SourceLineInfo const& _lineInfo, - std::string const& _name, - std::string const& _description ) - : name( _name ), - description( _description ), - lineInfo( _lineInfo ) - {} - - Section::Section( SectionInfo const& info ) - : m_info( info ), - m_sectionIncluded( getResultCapture().sectionStarted( m_info, m_assertions ) ) - { - m_timer.start(); - } - - Section::~Section() { - if( m_sectionIncluded ) - getResultCapture().sectionEnded( m_info, m_assertions, m_timer.getElapsedSeconds() ); - } - - // This indicates whether the section should be executed or not - Section::operator bool() const { - return m_sectionIncluded; - } - -} // end namespace Catch - -// #included from: catch_debugger.hpp -#define TWOBLUECUBES_CATCH_DEBUGGER_HPP_INCLUDED - -#include <iostream> - -#ifdef CATCH_PLATFORM_MAC - - #include <assert.h> - #include <stdbool.h> - #include <sys/types.h> - #include <unistd.h> - #include <sys/sysctl.h> - - namespace Catch{ - - // The following function is taken directly from the following technical note: - // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html - - // Returns true if the current process is being debugged (either - // running under the debugger or has a debugger attached post facto). - bool isDebuggerActive(){ - - int mib[4]; - struct kinfo_proc info; - size_t size; - - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - - info.kp_proc.p_flag = 0; - - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - - // Call sysctl. - - size = sizeof(info); - if( sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0) != 0 ) { - Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; - return false; - } - - // We're being debugged if the P_TRACED flag is set. - - return ( (info.kp_proc.p_flag & P_TRACED) != 0 ); - } - } // namespace Catch - -#elif defined(_MSC_VER) - extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); - namespace Catch { - bool isDebuggerActive() { - return IsDebuggerPresent() != 0; - } - } -#elif defined(__MINGW32__) - extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); - namespace Catch { - bool isDebuggerActive() { - return IsDebuggerPresent() != 0; - } - } -#else - namespace Catch { - inline bool isDebuggerActive() { return false; } - } -#endif // Platform - -#ifdef CATCH_PLATFORM_WINDOWS - extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( const char* ); - namespace Catch { - void writeToDebugConsole( std::string const& text ) { - ::OutputDebugStringA( text.c_str() ); - } - } -#else - namespace Catch { - void writeToDebugConsole( std::string const& text ) { - // !TBD: Need a version for Mac/ XCode and other IDEs - Catch::cout() << text; - } - } -#endif // Platform - -// #included from: catch_tostring.hpp -#define TWOBLUECUBES_CATCH_TOSTRING_HPP_INCLUDED - -namespace Catch { - -namespace Detail { - - std::string unprintableString = "{?}"; - - namespace { - struct Endianness { - enum Arch { Big, Little }; - - static Arch which() { - union _{ - int asInt; - char asChar[sizeof (int)]; - } u; - - u.asInt = 1; - return ( u.asChar[sizeof(int)-1] == 1 ) ? Big : Little; - } - }; - } - - std::string rawMemoryToString( const void *object, std::size_t size ) - { - // Reverse order for little endian architectures - int i = 0, end = static_cast<int>( size ), inc = 1; - if( Endianness::which() == Endianness::Little ) { - i = end-1; - end = inc = -1; - } - - unsigned char const *bytes = static_cast<unsigned char const *>(object); - std::ostringstream os; - os << "0x" << std::setfill('0') << std::hex; - for( ; i != end; i += inc ) - os << std::setw(2) << static_cast<unsigned>(bytes[i]); - return os.str(); - } -} - -std::string toString( std::string const& value ) { - std::string s = value; - if( getCurrentContext().getConfig()->showInvisibles() ) { - for(size_t i = 0; i < s.size(); ++i ) { - std::string subs; - switch( s[i] ) { - case '\n': subs = "\\n"; break; - case '\t': subs = "\\t"; break; - default: break; - } - if( !subs.empty() ) { - s = s.substr( 0, i ) + subs + s.substr( i+1 ); - ++i; - } - } - } - return "\"" + s + "\""; -} -std::string toString( std::wstring const& value ) { - - std::string s; - s.reserve( value.size() ); - for(size_t i = 0; i < value.size(); ++i ) - s += value[i] <= 0xff ? static_cast<char>( value[i] ) : '?'; - return Catch::toString( s ); -} - -std::string toString( const char* const value ) { - return value ? Catch::toString( std::string( value ) ) : std::string( "{null string}" ); -} - -std::string toString( char* const value ) { - return Catch::toString( static_cast<const char*>( value ) ); -} - -std::string toString( const wchar_t* const value ) -{ - return value ? Catch::toString( std::wstring(value) ) : std::string( "{null string}" ); -} - -std::string toString( wchar_t* const value ) -{ - return Catch::toString( static_cast<const wchar_t*>( value ) ); -} - -std::string toString( int value ) { - std::ostringstream oss; - if( value > 8192 ) - oss << "0x" << std::hex << value; - else - oss << value; - return oss.str(); -} - -std::string toString( unsigned long value ) { - std::ostringstream oss; - if( value > 8192 ) - oss << "0x" << std::hex << value; - else - oss << value; - return oss.str(); -} - -std::string toString( unsigned int value ) { - return Catch::toString( static_cast<unsigned long>( value ) ); -} - -template<typename T> -std::string fpToString( T value, int precision ) { - std::ostringstream oss; - oss << std::setprecision( precision ) - << std::fixed - << value; - std::string d = oss.str(); - std::size_t i = d.find_last_not_of( '0' ); - if( i != std::string::npos && i != d.size()-1 ) { - if( d[i] == '.' ) - i++; - d = d.substr( 0, i+1 ); - } - return d; -} - -std::string toString( const double value ) { - return fpToString( value, 10 ); -} -std::string toString( const float value ) { - return fpToString( value, 5 ) + "f"; -} - -std::string toString( bool value ) { - return value ? "true" : "false"; -} - -std::string toString( char value ) { - return value < ' ' - ? toString( static_cast<unsigned int>( value ) ) - : Detail::makeString( value ); -} - -std::string toString( signed char value ) { - return toString( static_cast<char>( value ) ); -} - -std::string toString( unsigned char value ) { - return toString( static_cast<char>( value ) ); -} - -#ifdef CATCH_CONFIG_CPP11_NULLPTR -std::string toString( std::nullptr_t ) { - return "nullptr"; -} -#endif - -#ifdef __OBJC__ - std::string toString( NSString const * const& nsstring ) { - if( !nsstring ) - return "nil"; - return "@" + toString([nsstring UTF8String]); - } - std::string toString( NSString * CATCH_ARC_STRONG const& nsstring ) { - if( !nsstring ) - return "nil"; - return "@" + toString([nsstring UTF8String]); - } - std::string toString( NSObject* const& nsObject ) { - return toString( [nsObject description] ); - } -#endif - -} // end namespace Catch - -// #included from: catch_result_builder.hpp -#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED - -namespace Catch { - - ResultBuilder::ResultBuilder( char const* macroName, - SourceLineInfo const& lineInfo, - char const* capturedExpression, - ResultDisposition::Flags resultDisposition ) - : m_assertionInfo( macroName, lineInfo, capturedExpression, resultDisposition ), - m_shouldDebugBreak( false ), - m_shouldThrow( false ) - {} - - ResultBuilder& ResultBuilder::setResultType( ResultWas::OfType result ) { - m_data.resultType = result; - return *this; - } - ResultBuilder& ResultBuilder::setResultType( bool result ) { - m_data.resultType = result ? ResultWas::Ok : ResultWas::ExpressionFailed; - return *this; - } - ResultBuilder& ResultBuilder::setLhs( std::string const& lhs ) { - m_exprComponents.lhs = lhs; - return *this; - } - ResultBuilder& ResultBuilder::setRhs( std::string const& rhs ) { - m_exprComponents.rhs = rhs; - return *this; - } - ResultBuilder& ResultBuilder::setOp( std::string const& op ) { - m_exprComponents.op = op; - return *this; - } - - void ResultBuilder::endExpression() { - m_exprComponents.testFalse = isFalseTest( m_assertionInfo.resultDisposition ); - captureExpression(); - } - - void ResultBuilder::useActiveException( ResultDisposition::Flags resultDisposition ) { - m_assertionInfo.resultDisposition = resultDisposition; - m_stream.oss << Catch::translateActiveException(); - captureResult( ResultWas::ThrewException ); - } - - void ResultBuilder::captureResult( ResultWas::OfType resultType ) { - setResultType( resultType ); - captureExpression(); - } - - void ResultBuilder::captureExpression() { - AssertionResult result = build(); - getResultCapture().assertionEnded( result ); - - if( !result.isOk() ) { - if( getCurrentContext().getConfig()->shouldDebugBreak() ) - m_shouldDebugBreak = true; - if( getCurrentContext().getRunner()->aborting() || (m_assertionInfo.resultDisposition & ResultDisposition::Normal) ) - m_shouldThrow = true; - } - } - void ResultBuilder::react() { - if( m_shouldThrow ) - throw Catch::TestFailureException(); - } - - bool ResultBuilder::shouldDebugBreak() const { return m_shouldDebugBreak; } - bool ResultBuilder::allowThrows() const { return getCurrentContext().getConfig()->allowThrows(); } - - AssertionResult ResultBuilder::build() const - { - assert( m_data.resultType != ResultWas::Unknown ); - - AssertionResultData data = m_data; - - // Flip bool results if testFalse is set - if( m_exprComponents.testFalse ) { - if( data.resultType == ResultWas::Ok ) - data.resultType = ResultWas::ExpressionFailed; - else if( data.resultType == ResultWas::ExpressionFailed ) - data.resultType = ResultWas::Ok; - } - - data.message = m_stream.oss.str(); - data.reconstructedExpression = reconstructExpression(); - if( m_exprComponents.testFalse ) { - if( m_exprComponents.op == "" ) - data.reconstructedExpression = "!" + data.reconstructedExpression; - else - data.reconstructedExpression = "!(" + data.reconstructedExpression + ")"; - } - return AssertionResult( m_assertionInfo, data ); - } - std::string ResultBuilder::reconstructExpression() const { - if( m_exprComponents.op == "" ) - return m_exprComponents.lhs.empty() ? m_assertionInfo.capturedExpression : m_exprComponents.op + m_exprComponents.lhs; - else if( m_exprComponents.op == "matches" ) - return m_exprComponents.lhs + " " + m_exprComponents.rhs; - else if( m_exprComponents.op != "!" ) { - if( m_exprComponents.lhs.size() + m_exprComponents.rhs.size() < 40 && - m_exprComponents.lhs.find("\n") == std::string::npos && - m_exprComponents.rhs.find("\n") == std::string::npos ) - return m_exprComponents.lhs + " " + m_exprComponents.op + " " + m_exprComponents.rhs; - else - return m_exprComponents.lhs + "\n" + m_exprComponents.op + "\n" + m_exprComponents.rhs; - } - else - return "{can't expand - use " + m_assertionInfo.macroName + "_FALSE( " + m_assertionInfo.capturedExpression.substr(1) + " ) instead of " + m_assertionInfo.macroName + "( " + m_assertionInfo.capturedExpression + " ) for better diagnostics}"; - } - -} // end namespace Catch - -// #included from: catch_tag_alias_registry.hpp -#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_HPP_INCLUDED - -// #included from: catch_tag_alias_registry.h -#define TWOBLUECUBES_CATCH_TAG_ALIAS_REGISTRY_H_INCLUDED - -#include <map> - -namespace Catch { - - class TagAliasRegistry : public ITagAliasRegistry { - public: - virtual ~TagAliasRegistry(); - virtual Option<TagAlias> find( std::string const& alias ) const; - virtual std::string expandAliases( std::string const& unexpandedTestSpec ) const; - void add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ); - static TagAliasRegistry& get(); - - private: - std::map<std::string, TagAlias> m_registry; - }; - -} // end namespace Catch - -#include <map> -#include <iostream> - -namespace Catch { - - TagAliasRegistry::~TagAliasRegistry() {} - - Option<TagAlias> TagAliasRegistry::find( std::string const& alias ) const { - std::map<std::string, TagAlias>::const_iterator it = m_registry.find( alias ); - if( it != m_registry.end() ) - return it->second; - else - return Option<TagAlias>(); - } - - std::string TagAliasRegistry::expandAliases( std::string const& unexpandedTestSpec ) const { - std::string expandedTestSpec = unexpandedTestSpec; - for( std::map<std::string, TagAlias>::const_iterator it = m_registry.begin(), itEnd = m_registry.end(); - it != itEnd; - ++it ) { - std::size_t pos = expandedTestSpec.find( it->first ); - if( pos != std::string::npos ) { - expandedTestSpec = expandedTestSpec.substr( 0, pos ) + - it->second.tag + - expandedTestSpec.substr( pos + it->first.size() ); - } - } - return expandedTestSpec; - } - - void TagAliasRegistry::add( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { - - if( !startsWith( alias, "[@" ) || !endsWith( alias, "]" ) ) { - std::ostringstream oss; - oss << "error: tag alias, \"" << alias << "\" is not of the form [@alias name].\n" << lineInfo; - throw std::domain_error( oss.str().c_str() ); - } - if( !m_registry.insert( std::make_pair( alias, TagAlias( tag, lineInfo ) ) ).second ) { - std::ostringstream oss; - oss << "error: tag alias, \"" << alias << "\" already registered.\n" - << "\tFirst seen at " << find(alias)->lineInfo << "\n" - << "\tRedefined at " << lineInfo; - throw std::domain_error( oss.str().c_str() ); - } - } - - TagAliasRegistry& TagAliasRegistry::get() { - static TagAliasRegistry instance; - return instance; - - } - - ITagAliasRegistry::~ITagAliasRegistry() {} - ITagAliasRegistry const& ITagAliasRegistry::get() { return TagAliasRegistry::get(); } - - RegistrarForTagAliases::RegistrarForTagAliases( char const* alias, char const* tag, SourceLineInfo const& lineInfo ) { - try { - TagAliasRegistry::get().add( alias, tag, lineInfo ); - } - catch( std::exception& ex ) { - Colour colourGuard( Colour::Red ); - Catch::cerr() << ex.what() << std::endl; - exit(1); - } - } - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_xml.hpp -#define TWOBLUECUBES_CATCH_REPORTER_XML_HPP_INCLUDED - -// #included from: catch_reporter_bases.hpp -#define TWOBLUECUBES_CATCH_REPORTER_BASES_HPP_INCLUDED - -#include <cstring> - -namespace Catch { - - struct StreamingReporterBase : SharedImpl<IStreamingReporter> { - - StreamingReporterBase( ReporterConfig const& _config ) - : m_config( _config.fullConfig() ), - stream( _config.stream() ) - {} - - virtual ~StreamingReporterBase(); - - virtual void noMatchingTestCases( std::string const& ) {} - - virtual void testRunStarting( TestRunInfo const& _testRunInfo ) { - currentTestRunInfo = _testRunInfo; - } - virtual void testGroupStarting( GroupInfo const& _groupInfo ) { - currentGroupInfo = _groupInfo; - } - - virtual void testCaseStarting( TestCaseInfo const& _testInfo ) { - currentTestCaseInfo = _testInfo; - } - virtual void sectionStarting( SectionInfo const& _sectionInfo ) { - m_sectionStack.push_back( _sectionInfo ); - } - - virtual void sectionEnded( SectionStats const& /* _sectionStats */ ) { - m_sectionStack.pop_back(); - } - virtual void testCaseEnded( TestCaseStats const& /* _testCaseStats */ ) { - currentTestCaseInfo.reset(); - } - virtual void testGroupEnded( TestGroupStats const& /* _testGroupStats */ ) { - currentGroupInfo.reset(); - } - virtual void testRunEnded( TestRunStats const& /* _testRunStats */ ) { - currentTestCaseInfo.reset(); - currentGroupInfo.reset(); - currentTestRunInfo.reset(); - } - - virtual void skipTest( TestCaseInfo const& ) { - // Don't do anything with this by default. - // It can optionally be overridden in the derived class. - } - - Ptr<IConfig> m_config; - std::ostream& stream; - - LazyStat<TestRunInfo> currentTestRunInfo; - LazyStat<GroupInfo> currentGroupInfo; - LazyStat<TestCaseInfo> currentTestCaseInfo; - - std::vector<SectionInfo> m_sectionStack; - }; - - struct CumulativeReporterBase : SharedImpl<IStreamingReporter> { - template<typename T, typename ChildNodeT> - struct Node : SharedImpl<> { - explicit Node( T const& _value ) : value( _value ) {} - virtual ~Node() {} - - typedef std::vector<Ptr<ChildNodeT> > ChildNodes; - T value; - ChildNodes children; - }; - struct SectionNode : SharedImpl<> { - explicit SectionNode( SectionStats const& _stats ) : stats( _stats ) {} - virtual ~SectionNode(); - - bool operator == ( SectionNode const& other ) const { - return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; - } - bool operator == ( Ptr<SectionNode> const& other ) const { - return operator==( *other ); - } - - SectionStats stats; - typedef std::vector<Ptr<SectionNode> > ChildSections; - typedef std::vector<AssertionStats> Assertions; - ChildSections childSections; - Assertions assertions; - std::string stdOut; - std::string stdErr; - }; - - struct BySectionInfo { - BySectionInfo( SectionInfo const& other ) : m_other( other ) {} - BySectionInfo( BySectionInfo const& other ) : m_other( other.m_other ) {} - bool operator() ( Ptr<SectionNode> const& node ) const { - return node->stats.sectionInfo.lineInfo == m_other.lineInfo; - } - private: - void operator=( BySectionInfo const& ); - SectionInfo const& m_other; - }; - - typedef Node<TestCaseStats, SectionNode> TestCaseNode; - typedef Node<TestGroupStats, TestCaseNode> TestGroupNode; - typedef Node<TestRunStats, TestGroupNode> TestRunNode; - - CumulativeReporterBase( ReporterConfig const& _config ) - : m_config( _config.fullConfig() ), - stream( _config.stream() ) - {} - ~CumulativeReporterBase(); - - virtual void testRunStarting( TestRunInfo const& ) {} - virtual void testGroupStarting( GroupInfo const& ) {} - - virtual void testCaseStarting( TestCaseInfo const& ) {} - - virtual void sectionStarting( SectionInfo const& sectionInfo ) { - SectionStats incompleteStats( sectionInfo, Counts(), 0, false ); - Ptr<SectionNode> node; - if( m_sectionStack.empty() ) { - if( !m_rootSection ) - m_rootSection = new SectionNode( incompleteStats ); - node = m_rootSection; - } - else { - SectionNode& parentNode = *m_sectionStack.back(); - SectionNode::ChildSections::const_iterator it = - std::find_if( parentNode.childSections.begin(), - parentNode.childSections.end(), - BySectionInfo( sectionInfo ) ); - if( it == parentNode.childSections.end() ) { - node = new SectionNode( incompleteStats ); - parentNode.childSections.push_back( node ); - } - else - node = *it; - } - m_sectionStack.push_back( node ); - m_deepestSection = node; - } - - virtual void assertionStarting( AssertionInfo const& ) {} - - virtual bool assertionEnded( AssertionStats const& assertionStats ) { - assert( !m_sectionStack.empty() ); - SectionNode& sectionNode = *m_sectionStack.back(); - sectionNode.assertions.push_back( assertionStats ); - return true; - } - virtual void sectionEnded( SectionStats const& sectionStats ) { - assert( !m_sectionStack.empty() ); - SectionNode& node = *m_sectionStack.back(); - node.stats = sectionStats; - m_sectionStack.pop_back(); - } - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) { - Ptr<TestCaseNode> node = new TestCaseNode( testCaseStats ); - assert( m_sectionStack.size() == 0 ); - node->children.push_back( m_rootSection ); - m_testCases.push_back( node ); - m_rootSection.reset(); - - assert( m_deepestSection ); - m_deepestSection->stdOut = testCaseStats.stdOut; - m_deepestSection->stdErr = testCaseStats.stdErr; - } - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) { - Ptr<TestGroupNode> node = new TestGroupNode( testGroupStats ); - node->children.swap( m_testCases ); - m_testGroups.push_back( node ); - } - virtual void testRunEnded( TestRunStats const& testRunStats ) { - Ptr<TestRunNode> node = new TestRunNode( testRunStats ); - node->children.swap( m_testGroups ); - m_testRuns.push_back( node ); - testRunEndedCumulative(); - } - virtual void testRunEndedCumulative() = 0; - - virtual void skipTest( TestCaseInfo const& ) {} - - Ptr<IConfig> m_config; - std::ostream& stream; - std::vector<AssertionStats> m_assertions; - std::vector<std::vector<Ptr<SectionNode> > > m_sections; - std::vector<Ptr<TestCaseNode> > m_testCases; - std::vector<Ptr<TestGroupNode> > m_testGroups; - - std::vector<Ptr<TestRunNode> > m_testRuns; - - Ptr<SectionNode> m_rootSection; - Ptr<SectionNode> m_deepestSection; - std::vector<Ptr<SectionNode> > m_sectionStack; - - }; - - template<char C> - char const* getLineOfChars() { - static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; - if( !*line ) { - memset( line, C, CATCH_CONFIG_CONSOLE_WIDTH-1 ); - line[CATCH_CONFIG_CONSOLE_WIDTH-1] = 0; - } - return line; - } - -} // end namespace Catch - -// #included from: ../internal/catch_reporter_registrars.hpp -#define TWOBLUECUBES_CATCH_REPORTER_REGISTRARS_HPP_INCLUDED - -namespace Catch { - - template<typename T> - class LegacyReporterRegistrar { - - class ReporterFactory : public IReporterFactory { - virtual IStreamingReporter* create( ReporterConfig const& config ) const { - return new LegacyReporterAdapter( new T( config ) ); - } - - virtual std::string getDescription() const { - return T::getDescription(); - } - }; - - public: - - LegacyReporterRegistrar( std::string const& name ) { - getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); - } - }; - - template<typename T> - class ReporterRegistrar { - - class ReporterFactory : public IReporterFactory { - - // *** Please Note ***: - // - If you end up here looking at a compiler error because it's trying to register - // your custom reporter class be aware that the native reporter interface has changed - // to IStreamingReporter. The "legacy" interface, IReporter, is still supported via - // an adapter. Just use REGISTER_LEGACY_REPORTER to take advantage of the adapter. - // However please consider updating to the new interface as the old one is now - // deprecated and will probably be removed quite soon! - // Please contact me via github if you have any questions at all about this. - // In fact, ideally, please contact me anyway to let me know you've hit this - as I have - // no idea who is actually using custom reporters at all (possibly no-one!). - // The new interface is designed to minimise exposure to interface changes in the future. - virtual IStreamingReporter* create( ReporterConfig const& config ) const { - return new T( config ); - } - - virtual std::string getDescription() const { - return T::getDescription(); - } - }; - - public: - - ReporterRegistrar( std::string const& name ) { - getMutableRegistryHub().registerReporter( name, new ReporterFactory() ); - } - }; -} - -#define INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) \ - namespace{ Catch::LegacyReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } -#define INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) \ - namespace{ Catch::ReporterRegistrar<reporterType> catch_internal_RegistrarFor##reporterType( name ); } - -// #included from: ../internal/catch_xmlwriter.hpp -#define TWOBLUECUBES_CATCH_XMLWRITER_HPP_INCLUDED - -#include <sstream> -#include <string> -#include <vector> - -namespace Catch { - - class XmlWriter { - public: - - class ScopedElement { - public: - ScopedElement( XmlWriter* writer ) - : m_writer( writer ) - {} - - ScopedElement( ScopedElement const& other ) - : m_writer( other.m_writer ){ - other.m_writer = NULL; - } - - ~ScopedElement() { - if( m_writer ) - m_writer->endElement(); - } - - ScopedElement& writeText( std::string const& text, bool indent = true ) { - m_writer->writeText( text, indent ); - return *this; - } - - template<typename T> - ScopedElement& writeAttribute( std::string const& name, T const& attribute ) { - m_writer->writeAttribute( name, attribute ); - return *this; - } - - private: - mutable XmlWriter* m_writer; - }; - - XmlWriter() - : m_tagIsOpen( false ), - m_needsNewline( false ), - m_os( &Catch::cout() ) - {} - - XmlWriter( std::ostream& os ) - : m_tagIsOpen( false ), - m_needsNewline( false ), - m_os( &os ) - {} - - ~XmlWriter() { - while( !m_tags.empty() ) - endElement(); - } - - XmlWriter& startElement( std::string const& name ) { - ensureTagClosed(); - newlineIfNecessary(); - stream() << m_indent << "<" << name; - m_tags.push_back( name ); - m_indent += " "; - m_tagIsOpen = true; - return *this; - } - - ScopedElement scopedElement( std::string const& name ) { - ScopedElement scoped( this ); - startElement( name ); - return scoped; - } - - XmlWriter& endElement() { - newlineIfNecessary(); - m_indent = m_indent.substr( 0, m_indent.size()-2 ); - if( m_tagIsOpen ) { - stream() << "/>\n"; - m_tagIsOpen = false; - } - else { - stream() << m_indent << "</" << m_tags.back() << ">\n"; - } - m_tags.pop_back(); - return *this; - } - - XmlWriter& writeAttribute( std::string const& name, std::string const& attribute ) { - if( !name.empty() && !attribute.empty() ) { - stream() << " " << name << "=\""; - writeEncodedText( attribute ); - stream() << "\""; - } - return *this; - } - - XmlWriter& writeAttribute( std::string const& name, bool attribute ) { - stream() << " " << name << "=\"" << ( attribute ? "true" : "false" ) << "\""; - return *this; - } - - template<typename T> - XmlWriter& writeAttribute( std::string const& name, T const& attribute ) { - if( !name.empty() ) - stream() << " " << name << "=\"" << attribute << "\""; - return *this; - } - - XmlWriter& writeText( std::string const& text, bool indent = true ) { - if( !text.empty() ){ - bool tagWasOpen = m_tagIsOpen; - ensureTagClosed(); - if( tagWasOpen && indent ) - stream() << m_indent; - writeEncodedText( text ); - m_needsNewline = true; - } - return *this; - } - - XmlWriter& writeComment( std::string const& text ) { - ensureTagClosed(); - stream() << m_indent << "<!--" << text << "-->"; - m_needsNewline = true; - return *this; - } - - XmlWriter& writeBlankLine() { - ensureTagClosed(); - stream() << "\n"; - return *this; - } - - void setStream( std::ostream& os ) { - m_os = &os; - } - - private: - XmlWriter( XmlWriter const& ); - void operator=( XmlWriter const& ); - - std::ostream& stream() { - return *m_os; - } - - void ensureTagClosed() { - if( m_tagIsOpen ) { - stream() << ">\n"; - m_tagIsOpen = false; - } - } - - void newlineIfNecessary() { - if( m_needsNewline ) { - stream() << "\n"; - m_needsNewline = false; - } - } - - void writeEncodedText( std::string const& text ) { - static const char* charsToEncode = "<&\""; - std::string mtext = text; - std::string::size_type pos = mtext.find_first_of( charsToEncode ); - while( pos != std::string::npos ) { - stream() << mtext.substr( 0, pos ); - - switch( mtext[pos] ) { - case '<': - stream() << "<"; - break; - case '&': - stream() << "&"; - break; - case '\"': - stream() << """; - break; - } - mtext = mtext.substr( pos+1 ); - pos = mtext.find_first_of( charsToEncode ); - } - stream() << mtext; - } - - bool m_tagIsOpen; - bool m_needsNewline; - std::vector<std::string> m_tags; - std::string m_indent; - std::ostream* m_os; - }; - -} -namespace Catch { - class XmlReporter : public StreamingReporterBase { - public: - XmlReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ), - m_sectionDepth( 0 ) - {} - - virtual ~XmlReporter(); - - static std::string getDescription() { - return "Reports test results as an XML document"; - } - - public: // StreamingReporterBase - virtual ReporterPreferences getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = true; - return prefs; - } - - virtual void noMatchingTestCases( std::string const& s ) { - StreamingReporterBase::noMatchingTestCases( s ); - } - - virtual void testRunStarting( TestRunInfo const& testInfo ) { - StreamingReporterBase::testRunStarting( testInfo ); - m_xml.setStream( stream ); - m_xml.startElement( "Catch" ); - if( !m_config->name().empty() ) - m_xml.writeAttribute( "name", m_config->name() ); - } - - virtual void testGroupStarting( GroupInfo const& groupInfo ) { - StreamingReporterBase::testGroupStarting( groupInfo ); - m_xml.startElement( "Group" ) - .writeAttribute( "name", groupInfo.name ); - } - - virtual void testCaseStarting( TestCaseInfo const& testInfo ) { - StreamingReporterBase::testCaseStarting(testInfo); - m_xml.startElement( "TestCase" ).writeAttribute( "name", trim( testInfo.name ) ); - - if ( m_config->showDurations() == ShowDurations::Always ) - m_testCaseTimer.start(); - } - - virtual void sectionStarting( SectionInfo const& sectionInfo ) { - StreamingReporterBase::sectionStarting( sectionInfo ); - if( m_sectionDepth++ > 0 ) { - m_xml.startElement( "Section" ) - .writeAttribute( "name", trim( sectionInfo.name ) ) - .writeAttribute( "description", sectionInfo.description ); - } - } - - virtual void assertionStarting( AssertionInfo const& ) { } - - virtual bool assertionEnded( AssertionStats const& assertionStats ) { - const AssertionResult& assertionResult = assertionStats.assertionResult; - - // Print any info messages in <Info> tags. - if( assertionStats.assertionResult.getResultType() != ResultWas::Ok ) { - for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end(); - it != itEnd; - ++it ) { - if( it->type == ResultWas::Info ) { - m_xml.scopedElement( "Info" ) - .writeText( it->message ); - } else if ( it->type == ResultWas::Warning ) { - m_xml.scopedElement( "Warning" ) - .writeText( it->message ); - } - } - } - - // Drop out if result was successful but we're not printing them. - if( !m_config->includeSuccessfulResults() && isOk(assertionResult.getResultType()) ) - return true; - - // Print the expression if there is one. - if( assertionResult.hasExpression() ) { - m_xml.startElement( "Expression" ) - .writeAttribute( "success", assertionResult.succeeded() ) - .writeAttribute( "type", assertionResult.getTestMacroName() ) - .writeAttribute( "filename", assertionResult.getSourceInfo().file ) - .writeAttribute( "line", assertionResult.getSourceInfo().line ); - - m_xml.scopedElement( "Original" ) - .writeText( assertionResult.getExpression() ); - m_xml.scopedElement( "Expanded" ) - .writeText( assertionResult.getExpandedExpression() ); - } - - // And... Print a result applicable to each result type. - switch( assertionResult.getResultType() ) { - case ResultWas::ThrewException: - m_xml.scopedElement( "Exception" ) - .writeAttribute( "filename", assertionResult.getSourceInfo().file ) - .writeAttribute( "line", assertionResult.getSourceInfo().line ) - .writeText( assertionResult.getMessage() ); - break; - case ResultWas::FatalErrorCondition: - m_xml.scopedElement( "Fatal Error Condition" ) - .writeAttribute( "filename", assertionResult.getSourceInfo().file ) - .writeAttribute( "line", assertionResult.getSourceInfo().line ) - .writeText( assertionResult.getMessage() ); - break; - case ResultWas::Info: - m_xml.scopedElement( "Info" ) - .writeText( assertionResult.getMessage() ); - break; - case ResultWas::Warning: - // Warning will already have been written - break; - case ResultWas::ExplicitFailure: - m_xml.scopedElement( "Failure" ) - .writeText( assertionResult.getMessage() ); - break; - default: - break; - } - - if( assertionResult.hasExpression() ) - m_xml.endElement(); - - return true; - } - - virtual void sectionEnded( SectionStats const& sectionStats ) { - StreamingReporterBase::sectionEnded( sectionStats ); - if( --m_sectionDepth > 0 ) { - XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResults" ); - e.writeAttribute( "successes", sectionStats.assertions.passed ); - e.writeAttribute( "failures", sectionStats.assertions.failed ); - e.writeAttribute( "expectedFailures", sectionStats.assertions.failedButOk ); - - if ( m_config->showDurations() == ShowDurations::Always ) - e.writeAttribute( "durationInSeconds", sectionStats.durationInSeconds ); - - m_xml.endElement(); - } - } - - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) { - StreamingReporterBase::testCaseEnded( testCaseStats ); - XmlWriter::ScopedElement e = m_xml.scopedElement( "OverallResult" ); - e.writeAttribute( "success", testCaseStats.totals.assertions.allOk() ); - - if ( m_config->showDurations() == ShowDurations::Always ) - e.writeAttribute( "durationInSeconds", m_testCaseTimer.getElapsedSeconds() ); - - m_xml.endElement(); - } - - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) { - StreamingReporterBase::testGroupEnded( testGroupStats ); - // TODO: Check testGroupStats.aborting and act accordingly. - m_xml.scopedElement( "OverallResults" ) - .writeAttribute( "successes", testGroupStats.totals.assertions.passed ) - .writeAttribute( "failures", testGroupStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testGroupStats.totals.assertions.failedButOk ); - m_xml.endElement(); - } - - virtual void testRunEnded( TestRunStats const& testRunStats ) { - StreamingReporterBase::testRunEnded( testRunStats ); - m_xml.scopedElement( "OverallResults" ) - .writeAttribute( "successes", testRunStats.totals.assertions.passed ) - .writeAttribute( "failures", testRunStats.totals.assertions.failed ) - .writeAttribute( "expectedFailures", testRunStats.totals.assertions.failedButOk ); - m_xml.endElement(); - } - - private: - Timer m_testCaseTimer; - XmlWriter m_xml; - int m_sectionDepth; - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "xml", XmlReporter ) - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_junit.hpp -#define TWOBLUECUBES_CATCH_REPORTER_JUNIT_HPP_INCLUDED - -#include <assert.h> - -namespace Catch { - - class JunitReporter : public CumulativeReporterBase { - public: - JunitReporter( ReporterConfig const& _config ) - : CumulativeReporterBase( _config ), - xml( _config.stream() ) - {} - - ~JunitReporter(); - - static std::string getDescription() { - return "Reports test results in an XML format that looks like Ant's junitreport target"; - } - - virtual void noMatchingTestCases( std::string const& /*spec*/ ) {} - - virtual ReporterPreferences getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = true; - return prefs; - } - - virtual void testRunStarting( TestRunInfo const& runInfo ) { - CumulativeReporterBase::testRunStarting( runInfo ); - xml.startElement( "testsuites" ); - } - - virtual void testGroupStarting( GroupInfo const& groupInfo ) { - suiteTimer.start(); - stdOutForSuite.str(""); - stdErrForSuite.str(""); - unexpectedExceptions = 0; - CumulativeReporterBase::testGroupStarting( groupInfo ); - } - - virtual bool assertionEnded( AssertionStats const& assertionStats ) { - if( assertionStats.assertionResult.getResultType() == ResultWas::ThrewException ) - unexpectedExceptions++; - return CumulativeReporterBase::assertionEnded( assertionStats ); - } - - virtual void testCaseEnded( TestCaseStats const& testCaseStats ) { - stdOutForSuite << testCaseStats.stdOut; - stdErrForSuite << testCaseStats.stdErr; - CumulativeReporterBase::testCaseEnded( testCaseStats ); - } - - virtual void testGroupEnded( TestGroupStats const& testGroupStats ) { - double suiteTime = suiteTimer.getElapsedSeconds(); - CumulativeReporterBase::testGroupEnded( testGroupStats ); - writeGroup( *m_testGroups.back(), suiteTime ); - } - - virtual void testRunEndedCumulative() { - xml.endElement(); - } - - void writeGroup( TestGroupNode const& groupNode, double suiteTime ) { - XmlWriter::ScopedElement e = xml.scopedElement( "testsuite" ); - TestGroupStats const& stats = groupNode.value; - xml.writeAttribute( "name", stats.groupInfo.name ); - xml.writeAttribute( "errors", unexpectedExceptions ); - xml.writeAttribute( "failures", stats.totals.assertions.failed-unexpectedExceptions ); - xml.writeAttribute( "tests", stats.totals.assertions.total() ); - xml.writeAttribute( "hostname", "tbd" ); // !TBD - if( m_config->showDurations() == ShowDurations::Never ) - xml.writeAttribute( "time", "" ); - else - xml.writeAttribute( "time", suiteTime ); - xml.writeAttribute( "timestamp", "tbd" ); // !TBD - - // Write test cases - for( TestGroupNode::ChildNodes::const_iterator - it = groupNode.children.begin(), itEnd = groupNode.children.end(); - it != itEnd; - ++it ) - writeTestCase( **it ); - - xml.scopedElement( "system-out" ).writeText( trim( stdOutForSuite.str() ), false ); - xml.scopedElement( "system-err" ).writeText( trim( stdErrForSuite.str() ), false ); - } - - void writeTestCase( TestCaseNode const& testCaseNode ) { - TestCaseStats const& stats = testCaseNode.value; - - // All test cases have exactly one section - which represents the - // test case itself. That section may have 0-n nested sections - assert( testCaseNode.children.size() == 1 ); - SectionNode const& rootSection = *testCaseNode.children.front(); - - std::string className = stats.testInfo.className; - - if( className.empty() ) { - if( rootSection.childSections.empty() ) - className = "global"; - } - writeSection( className, "", rootSection ); - } - - void writeSection( std::string const& className, - std::string const& rootName, - SectionNode const& sectionNode ) { - std::string name = trim( sectionNode.stats.sectionInfo.name ); - if( !rootName.empty() ) - name = rootName + "/" + name; - - if( !sectionNode.assertions.empty() || - !sectionNode.stdOut.empty() || - !sectionNode.stdErr.empty() ) { - XmlWriter::ScopedElement e = xml.scopedElement( "testcase" ); - if( className.empty() ) { - xml.writeAttribute( "classname", name ); - xml.writeAttribute( "name", "root" ); - } - else { - xml.writeAttribute( "classname", className ); - xml.writeAttribute( "name", name ); - } - xml.writeAttribute( "time", Catch::toString( sectionNode.stats.durationInSeconds ) ); - - writeAssertions( sectionNode ); - - if( !sectionNode.stdOut.empty() ) - xml.scopedElement( "system-out" ).writeText( trim( sectionNode.stdOut ), false ); - if( !sectionNode.stdErr.empty() ) - xml.scopedElement( "system-err" ).writeText( trim( sectionNode.stdErr ), false ); - } - for( SectionNode::ChildSections::const_iterator - it = sectionNode.childSections.begin(), - itEnd = sectionNode.childSections.end(); - it != itEnd; - ++it ) - if( className.empty() ) - writeSection( name, "", **it ); - else - writeSection( className, name, **it ); - } - - void writeAssertions( SectionNode const& sectionNode ) { - for( SectionNode::Assertions::const_iterator - it = sectionNode.assertions.begin(), itEnd = sectionNode.assertions.end(); - it != itEnd; - ++it ) - writeAssertion( *it ); - } - void writeAssertion( AssertionStats const& stats ) { - AssertionResult const& result = stats.assertionResult; - if( !result.isOk() ) { - std::string elementName; - switch( result.getResultType() ) { - case ResultWas::ThrewException: - case ResultWas::FatalErrorCondition: - elementName = "error"; - break; - case ResultWas::ExplicitFailure: - elementName = "failure"; - break; - case ResultWas::ExpressionFailed: - elementName = "failure"; - break; - case ResultWas::DidntThrowException: - elementName = "failure"; - break; - - // We should never see these here: - case ResultWas::Info: - case ResultWas::Warning: - case ResultWas::Ok: - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - elementName = "internalError"; - break; - } - - XmlWriter::ScopedElement e = xml.scopedElement( elementName ); - - xml.writeAttribute( "message", result.getExpandedExpression() ); - xml.writeAttribute( "type", result.getTestMacroName() ); - - std::ostringstream oss; - if( !result.getMessage().empty() ) - oss << result.getMessage() << "\n"; - for( std::vector<MessageInfo>::const_iterator - it = stats.infoMessages.begin(), - itEnd = stats.infoMessages.end(); - it != itEnd; - ++it ) - if( it->type == ResultWas::Info ) - oss << it->message << "\n"; - - oss << "at " << result.getSourceInfo(); - xml.writeText( oss.str(), false ); - } - } - - XmlWriter xml; - Timer suiteTimer; - std::ostringstream stdOutForSuite; - std::ostringstream stdErrForSuite; - unsigned int unexpectedExceptions; - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "junit", JunitReporter ) - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_console.hpp -#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED - -namespace Catch { - - struct ConsoleReporter : StreamingReporterBase { - ConsoleReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ), - m_headerPrinted( false ) - {} - - virtual ~ConsoleReporter(); - static std::string getDescription() { - return "Reports test results as plain lines of text"; - } - virtual ReporterPreferences getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = false; - return prefs; - } - - virtual void noMatchingTestCases( std::string const& spec ) { - stream << "No test cases matched '" << spec << "'" << std::endl; - } - - virtual void assertionStarting( AssertionInfo const& ) { - } - - virtual bool assertionEnded( AssertionStats const& _assertionStats ) { - AssertionResult const& result = _assertionStats.assertionResult; - - bool printInfoMessages = true; - - // Drop out if result was successful and we're not printing those - if( !m_config->includeSuccessfulResults() && result.isOk() ) { - if( result.getResultType() != ResultWas::Warning ) - return false; - printInfoMessages = false; - } - - lazyPrint(); - - AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); - printer.print(); - stream << std::endl; - return true; - } - - virtual void sectionStarting( SectionInfo const& _sectionInfo ) { - m_headerPrinted = false; - StreamingReporterBase::sectionStarting( _sectionInfo ); - } - virtual void sectionEnded( SectionStats const& _sectionStats ) { - if( _sectionStats.missingAssertions ) { - lazyPrint(); - Colour colour( Colour::ResultError ); - if( m_sectionStack.size() > 1 ) - stream << "\nNo assertions in section"; - else - stream << "\nNo assertions in test case"; - stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; - } - if( m_headerPrinted ) { - if( m_config->showDurations() == ShowDurations::Always ) - stream << "Completed in " << _sectionStats.durationInSeconds << "s" << std::endl; - m_headerPrinted = false; - } - else { - if( m_config->showDurations() == ShowDurations::Always ) - stream << _sectionStats.sectionInfo.name << " completed in " << _sectionStats.durationInSeconds << "s" << std::endl; - } - StreamingReporterBase::sectionEnded( _sectionStats ); - } - - virtual void testCaseEnded( TestCaseStats const& _testCaseStats ) { - StreamingReporterBase::testCaseEnded( _testCaseStats ); - m_headerPrinted = false; - } - virtual void testGroupEnded( TestGroupStats const& _testGroupStats ) { - if( currentGroupInfo.used ) { - printSummaryDivider(); - stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; - printTotals( _testGroupStats.totals ); - stream << "\n" << std::endl; - } - StreamingReporterBase::testGroupEnded( _testGroupStats ); - } - virtual void testRunEnded( TestRunStats const& _testRunStats ) { - printTotalsDivider( _testRunStats.totals ); - printTotals( _testRunStats.totals ); - stream << std::endl; - StreamingReporterBase::testRunEnded( _testRunStats ); - } - - private: - - class AssertionPrinter { - void operator= ( AssertionPrinter const& ); - public: - AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) - : stream( _stream ), - stats( _stats ), - result( _stats.assertionResult ), - colour( Colour::None ), - message( result.getMessage() ), - messages( _stats.infoMessages ), - printInfoMessages( _printInfoMessages ) - { - switch( result.getResultType() ) { - case ResultWas::Ok: - colour = Colour::Success; - passOrFail = "PASSED"; - //if( result.hasMessage() ) - if( _stats.infoMessages.size() == 1 ) - messageLabel = "with message"; - if( _stats.infoMessages.size() > 1 ) - messageLabel = "with messages"; - break; - case ResultWas::ExpressionFailed: - if( result.isOk() ) { - colour = Colour::Success; - passOrFail = "FAILED - but was ok"; - } - else { - colour = Colour::Error; - passOrFail = "FAILED"; - } - if( _stats.infoMessages.size() == 1 ) - messageLabel = "with message"; - if( _stats.infoMessages.size() > 1 ) - messageLabel = "with messages"; - break; - case ResultWas::ThrewException: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "due to unexpected exception with message"; - break; - case ResultWas::FatalErrorCondition: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "due to a fatal error condition"; - break; - case ResultWas::DidntThrowException: - colour = Colour::Error; - passOrFail = "FAILED"; - messageLabel = "because no exception was thrown where one was expected"; - break; - case ResultWas::Info: - messageLabel = "info"; - break; - case ResultWas::Warning: - messageLabel = "warning"; - break; - case ResultWas::ExplicitFailure: - passOrFail = "FAILED"; - colour = Colour::Error; - if( _stats.infoMessages.size() == 1 ) - messageLabel = "explicitly with message"; - if( _stats.infoMessages.size() > 1 ) - messageLabel = "explicitly with messages"; - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - passOrFail = "** internal error **"; - colour = Colour::Error; - break; - } - } - - void print() const { - printSourceInfo(); - if( stats.totals.assertions.total() > 0 ) { - if( result.isOk() ) - stream << "\n"; - printResultType(); - printOriginalExpression(); - printReconstructedExpression(); - } - else { - stream << "\n"; - } - printMessage(); - } - - private: - void printResultType() const { - if( !passOrFail.empty() ) { - Colour colourGuard( colour ); - stream << passOrFail << ":\n"; - } - } - void printOriginalExpression() const { - if( result.hasExpression() ) { - Colour colourGuard( Colour::OriginalExpression ); - stream << " "; - stream << result.getExpressionInMacro(); - stream << "\n"; - } - } - void printReconstructedExpression() const { - if( result.hasExpandedExpression() ) { - stream << "with expansion:\n"; - Colour colourGuard( Colour::ReconstructedExpression ); - stream << Text( result.getExpandedExpression(), TextAttributes().setIndent(2) ) << "\n"; - } - } - void printMessage() const { - if( !messageLabel.empty() ) - stream << messageLabel << ":" << "\n"; - for( std::vector<MessageInfo>::const_iterator it = messages.begin(), itEnd = messages.end(); - it != itEnd; - ++it ) { - // If this assertion is a warning ignore any INFO messages - if( printInfoMessages || it->type != ResultWas::Info ) - stream << Text( it->message, TextAttributes().setIndent(2) ) << "\n"; - } - } - void printSourceInfo() const { - Colour colourGuard( Colour::FileName ); - stream << result.getSourceInfo() << ": "; - } - - std::ostream& stream; - AssertionStats const& stats; - AssertionResult const& result; - Colour::Code colour; - std::string passOrFail; - std::string messageLabel; - std::string message; - std::vector<MessageInfo> messages; - bool printInfoMessages; - }; - - void lazyPrint() { - - if( !currentTestRunInfo.used ) - lazyPrintRunInfo(); - if( !currentGroupInfo.used ) - lazyPrintGroupInfo(); - - if( !m_headerPrinted ) { - printTestCaseAndSectionHeader(); - m_headerPrinted = true; - } - } - void lazyPrintRunInfo() { - stream << "\n" << getLineOfChars<'~'>() << "\n"; - Colour colour( Colour::SecondaryText ); - stream << currentTestRunInfo->name - << " is a Catch v" << libraryVersion.majorVersion << "." - << libraryVersion.minorVersion << " b" - << libraryVersion.buildNumber; - if( libraryVersion.branchName != std::string( "master" ) ) - stream << " (" << libraryVersion.branchName << ")"; - stream << " host application.\n" - << "Run with -? for options\n\n"; - - if( m_config->rngSeed() != 0 ) - stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; - - currentTestRunInfo.used = true; - } - void lazyPrintGroupInfo() { - if( !currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1 ) { - printClosedHeader( "Group: " + currentGroupInfo->name ); - currentGroupInfo.used = true; - } - } - void printTestCaseAndSectionHeader() { - assert( !m_sectionStack.empty() ); - printOpenHeader( currentTestCaseInfo->name ); - - if( m_sectionStack.size() > 1 ) { - Colour colourGuard( Colour::Headers ); - - std::vector<SectionInfo>::const_iterator - it = m_sectionStack.begin()+1, // Skip first section (test case) - itEnd = m_sectionStack.end(); - for( ; it != itEnd; ++it ) - printHeaderString( it->name, 2 ); - } - - SourceLineInfo lineInfo = m_sectionStack.front().lineInfo; - - if( !lineInfo.empty() ){ - stream << getLineOfChars<'-'>() << "\n"; - Colour colourGuard( Colour::FileName ); - stream << lineInfo << "\n"; - } - stream << getLineOfChars<'.'>() << "\n" << std::endl; - } - - void printClosedHeader( std::string const& _name ) { - printOpenHeader( _name ); - stream << getLineOfChars<'.'>() << "\n"; - } - void printOpenHeader( std::string const& _name ) { - stream << getLineOfChars<'-'>() << "\n"; - { - Colour colourGuard( Colour::Headers ); - printHeaderString( _name ); - } - } - - // if string has a : in first line will set indent to follow it on - // subsequent lines - void printHeaderString( std::string const& _string, std::size_t indent = 0 ) { - std::size_t i = _string.find( ": " ); - if( i != std::string::npos ) - i+=2; - else - i = 0; - stream << Text( _string, TextAttributes() - .setIndent( indent+i) - .setInitialIndent( indent ) ) << "\n"; - } - - struct SummaryColumn { - - SummaryColumn( std::string const& _label, Colour::Code _colour ) - : label( _label ), - colour( _colour ) - {} - SummaryColumn addRow( std::size_t count ) { - std::ostringstream oss; - oss << count; - std::string row = oss.str(); - for( std::vector<std::string>::iterator it = rows.begin(); it != rows.end(); ++it ) { - while( it->size() < row.size() ) - *it = " " + *it; - while( it->size() > row.size() ) - row = " " + row; - } - rows.push_back( row ); - return *this; - } - - std::string label; - Colour::Code colour; - std::vector<std::string> rows; - - }; - - void printTotals( Totals const& totals ) { - if( totals.testCases.total() == 0 ) { - stream << Colour( Colour::Warning ) << "No tests ran\n"; - } - else if( totals.assertions.total() > 0 && totals.assertions.allPassed() ) { - stream << Colour( Colour::ResultSuccess ) << "All tests passed"; - stream << " (" - << pluralise( totals.assertions.passed, "assertion" ) << " in " - << pluralise( totals.testCases.passed, "test case" ) << ")" - << "\n"; - } - else { - - std::vector<SummaryColumn> columns; - columns.push_back( SummaryColumn( "", Colour::None ) - .addRow( totals.testCases.total() ) - .addRow( totals.assertions.total() ) ); - columns.push_back( SummaryColumn( "passed", Colour::Success ) - .addRow( totals.testCases.passed ) - .addRow( totals.assertions.passed ) ); - columns.push_back( SummaryColumn( "failed", Colour::ResultError ) - .addRow( totals.testCases.failed ) - .addRow( totals.assertions.failed ) ); - columns.push_back( SummaryColumn( "failed as expected", Colour::ResultExpectedFailure ) - .addRow( totals.testCases.failedButOk ) - .addRow( totals.assertions.failedButOk ) ); - - printSummaryRow( "test cases", columns, 0 ); - printSummaryRow( "assertions", columns, 1 ); - } - } - void printSummaryRow( std::string const& label, std::vector<SummaryColumn> const& cols, std::size_t row ) { - for( std::vector<SummaryColumn>::const_iterator it = cols.begin(); it != cols.end(); ++it ) { - std::string value = it->rows[row]; - if( it->label.empty() ) { - stream << label << ": "; - if( value != "0" ) - stream << value; - else - stream << Colour( Colour::Warning ) << "- none -"; - } - else if( value != "0" ) { - stream << Colour( Colour::LightGrey ) << " | "; - stream << Colour( it->colour ) - << value << " " << it->label; - } - } - stream << "\n"; - } - - static std::size_t makeRatio( std::size_t number, std::size_t total ) { - std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number/ total : 0; - return ( ratio == 0 && number > 0 ) ? 1 : ratio; - } - static std::size_t& findMax( std::size_t& i, std::size_t& j, std::size_t& k ) { - if( i > j && i > k ) - return i; - else if( j > k ) - return j; - else - return k; - } - - void printTotalsDivider( Totals const& totals ) { - if( totals.testCases.total() > 0 ) { - std::size_t failedRatio = makeRatio( totals.testCases.failed, totals.testCases.total() ); - std::size_t failedButOkRatio = makeRatio( totals.testCases.failedButOk, totals.testCases.total() ); - std::size_t passedRatio = makeRatio( totals.testCases.passed, totals.testCases.total() ); - while( failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH-1 ) - findMax( failedRatio, failedButOkRatio, passedRatio )++; - while( failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH-1 ) - findMax( failedRatio, failedButOkRatio, passedRatio )--; - - stream << Colour( Colour::Error ) << std::string( failedRatio, '=' ); - stream << Colour( Colour::ResultExpectedFailure ) << std::string( failedButOkRatio, '=' ); - if( totals.testCases.allPassed() ) - stream << Colour( Colour::ResultSuccess ) << std::string( passedRatio, '=' ); - else - stream << Colour( Colour::Success ) << std::string( passedRatio, '=' ); - } - else { - stream << Colour( Colour::Warning ) << std::string( CATCH_CONFIG_CONSOLE_WIDTH-1, '=' ); - } - stream << "\n"; - } - void printSummaryDivider() { - stream << getLineOfChars<'-'>() << "\n"; - } - - private: - bool m_headerPrinted; - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "console", ConsoleReporter ) - -} // end namespace Catch - -// #included from: ../reporters/catch_reporter_compact.hpp -#define TWOBLUECUBES_CATCH_REPORTER_COMPACT_HPP_INCLUDED - -namespace Catch { - - struct CompactReporter : StreamingReporterBase { - - CompactReporter( ReporterConfig const& _config ) - : StreamingReporterBase( _config ) - {} - - virtual ~CompactReporter(); - - static std::string getDescription() { - return "Reports test results on a single line, suitable for IDEs"; - } - - virtual ReporterPreferences getPreferences() const { - ReporterPreferences prefs; - prefs.shouldRedirectStdOut = false; - return prefs; - } - - virtual void noMatchingTestCases( std::string const& spec ) { - stream << "No test cases matched '" << spec << "'" << std::endl; - } - - virtual void assertionStarting( AssertionInfo const& ) { - } - - virtual bool assertionEnded( AssertionStats const& _assertionStats ) { - AssertionResult const& result = _assertionStats.assertionResult; - - bool printInfoMessages = true; - - // Drop out if result was successful and we're not printing those - if( !m_config->includeSuccessfulResults() && result.isOk() ) { - if( result.getResultType() != ResultWas::Warning ) - return false; - printInfoMessages = false; - } - - AssertionPrinter printer( stream, _assertionStats, printInfoMessages ); - printer.print(); - - stream << std::endl; - return true; - } - - virtual void testRunEnded( TestRunStats const& _testRunStats ) { - printTotals( _testRunStats.totals ); - stream << "\n" << std::endl; - StreamingReporterBase::testRunEnded( _testRunStats ); - } - - private: - class AssertionPrinter { - void operator= ( AssertionPrinter const& ); - public: - AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, bool _printInfoMessages ) - : stream( _stream ) - , stats( _stats ) - , result( _stats.assertionResult ) - , messages( _stats.infoMessages ) - , itMessage( _stats.infoMessages.begin() ) - , printInfoMessages( _printInfoMessages ) - {} - - void print() { - printSourceInfo(); - - itMessage = messages.begin(); - - switch( result.getResultType() ) { - case ResultWas::Ok: - printResultType( Colour::ResultSuccess, passedString() ); - printOriginalExpression(); - printReconstructedExpression(); - if ( ! result.hasExpression() ) - printRemainingMessages( Colour::None ); - else - printRemainingMessages(); - break; - case ResultWas::ExpressionFailed: - if( result.isOk() ) - printResultType( Colour::ResultSuccess, failedString() + std::string( " - but was ok" ) ); - else - printResultType( Colour::Error, failedString() ); - printOriginalExpression(); - printReconstructedExpression(); - printRemainingMessages(); - break; - case ResultWas::ThrewException: - printResultType( Colour::Error, failedString() ); - printIssue( "unexpected exception with message:" ); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::FatalErrorCondition: - printResultType( Colour::Error, failedString() ); - printIssue( "fatal error condition with message:" ); - printMessage(); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::DidntThrowException: - printResultType( Colour::Error, failedString() ); - printIssue( "expected exception, got none" ); - printExpressionWas(); - printRemainingMessages(); - break; - case ResultWas::Info: - printResultType( Colour::None, "info" ); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::Warning: - printResultType( Colour::None, "warning" ); - printMessage(); - printRemainingMessages(); - break; - case ResultWas::ExplicitFailure: - printResultType( Colour::Error, failedString() ); - printIssue( "explicitly" ); - printRemainingMessages( Colour::None ); - break; - // These cases are here to prevent compiler warnings - case ResultWas::Unknown: - case ResultWas::FailureBit: - case ResultWas::Exception: - printResultType( Colour::Error, "** internal error **" ); - break; - } - } - - private: - // Colour::LightGrey - - static Colour::Code dimColour() { return Colour::FileName; } - -#ifdef CATCH_PLATFORM_MAC - static const char* failedString() { return "FAILED"; } - static const char* passedString() { return "PASSED"; } -#else - static const char* failedString() { return "failed"; } - static const char* passedString() { return "passed"; } -#endif - - void printSourceInfo() const { - Colour colourGuard( Colour::FileName ); - stream << result.getSourceInfo() << ":"; - } - - void printResultType( Colour::Code colour, std::string passOrFail ) const { - if( !passOrFail.empty() ) { - { - Colour colourGuard( colour ); - stream << " " << passOrFail; - } - stream << ":"; - } - } - - void printIssue( std::string issue ) const { - stream << " " << issue; - } - - void printExpressionWas() { - if( result.hasExpression() ) { - stream << ";"; - { - Colour colour( dimColour() ); - stream << " expression was:"; - } - printOriginalExpression(); - } - } - - void printOriginalExpression() const { - if( result.hasExpression() ) { - stream << " " << result.getExpression(); - } - } - - void printReconstructedExpression() const { - if( result.hasExpandedExpression() ) { - { - Colour colour( dimColour() ); - stream << " for: "; - } - stream << result.getExpandedExpression(); - } - } - - void printMessage() { - if ( itMessage != messages.end() ) { - stream << " '" << itMessage->message << "'"; - ++itMessage; - } - } - - void printRemainingMessages( Colour::Code colour = dimColour() ) { - if ( itMessage == messages.end() ) - return; - - // using messages.end() directly yields compilation error: - std::vector<MessageInfo>::const_iterator itEnd = messages.end(); - const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) ); - - { - Colour colourGuard( colour ); - stream << " with " << pluralise( N, "message" ) << ":"; - } - - for(; itMessage != itEnd; ) { - // If this assertion is a warning ignore any INFO messages - if( printInfoMessages || itMessage->type != ResultWas::Info ) { - stream << " '" << itMessage->message << "'"; - if ( ++itMessage != itEnd ) { - Colour colourGuard( dimColour() ); - stream << " and"; - } - } - } - } - - private: - std::ostream& stream; - AssertionStats const& stats; - AssertionResult const& result; - std::vector<MessageInfo> messages; - std::vector<MessageInfo>::const_iterator itMessage; - bool printInfoMessages; - }; - - // Colour, message variants: - // - white: No tests ran. - // - red: Failed [both/all] N test cases, failed [both/all] M assertions. - // - white: Passed [both/all] N test cases (no assertions). - // - red: Failed N tests cases, failed M assertions. - // - green: Passed [both/all] N tests cases with M assertions. - - std::string bothOrAll( std::size_t count ) const { - return count == 1 ? "" : count == 2 ? "both " : "all " ; - } - - void printTotals( const Totals& totals ) const { - if( totals.testCases.total() == 0 ) { - stream << "No tests ran."; - } - else if( totals.testCases.failed == totals.testCases.total() ) { - Colour colour( Colour::ResultError ); - const std::string qualify_assertions_failed = - totals.assertions.failed == totals.assertions.total() ? - bothOrAll( totals.assertions.failed ) : ""; - stream << - "Failed " << bothOrAll( totals.testCases.failed ) - << pluralise( totals.testCases.failed, "test case" ) << ", " - "failed " << qualify_assertions_failed << - pluralise( totals.assertions.failed, "assertion" ) << "."; - } - else if( totals.assertions.total() == 0 ) { - stream << - "Passed " << bothOrAll( totals.testCases.total() ) - << pluralise( totals.testCases.total(), "test case" ) - << " (no assertions)."; - } - else if( totals.assertions.failed ) { - Colour colour( Colour::ResultError ); - stream << - "Failed " << pluralise( totals.testCases.failed, "test case" ) << ", " - "failed " << pluralise( totals.assertions.failed, "assertion" ) << "."; - } - else { - Colour colour( Colour::ResultSuccess ); - stream << - "Passed " << bothOrAll( totals.testCases.passed ) - << pluralise( totals.testCases.passed, "test case" ) << - " with " << pluralise( totals.assertions.passed, "assertion" ) << "."; - } - } - }; - - INTERNAL_CATCH_REGISTER_REPORTER( "compact", CompactReporter ) - -} // end namespace Catch - -namespace Catch { - NonCopyable::~NonCopyable() {} - IShared::~IShared() {} - StreamBufBase::~StreamBufBase() CATCH_NOEXCEPT {} - IContext::~IContext() {} - IResultCapture::~IResultCapture() {} - ITestCase::~ITestCase() {} - ITestCaseRegistry::~ITestCaseRegistry() {} - IRegistryHub::~IRegistryHub() {} - IMutableRegistryHub::~IMutableRegistryHub() {} - IExceptionTranslator::~IExceptionTranslator() {} - IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() {} - IReporter::~IReporter() {} - IReporterFactory::~IReporterFactory() {} - IReporterRegistry::~IReporterRegistry() {} - IStreamingReporter::~IStreamingReporter() {} - AssertionStats::~AssertionStats() {} - SectionStats::~SectionStats() {} - TestCaseStats::~TestCaseStats() {} - TestGroupStats::~TestGroupStats() {} - TestRunStats::~TestRunStats() {} - CumulativeReporterBase::SectionNode::~SectionNode() {} - CumulativeReporterBase::~CumulativeReporterBase() {} - - StreamingReporterBase::~StreamingReporterBase() {} - ConsoleReporter::~ConsoleReporter() {} - CompactReporter::~CompactReporter() {} - IRunner::~IRunner() {} - IMutableContext::~IMutableContext() {} - IConfig::~IConfig() {} - XmlReporter::~XmlReporter() {} - JunitReporter::~JunitReporter() {} - TestRegistry::~TestRegistry() {} - FreeFunctionTestCase::~FreeFunctionTestCase() {} - IGeneratorInfo::~IGeneratorInfo() {} - IGeneratorsForTest::~IGeneratorsForTest() {} - TestSpec::Pattern::~Pattern() {} - TestSpec::NamePattern::~NamePattern() {} - TestSpec::TagPattern::~TagPattern() {} - TestSpec::ExcludedPattern::~ExcludedPattern() {} - - Matchers::Impl::StdString::Equals::~Equals() {} - Matchers::Impl::StdString::Contains::~Contains() {} - Matchers::Impl::StdString::StartsWith::~StartsWith() {} - Matchers::Impl::StdString::EndsWith::~EndsWith() {} - - void Config::dummy() {} -} - -#ifdef __clang__ -#pragma clang diagnostic pop -#endif - -#endif - -#ifdef CATCH_CONFIG_MAIN -// #included from: internal/catch_default_main.hpp -#define TWOBLUECUBES_CATCH_DEFAULT_MAIN_HPP_INCLUDED - -#ifndef __OBJC__ - -// Standard C/C++ main entry point -int main (int argc, char * const argv[]) { - return Catch::Session().run( argc, argv ); -} - -#else // __OBJC__ - -// Objective-C entry point -int main (int argc, char * const argv[]) { -#if !CATCH_ARC_ENABLED - NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; -#endif - - Catch::registerTestMethods(); - int result = Catch::Session().run( argc, (char* const*)argv ); - -#if !CATCH_ARC_ENABLED - [pool drain]; -#endif - - return result; -} - -#endif // __OBJC__ - -#endif - -#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED -# undef CLARA_CONFIG_MAIN -#endif - -////// - -// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ -#ifdef CATCH_CONFIG_PREFIX_ALL - -#define CATCH_REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE" ) -#define CATCH_REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "CATCH_REQUIRE_FALSE" ) - -#define CATCH_REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS" ) -#define CATCH_REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THROWS_AS" ) -#define CATCH_REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_NOTHROW" ) - -#define CATCH_CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK" ) -#define CATCH_CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CATCH_CHECK_FALSE" ) -#define CATCH_CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_IF" ) -#define CATCH_CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECKED_ELSE" ) -#define CATCH_CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CATCH_CHECK_NOFAIL" ) - -#define CATCH_CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS" ) -#define CATCH_CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THROWS_AS" ) -#define CATCH_CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_NOTHROW" ) - -#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CATCH_CHECK_THAT" ) -#define CATCH_REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "CATCH_REQUIRE_THAT" ) - -#define CATCH_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) -#define CATCH_WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "CATCH_WARN", msg ) -#define CATCH_SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "CATCH_INFO" ) -#define CATCH_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) -#define CATCH_SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CATCH_CAPTURE" ) - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define CATCH_TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) - #define CATCH_TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) - #define CATCH_METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) - #define CATCH_SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) - #define CATCH_FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", __VA_ARGS__ ) - #define CATCH_SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", __VA_ARGS__ ) -#else - #define CATCH_TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) - #define CATCH_TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) - #define CATCH_METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) - #define CATCH_SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) - #define CATCH_FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "CATCH_FAIL", msg ) - #define CATCH_SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "CATCH_SUCCEED", msg ) -#endif -#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) - -#define CATCH_REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) -#define CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) - -#define CATCH_GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) - -// "BDD-style" convenience wrappers -#ifdef CATCH_CONFIG_VARIADIC_MACROS -#define CATCH_SCENARIO( ... ) CATCH_TEST_CASE( "Scenario: " __VA_ARGS__ ) -#define CATCH_SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) -#else -#define CATCH_SCENARIO( name, tags ) CATCH_TEST_CASE( "Scenario: " name, tags ) -#define CATCH_SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) -#endif -#define CATCH_GIVEN( desc ) CATCH_SECTION( "Given: " desc, "" ) -#define CATCH_WHEN( desc ) CATCH_SECTION( " When: " desc, "" ) -#define CATCH_AND_WHEN( desc ) CATCH_SECTION( " And: " desc, "" ) -#define CATCH_THEN( desc ) CATCH_SECTION( " Then: " desc, "" ) -#define CATCH_AND_THEN( desc ) CATCH_SECTION( " And: " desc, "" ) - -// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required -#else - -#define REQUIRE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal, "REQUIRE" ) -#define REQUIRE_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, "REQUIRE_FALSE" ) - -#define REQUIRE_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::Normal, "REQUIRE_THROWS" ) -#define REQUIRE_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::Normal, "REQUIRE_THROWS_AS" ) -#define REQUIRE_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::Normal, "REQUIRE_NOTHROW" ) - -#define CHECK( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK" ) -#define CHECK_FALSE( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, "CHECK_FALSE" ) -#define CHECKED_IF( expr ) INTERNAL_CATCH_IF( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_IF" ) -#define CHECKED_ELSE( expr ) INTERNAL_CATCH_ELSE( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECKED_ELSE" ) -#define CHECK_NOFAIL( expr ) INTERNAL_CATCH_TEST( expr, Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, "CHECK_NOFAIL" ) - -#define CHECK_THROWS( expr ) INTERNAL_CATCH_THROWS( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS" ) -#define CHECK_THROWS_AS( expr, exceptionType ) INTERNAL_CATCH_THROWS_AS( expr, exceptionType, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THROWS_AS" ) -#define CHECK_NOTHROW( expr ) INTERNAL_CATCH_NO_THROW( expr, Catch::ResultDisposition::ContinueOnFailure, "CHECK_NOTHROW" ) - -#define CHECK_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::ContinueOnFailure, "CHECK_THAT" ) -#define REQUIRE_THAT( arg, matcher ) INTERNAL_CHECK_THAT( arg, matcher, Catch::ResultDisposition::Normal, "REQUIRE_THAT" ) - -#define INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) -#define WARN( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, "WARN", msg ) -#define SCOPED_INFO( msg ) INTERNAL_CATCH_INFO( msg, "INFO" ) -#define CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) -#define SCOPED_CAPTURE( msg ) INTERNAL_CATCH_INFO( #msg " := " << msg, "CAPTURE" ) - -#ifdef CATCH_CONFIG_VARIADIC_MACROS - #define TEST_CASE( ... ) INTERNAL_CATCH_TESTCASE( __VA_ARGS__ ) - #define TEST_CASE_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, __VA_ARGS__ ) - #define METHOD_AS_TEST_CASE( method, ... ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, __VA_ARGS__ ) - #define SECTION( ... ) INTERNAL_CATCH_SECTION( __VA_ARGS__ ) - #define FAIL( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", __VA_ARGS__ ) - #define SUCCEED( ... ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", __VA_ARGS__ ) -#else - #define TEST_CASE( name, description ) INTERNAL_CATCH_TESTCASE( name, description ) - #define TEST_CASE_METHOD( className, name, description ) INTERNAL_CATCH_TEST_CASE_METHOD( className, name, description ) - #define METHOD_AS_TEST_CASE( method, name, description ) INTERNAL_CATCH_METHOD_AS_TEST_CASE( method, name, description ) - #define SECTION( name, description ) INTERNAL_CATCH_SECTION( name, description ) - #define FAIL( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, "FAIL", msg ) - #define SUCCEED( msg ) INTERNAL_CATCH_MSG( Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, "SUCCEED", msg ) -#endif -#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE( "", "" ) - -#define REGISTER_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_REPORTER( name, reporterType ) -#define REGISTER_LEGACY_REPORTER( name, reporterType ) INTERNAL_CATCH_REGISTER_LEGACY_REPORTER( name, reporterType ) - -#define GENERATE( expr) INTERNAL_CATCH_GENERATE( expr ) - -#endif - -#define CATCH_TRANSLATE_EXCEPTION( signature ) INTERNAL_CATCH_TRANSLATE_EXCEPTION( signature ) - -// "BDD-style" convenience wrappers -#ifdef CATCH_CONFIG_VARIADIC_MACROS -#define SCENARIO( ... ) TEST_CASE( "Scenario: " __VA_ARGS__ ) -#define SCENARIO_METHOD( className, ... ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " __VA_ARGS__ ) -#else -#define SCENARIO( name, tags ) TEST_CASE( "Scenario: " name, tags ) -#define SCENARIO_METHOD( className, name, tags ) INTERNAL_CATCH_TEST_CASE_METHOD( className, "Scenario: " name, tags ) -#endif -#define GIVEN( desc ) SECTION( " Given: " desc, "" ) -#define WHEN( desc ) SECTION( " When: " desc, "" ) -#define AND_WHEN( desc ) SECTION( "And when: " desc, "" ) -#define THEN( desc ) SECTION( " Then: " desc, "" ) -#define AND_THEN( desc ) SECTION( " And: " desc, "" ) - -using Catch::Detail::Approx; - -// #included from: internal/catch_reenable_warnings.h - -#define TWOBLUECUBES_CATCH_REENABLE_WARNINGS_H_INCLUDED - -#ifdef __clang__ -# ifdef __ICC // icpc defines the __clang__ macro -# pragma warning(pop) -# else -# pragma clang diagnostic pop -# endif -#elif defined __GNUC__ -# pragma GCC diagnostic pop -#endif - -#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED - diff --git a/third_party/immer/tools/include/doctest.h b/third_party/immer/tools/include/doctest.h deleted file mode 100644 index 695c271b59c9..000000000000 --- a/third_party/immer/tools/include/doctest.h +++ /dev/null @@ -1,5696 +0,0 @@ -// ====================================================================== -// == DO NOT MODIFY THIS FILE BY HAND - IT IS AUTO GENERATED BY CMAKE! == -// ====================================================================== -// -// doctest.h - the lightest feature-rich C++ single-header testing framework for unit tests and TDD -// -// Copyright (c) 2016-2017 Viktor Kirilov -// -// Distributed under the MIT Software License -// See accompanying file LICENSE.txt or copy at -// https://opensource.org/licenses/MIT -// -// The documentation can be found at the library's page: -// https://github.com/onqtam/doctest/blob/master/doc/markdown/readme.md -// -// ================================================================================================= -// ================================================================================================= -// ================================================================================================= -// -// The library is heavily influenced by Catch - https://github.com/philsquared/Catch -// which uses the Boost Software License - Version 1.0 -// see here - https://github.com/philsquared/Catch/blob/master/LICENSE_1_0.txt -// -// The concept of subcases (sections in Catch) and expression decomposition are from there. -// Some parts of the code are taken directly: -// - stringification - the detection of "ostream& operator<<(ostream&, const T&)" and StringMaker<> -// - the Approx() helper class for floating point comparison -// - colors in the console -// - breaking into a debugger -// - signal / SEH handling -// - timer -// -// The expression decomposing templates are taken from lest - https://github.com/martinmoene/lest -// which uses the Boost Software License - Version 1.0 -// see here - https://github.com/martinmoene/lest/blob/master/LICENSE_1_0.txt -// -// The type list and the foreach algorithm on it for C++98 are taken from Loki -// - http://loki-lib.sourceforge.net/ -// - https://en.wikipedia.org/wiki/Loki_%28C%2B%2B%29 -// - https://github.com/snaewe/loki-lib -// which uses the MIT Software License -// -// ================================================================================================= -// ================================================================================================= -// ================================================================================================= - -// Suppress this globally (without push/pop) - there is no way to silence it in the -// expression decomposition macros _Pragma() in macros doesn't work for the c++ front-end of g++ -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55578 -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69543 -// Also the warning is completely worthless nowadays - http://stackoverflow.com/questions/14016993 -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic ignored "-Waggregate-return" -#endif - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunknown-pragmas" -#pragma clang diagnostic ignored "-Wnon-virtual-dtor" -#pragma clang diagnostic ignored "-Wweak-vtables" -#pragma clang diagnostic ignored "-Wpadded" -#pragma clang diagnostic ignored "-Wdeprecated" -#pragma clang diagnostic ignored "-Wmissing-prototypes" -#pragma clang diagnostic ignored "-Wunused-local-typedef" -#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" -#pragma clang diagnostic ignored "-Wc++11-long-long" -#endif // __clang__ - -#if defined(__GNUC__) && !defined(__clang__) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) -#pragma GCC diagnostic push -#endif // > gcc 4.6 -#pragma GCC diagnostic ignored "-Wunknown-pragmas" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wstrict-overflow" -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#pragma GCC diagnostic ignored "-Wctor-dtor-privacy" -#pragma GCC diagnostic ignored "-Wmissing-declarations" -#pragma GCC diagnostic ignored "-Wnon-virtual-dtor" -#pragma GCC diagnostic ignored "-Winline" -#pragma GCC diagnostic ignored "-Wlong-long" -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#endif // > gcc 4.6 -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 7) -#pragma GCC diagnostic ignored "-Wunused-local-typedefs" -#endif // > gcc 4.7 -#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 3) -#pragma GCC diagnostic ignored "-Wuseless-cast" -#endif // > gcc 5.3 -#endif // __GNUC__ - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4996) // The compiler encountered a deprecated declaration -#pragma warning(disable : 4706) // assignment within conditional expression -#pragma warning(disable : 4512) // 'class' : assignment operator could not be generated -#pragma warning(disable : 4127) // conditional expression is constant -#endif // _MSC_VER - -#ifndef DOCTEST_LIBRARY_INCLUDED -#define DOCTEST_LIBRARY_INCLUDED - -#define DOCTEST_VERSION_MAJOR 1 -#define DOCTEST_VERSION_MINOR 2 -#define DOCTEST_VERSION_PATCH 1 -#define DOCTEST_VERSION_STR "1.2.1" - -#define DOCTEST_VERSION \ - (DOCTEST_VERSION_MAJOR * 10000 + DOCTEST_VERSION_MINOR * 100 + DOCTEST_VERSION_PATCH) - -// ================================================================================================= -// == FEATURE DETECTION ============================================================================ -// ================================================================================================= - -#if __cplusplus >= 201103L -#ifndef DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS -#define DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS -#endif // DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS -#ifndef DOCTEST_CONFIG_WITH_RVALUE_REFERENCES -#define DOCTEST_CONFIG_WITH_RVALUE_REFERENCES -#endif // DOCTEST_CONFIG_WITH_RVALUE_REFERENCES -#ifndef DOCTEST_CONFIG_WITH_NULLPTR -#define DOCTEST_CONFIG_WITH_NULLPTR -#endif // DOCTEST_CONFIG_WITH_NULLPTR -#ifndef DOCTEST_CONFIG_WITH_LONG_LONG -#define DOCTEST_CONFIG_WITH_LONG_LONG -#endif // DOCTEST_CONFIG_WITH_LONG_LONG -#ifndef DOCTEST_CONFIG_WITH_STATIC_ASSERT -#define DOCTEST_CONFIG_WITH_STATIC_ASSERT -#endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT -#ifndef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#endif // __cplusplus >= 201103L - -#ifndef __has_feature -#define __has_feature(x) 0 -#endif // __has_feature - -// MSVC C++11 feature support table: https://msdn.microsoft.com/en-us/library/hh567368.aspx -// GCC C++11 feature support table: https://gcc.gnu.org/projects/cxx-status.html -// MSVC version table: -// MSVC++ 15.0 _MSC_VER == 1910 (Visual Studio 2017) -// MSVC++ 14.0 _MSC_VER == 1900 (Visual Studio 2015) -// MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013) -// MSVC++ 11.0 _MSC_VER == 1700 (Visual Studio 2012) -// MSVC++ 10.0 _MSC_VER == 1600 (Visual Studio 2010) -// MSVC++ 9.0 _MSC_VER == 1500 (Visual Studio 2008) -// MSVC++ 8.0 _MSC_VER == 1400 (Visual Studio 2005) - -// deleted functions - -#ifndef DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS -#if defined(_MSC_VER) && (_MSC_VER >= 1800) -#define DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS -#endif // _MSC_VER -#if defined(__clang__) && __has_feature(cxx_deleted_functions) -#define DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS -#endif // __clang__ -#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 4) || __GNUC__ > 4) && \ - defined(__GXX_EXPERIMENTAL_CXX0X__) -#define DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS -#endif // __GNUC__ -#endif // DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS - -#if defined(DOCTEST_CONFIG_NO_DELETED_FUNCTIONS) && defined(DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS) -#undef DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS -#endif // DOCTEST_CONFIG_NO_DELETED_FUNCTIONS - -// rvalue references - -#ifndef DOCTEST_CONFIG_WITH_RVALUE_REFERENCES -#if defined(_MSC_VER) && (_MSC_VER >= 1600) -#define DOCTEST_CONFIG_WITH_RVALUE_REFERENCES -#endif // _MSC_VER -#if defined(__clang__) && __has_feature(cxx_rvalue_references) -#define DOCTEST_CONFIG_WITH_RVALUE_REFERENCES -#endif // __clang__ -#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4) && \ - defined(__GXX_EXPERIMENTAL_CXX0X__) -#define DOCTEST_CONFIG_WITH_RVALUE_REFERENCES -#endif // __GNUC__ -#endif // DOCTEST_CONFIG_WITH_RVALUE_REFERENCES - -#if defined(DOCTEST_CONFIG_NO_RVALUE_REFERENCES) && defined(DOCTEST_CONFIG_WITH_RVALUE_REFERENCES) -#undef DOCTEST_CONFIG_WITH_RVALUE_REFERENCES -#endif // DOCTEST_CONFIG_NO_RVALUE_REFERENCES - -// nullptr - -#ifndef DOCTEST_CONFIG_WITH_NULLPTR -#if defined(__clang__) && __has_feature(cxx_nullptr) -#define DOCTEST_CONFIG_WITH_NULLPTR -#endif // __clang__ -#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) && \ - defined(__GXX_EXPERIMENTAL_CXX0X__) -#define DOCTEST_CONFIG_WITH_NULLPTR -#endif // __GNUC__ -#if defined(_MSC_VER) && (_MSC_VER >= 1600) // MSVC 2010 -#define DOCTEST_CONFIG_WITH_NULLPTR -#endif // _MSC_VER -#endif // DOCTEST_CONFIG_WITH_NULLPTR - -#if defined(DOCTEST_CONFIG_NO_NULLPTR) && defined(DOCTEST_CONFIG_WITH_NULLPTR) -#undef DOCTEST_CONFIG_WITH_NULLPTR -#endif // DOCTEST_CONFIG_NO_NULLPTR - -// variadic macros - -#ifndef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#if defined(_MSC_VER) && _MSC_VER > 1400 && !defined(__EDGE__) -#define DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#endif // _MSC_VER -#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || __GNUC__ > 4) && \ - defined(__GXX_EXPERIMENTAL_CXX0X__) -#define DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#endif // __GNUC__ and clang -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#if defined(DOCTEST_CONFIG_NO_VARIADIC_MACROS) && defined(DOCTEST_CONFIG_WITH_VARIADIC_MACROS) -#undef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#endif // DOCTEST_CONFIG_NO_VARIADIC_MACROS - -// long long - -#ifndef DOCTEST_CONFIG_WITH_LONG_LONG -#if defined(_MSC_VER) && (_MSC_VER >= 1400) -#define DOCTEST_CONFIG_WITH_LONG_LONG -#endif // _MSC_VER -#if(defined(__clang__) || \ - (defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 5) || __GNUC__ > 4))) && \ - defined(__GXX_EXPERIMENTAL_CXX0X__) -#define DOCTEST_CONFIG_WITH_LONG_LONG -#endif // __GNUC__ and clang -#endif // DOCTEST_CONFIG_WITH_LONG_LONG - -#if defined(DOCTEST_CONFIG_NO_LONG_LONG) && defined(DOCTEST_CONFIG_WITH_LONG_LONG) -#undef DOCTEST_CONFIG_WITH_LONG_LONG -#endif // DOCTEST_CONFIG_NO_LONG_LONG - -// static_assert - -#ifndef DOCTEST_CONFIG_WITH_STATIC_ASSERT -#if defined(__clang__) && __has_feature(cxx_static_assert) -#define DOCTEST_CONFIG_WITH_STATIC_ASSERT -#endif // __clang__ -#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4) && \ - defined(__GXX_EXPERIMENTAL_CXX0X__) -#define DOCTEST_CONFIG_WITH_STATIC_ASSERT -#endif // __GNUC__ -#if defined(_MSC_VER) && (_MSC_VER >= 1600) // MSVC 2010 -#define DOCTEST_CONFIG_WITH_STATIC_ASSERT -#endif // _MSC_VER -#endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT - -#if defined(DOCTEST_CONFIG_NO_STATIC_ASSERT) && defined(DOCTEST_CONFIG_WITH_STATIC_ASSERT) -#undef DOCTEST_CONFIG_WITH_STATIC_ASSERT -#endif // DOCTEST_CONFIG_NO_STATIC_ASSERT - -// other stuff... - -#if defined(DOCTEST_CONFIG_WITH_RVALUE_REFERENCES) || defined(DOCTEST_CONFIG_WITH_LONG_LONG) || \ - defined(DOCTEST_CONFIG_WITH_DELETED_FUNCTIONS) || defined(DOCTEST_CONFIG_WITH_NULLPTR) || \ - defined(DOCTEST_CONFIG_WITH_VARIADIC_MACROS) || defined(DOCTEST_CONFIG_WITH_STATIC_ASSERT) -#define DOCTEST_NO_CPP11_COMPAT -#endif // c++11 stuff - -#if defined(__clang__) && defined(DOCTEST_NO_CPP11_COMPAT) -#pragma clang diagnostic ignored "-Wc++98-compat" -#pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif // __clang__ && DOCTEST_NO_CPP11_COMPAT - -#if defined(_MSC_VER) && !defined(DOCTEST_CONFIG_WINDOWS_SEH) -#define DOCTEST_CONFIG_WINDOWS_SEH -#endif // _MSC_VER -#if defined(DOCTEST_CONFIG_NO_WINDOWS_SEH) && defined(DOCTEST_CONFIG_WINDOWS_SEH) -#undef DOCTEST_CONFIG_WINDOWS_SEH -#endif // DOCTEST_CONFIG_NO_WINDOWS_SEH - -#if !defined(_WIN32) && !defined(__QNX__) && !defined(DOCTEST_CONFIG_POSIX_SIGNALS) -#define DOCTEST_CONFIG_POSIX_SIGNALS -#endif // _WIN32 -#if defined(DOCTEST_CONFIG_NO_POSIX_SIGNALS) && defined(DOCTEST_CONFIG_POSIX_SIGNALS) -#undef DOCTEST_CONFIG_POSIX_SIGNALS -#endif // DOCTEST_CONFIG_NO_POSIX_SIGNALS - -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -#if defined(__GNUC__) && !defined(__EXCEPTIONS) -#define DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // clang and gcc -// in MSVC _HAS_EXCEPTIONS is defined in a header instead of as a project define -// so we can't do the automatic detection for MSVC without including some header -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS -#define DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#if defined(DOCTEST_CONFIG_NO_EXCEPTIONS) && !defined(DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS) -#define DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS && !DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS - -#if defined(DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN) && !defined(DOCTEST_CONFIG_IMPLEMENT) -#define DOCTEST_CONFIG_IMPLEMENT -#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - -#if defined _WIN32 || defined __CYGWIN__ -#ifdef __GNUC__ -#define DOCTEST_SYMBOL_EXPORT __attribute__((dllexport)) -#define DOCTEST_SYMBOL_IMPORT __attribute__((dllimport)) -#else // __GNUC__ -#define DOCTEST_SYMBOL_EXPORT __declspec(dllexport) -#define DOCTEST_SYMBOL_IMPORT __declspec(dllimport) -#endif // __GNUC__ -#else // _WIN32 -#define DOCTEST_SYMBOL_EXPORT __attribute__((visibility("default"))) -#define DOCTEST_SYMBOL_IMPORT -#endif // _WIN32 - -#ifdef DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL -#ifdef DOCTEST_CONFIG_IMPLEMENT -#define DOCTEST_INTERFACE DOCTEST_SYMBOL_EXPORT -#else // DOCTEST_CONFIG_IMPLEMENT -#define DOCTEST_INTERFACE DOCTEST_SYMBOL_IMPORT -#endif // DOCTEST_CONFIG_IMPLEMENT -#else // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL -#define DOCTEST_INTERFACE -#endif // DOCTEST_CONFIG_IMPLEMENTATION_IN_DLL - -#ifdef _MSC_VER -#define DOCTEST_NOINLINE __declspec(noinline) -#else // _MSC_VER -#define DOCTEST_NOINLINE __attribute__((noinline)) -#endif // _MSC_VER - -#ifndef DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK -#define DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK 5 -#endif // DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK - -// ================================================================================================= -// == FEATURE DETECTION END ======================================================================== -// ================================================================================================= - -// internal macros for string concatenation and anonymous variable name generation -#define DOCTEST_CAT_IMPL(s1, s2) s1##s2 -#define DOCTEST_CAT(s1, s2) DOCTEST_CAT_IMPL(s1, s2) -#ifdef __COUNTER__ // not standard and may be missing for some compilers -#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __COUNTER__) -#else // __COUNTER__ -#define DOCTEST_ANONYMOUS(x) DOCTEST_CAT(x, __LINE__) -#endif // __COUNTER__ - -// macro for making a string out of an identifier -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TOSTR_IMPL(...) #__VA_ARGS__ -#define DOCTEST_TOSTR(...) DOCTEST_TOSTR_IMPL(__VA_ARGS__) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TOSTR_IMPL(x) #x -#define DOCTEST_TOSTR(x) DOCTEST_TOSTR_IMPL(x) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -// for concatenating literals and making the result a string -#define DOCTEST_STR_CONCAT_TOSTR(s1, s2) DOCTEST_TOSTR(s1) DOCTEST_TOSTR(s2) - -// counts the number of elements in a C string -#define DOCTEST_COUNTOF(x) (sizeof(x) / sizeof(x[0])) - -#ifndef DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE -#define DOCTEST_REF_WRAP(x) x& -#else // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE -#define DOCTEST_REF_WRAP(x) x -#endif // DOCTEST_CONFIG_ASSERTION_PARAMETERS_BY_VALUE - -// not using __APPLE__ because... this is how Catch does it -#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) -#define DOCTEST_PLATFORM_MAC -#elif defined(__IPHONE_OS_VERSION_MIN_REQUIRED) -#define DOCTEST_PLATFORM_IPHONE -#elif defined(_WIN32) || defined(_MSC_VER) -#define DOCTEST_PLATFORM_WINDOWS -#else -#define DOCTEST_PLATFORM_LINUX -#endif - -#if defined(__clang__) -#define DOCTEST_GLOBAL_NO_WARNINGS(var) \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") static int var -#define DOCTEST_GLOBAL_NO_WARNINGS_END() _Pragma("clang diagnostic pop") -#elif defined(__GNUC__) -#define DOCTEST_GLOBAL_NO_WARNINGS(var) static int var __attribute__((unused)) -#define DOCTEST_GLOBAL_NO_WARNINGS_END() -#else // MSVC / other -#define DOCTEST_GLOBAL_NO_WARNINGS(var) static int var -#define DOCTEST_GLOBAL_NO_WARNINGS_END() -#endif // MSVC / other - -// should probably take a look at https://github.com/scottt/debugbreak -#ifdef DOCTEST_PLATFORM_MAC -#define DOCTEST_BREAK_INTO_DEBUGGER() __asm__("int $3\n" : :) -#elif defined(_MSC_VER) -#define DOCTEST_BREAK_INTO_DEBUGGER() __debugbreak() -#elif defined(__MINGW32__) -extern "C" __declspec(dllimport) void __stdcall DebugBreak(); -#define DOCTEST_BREAK_INTO_DEBUGGER() ::DebugBreak() -#else // linux -#define DOCTEST_BREAK_INTO_DEBUGGER() ((void)0) -#endif // linux - -#ifdef __clang__ -// to detect if libc++ is being used with clang (the _LIBCPP_VERSION identifier) -#include <ciso646> -#endif // __clang__ - -#ifdef _LIBCPP_VERSION -// not forward declaring ostream for libc++ because I had some problems (inline namespaces vs c++98) -// so the <iosfwd> header is used - also it is very light and doesn't drag a ton of stuff -#include <iosfwd> -#else // _LIBCPP_VERSION -#ifndef DOCTEST_CONFIG_USE_IOSFWD -namespace std -{ -template <class charT> -struct char_traits; -template <> -struct char_traits<char>; -template <class charT, class traits> -class basic_ostream; -typedef basic_ostream<char, char_traits<char> > ostream; -} // namespace std -#else // DOCTEST_CONFIG_USE_IOSFWD -#include <iosfwd> -#endif // DOCTEST_CONFIG_USE_IOSFWD -#endif // _LIBCPP_VERSION - -// static assert macro - because of the c++98 support requires that the message is an -// identifier (no spaces and not a C string) - example without quotes: I_am_a_message -// taken from here: http://stackoverflow.com/a/1980156/3162383 -#ifdef DOCTEST_CONFIG_WITH_STATIC_ASSERT -#define DOCTEST_STATIC_ASSERT(expression, message) static_assert(expression, #message) -#else // DOCTEST_CONFIG_WITH_STATIC_ASSERT -#define DOCTEST_STATIC_ASSERT(expression, message) \ - struct DOCTEST_CAT(__static_assertion_at_line_, __LINE__) \ - { \ - doctest::detail::static_assert_impl::StaticAssertion<static_cast<bool>((expression))> \ - DOCTEST_CAT(DOCTEST_CAT(DOCTEST_CAT(STATIC_ASSERTION_FAILED_AT_LINE_, __LINE__), \ - _), \ - message); \ - }; \ - typedef doctest::detail::static_assert_impl::StaticAssertionTest<static_cast<int>( \ - sizeof(DOCTEST_CAT(__static_assertion_at_line_, __LINE__)))> \ - DOCTEST_CAT(__static_assertion_test_at_line_, __LINE__) -#endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT - -#ifdef DOCTEST_CONFIG_WITH_NULLPTR -#ifdef _LIBCPP_VERSION -#include <cstddef> -#else // _LIBCPP_VERSION -namespace std -{ typedef decltype(nullptr) nullptr_t; } -#endif // _LIBCPP_VERSION -#endif // DOCTEST_CONFIG_WITH_NULLPTR - -#ifndef DOCTEST_CONFIG_DISABLE -namespace doctest -{ -namespace detail -{ - struct TestSuite - { - const char* m_test_suite; - const char* m_description; - bool m_skip; - bool m_may_fail; - bool m_should_fail; - int m_expected_failures; - double m_timeout; - - TestSuite& operator*(const char* in) { - m_test_suite = in; - // clear state - m_description = 0; - m_skip = false; - m_may_fail = false; - m_should_fail = false; - m_expected_failures = 0; - m_timeout = 0; - return *this; - } - - template <typename T> - TestSuite& operator*(const T& in) { - in.fill(*this); - return *this; - } - }; -} // namespace detail -} // namespace doctest - -// in a separate namespace outside of doctest because the DOCTEST_TEST_SUITE macro -// introduces an anonymous namespace in which getCurrentTestSuite gets overridden -namespace doctest_detail_test_suite_ns -{ -DOCTEST_INTERFACE doctest::detail::TestSuite& getCurrentTestSuite(); -} // namespace doctest_detail_test_suite_ns - -#endif // DOCTEST_CONFIG_DISABLE - -namespace doctest -{ -// A 24 byte string class (can be as small as 17 for x64 and 13 for x86) that can hold strings with length -// of up to 23 chars on the stack before going on the heap - the last byte of the buffer is used for: -// - "is small" bit - the highest bit - if "0" then it is small - otherwise its "1" (128) -// - if small - capacity left before going on the heap - using the lowest 5 bits -// - if small - 2 bits are left unused - the second and third highest ones -// - if small - acts as a null terminator if strlen() is 23 (24 including the null terminator) -// and the "is small" bit remains "0" ("as well as the capacity left") so its OK -// Idea taken from this lecture about the string implementation of facebook/folly - fbstring -// https://www.youtube.com/watch?v=kPR8h4-qZdk -// TODO: -// - optimizations - like not deleting memory unnecessarily in operator= and etc. -// - resize/reserve/clear -// - substr -// - replace -// - back/front -// - iterator stuff -// - find & friends -// - push_back/pop_back -// - assign/insert/erase -// - relational operators as free functions - taking const char* as one of the params -class DOCTEST_INTERFACE String -{ - static const unsigned len = 24; //!OCLINT avoid private static members - static const unsigned last = len - 1; //!OCLINT avoid private static members - - struct view // len should be more than sizeof(view) - because of the final byte for flags - { - char* ptr; - unsigned size; - unsigned capacity; - }; - - union - { - char buf[len]; - view data; - }; - - void copy(const String& other); - - void setOnHeap() { *reinterpret_cast<unsigned char*>(&buf[last]) = 128; } - void setLast(unsigned in = last) { buf[last] = char(in); } - -public: - String() { - buf[0] = '\0'; - setLast(); - } - - String(const char* in); - - String(const String& other) { copy(other); } - - ~String() { - if(!isOnStack()) - delete[] data.ptr; - } - - // GCC 4.9/5/6 report Wstrict-overflow when optimizations are ON and it got inlined in the vector class somewhere... - // see commit 574ef95f0cd379118be5011704664e4b5351f1e0 and build https://travis-ci.org/onqtam/doctest/builds/230671611 - DOCTEST_NOINLINE String& operator=(const String& other) { - if(!isOnStack()) - delete[] data.ptr; - - copy(other); - - return *this; - } - String& operator+=(const String& other); - - String operator+(const String& other) const { return String(*this) += other; } - -#ifdef DOCTEST_CONFIG_WITH_RVALUE_REFERENCES - String(String&& other); - String& operator=(String&& other); -#endif // DOCTEST_CONFIG_WITH_RVALUE_REFERENCES - - bool isOnStack() const { return (buf[last] & 128) == 0; } - - char operator[](unsigned i) const { return const_cast<String*>(this)->operator[](i); } // NOLINT - char& operator[](unsigned i) { - if(isOnStack()) - return reinterpret_cast<char*>(buf)[i]; - return data.ptr[i]; - } - - const char* c_str() const { return const_cast<String*>(this)->c_str(); } // NOLINT - char* c_str() { - if(isOnStack()) - return reinterpret_cast<char*>(buf); - return data.ptr; - } - - unsigned size() const { - if(isOnStack()) - return last - (unsigned(buf[last]) & 31); // using "last" would work only if "len" is 32 - return data.size; - } - - unsigned capacity() const { - if(isOnStack()) - return len; - return data.capacity; - } - - int compare(const char* other, bool no_case = false) const; - int compare(const String& other, bool no_case = false) const; -}; - -// clang-format off -inline bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; } -inline bool operator!=(const String& lhs, const String& rhs) { return lhs.compare(rhs) != 0; } -inline bool operator< (const String& lhs, const String& rhs) { return lhs.compare(rhs) < 0; } -inline bool operator> (const String& lhs, const String& rhs) { return lhs.compare(rhs) > 0; } -inline bool operator<=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) < 0 : true; } -inline bool operator>=(const String& lhs, const String& rhs) { return (lhs != rhs) ? lhs.compare(rhs) > 0 : true; } -// clang-format on - -DOCTEST_INTERFACE std::ostream& operator<<(std::ostream& stream, const String& in); - -namespace detail -{ -#ifndef DOCTEST_CONFIG_WITH_STATIC_ASSERT - namespace static_assert_impl - { - template <bool> - struct StaticAssertion; - - template <> - struct StaticAssertion<true> - {}; - - template <int i> - struct StaticAssertionTest - {}; - } // namespace static_assert_impl -#endif // DOCTEST_CONFIG_WITH_STATIC_ASSERT - - namespace traits - { - template <typename T> - struct remove_const - { typedef T type; }; - - template <typename T> - struct remove_const<const T> - { typedef T type; }; - - template <typename T> - struct remove_volatile - { typedef T type; }; - - template <typename T> - struct remove_volatile<volatile T> - { typedef T type; }; - - template <typename T> - struct remove_cv - { typedef typename remove_volatile<typename remove_const<T>::type>::type type; }; - - template <typename T> - struct is_pointer_helper - { static const bool value = false; }; - - template <typename T> - struct is_pointer_helper<T*> - // cppcheck-suppress unusedStructMember - { static const bool value = true; }; - - template <typename T> - struct is_pointer - // cppcheck-suppress unusedStructMember - { static const bool value = is_pointer_helper<typename remove_cv<T>::type>::value; }; - - template <bool CONDITION, typename TYPE = void> - struct enable_if - {}; - - template <typename TYPE> - struct enable_if<true, TYPE> - { typedef TYPE type; }; - - template <typename T> - struct remove_reference - { typedef T type; }; - - template <typename T> - struct remove_reference<T&> - { typedef T type; }; - - template <typename T, typename AT_1 = void> - class is_constructible_impl - { - private: - template <typename C_T, typename C_AT_1> - static bool test(typename enable_if< //!OCLINT avoid private static members - sizeof(C_T) == - sizeof(C_T(static_cast<C_AT_1>( - *static_cast<typename remove_reference<C_AT_1>::type*>( - 0))))>::type*); - - template <typename, typename> - static int test(...); //!OCLINT avoid private static members - - public: - static const bool value = sizeof(test<T, AT_1>(0)) == sizeof(bool); - }; - - template <typename T> - class is_constructible_impl<T, void> - { - private: - template <typename C_T> - static C_T testFun(C_T); //!OCLINT avoid private static members - - template <typename C_T> - static bool test(typename enable_if< //!OCLINT avoid private static members - sizeof(C_T) == sizeof(testFun(C_T()))>::type*); - - template <typename> - static int test(...); //!OCLINT avoid private static members - - public: - static const bool value = sizeof(test<T>(0)) == sizeof(bool); - }; - -// is_constructible<> taken from here: http://stackoverflow.com/a/40443701/3162383 -// for GCC/Clang gives the same results as std::is_constructible<> - see here: https://wandbox.org/permlink/bNWr7Ii2fuz4Vf7A -// modifications: -// - reworked to support only 1 argument (mainly because of MSVC...) -// - removed pointer support -// MSVC support: -// - for versions before 2012 read the CAUTION comment below -// currently intended for use only in the Approx() helper for strong typedefs of double - see issue #62 -#ifndef _MSC_VER - template <typename T, typename AT_1 = void> - class is_constructible - { - public: - static const bool value = is_pointer<typename remove_reference<T>::type>::value ? - false : - is_constructible_impl<T, AT_1>::value; - }; -#elif defined(_MSC_VER) && (_MSC_VER >= 1700) - template <typename T, typename AT_1> - struct is_constructible - { static const bool value = __is_constructible(T, AT_1); }; -#elif defined(_MSC_VER) - // !!! USE WITH CAUTION !!! - // will always return false - unable to implement this for versions of MSVC older than 2012 for now... - template <typename T, typename AT_1> - struct is_constructible - { static const bool value = false; }; -#endif // _MSC_VER - } // namespace traits - - template <typename T> - struct deferred_false - // cppcheck-suppress unusedStructMember - { static const bool value = false; }; - - // to silence the warning "-Wzero-as-null-pointer-constant" only for gcc 5 for the Approx template ctor - pragmas don't work for it... - inline void* getNull() { return 0; } - - namespace has_insertion_operator_impl - { - typedef char no; - typedef char yes[2]; - - struct any_t - { - template <typename T> - // cppcheck-suppress noExplicitConstructor - any_t(const DOCTEST_REF_WRAP(T)); - }; - - yes& testStreamable(std::ostream&); - no testStreamable(no); - - no operator<<(const std::ostream&, const any_t&); - - template <typename T> - struct has_insertion_operator - { - static std::ostream& s; - static const DOCTEST_REF_WRAP(T) t; - static const bool value = sizeof(testStreamable(s << t)) == sizeof(yes); - }; - } // namespace has_insertion_operator_impl - - template <typename T> - struct has_insertion_operator : has_insertion_operator_impl::has_insertion_operator<T> - {}; - - DOCTEST_INTERFACE void my_memcpy(void* dest, const void* src, unsigned num); - DOCTEST_INTERFACE unsigned my_strlen(const char* in); - - DOCTEST_INTERFACE std::ostream* createStream(); - DOCTEST_INTERFACE String getStreamResult(std::ostream*); - DOCTEST_INTERFACE void freeStream(std::ostream*); - - template <bool C> - struct StringMakerBase - { - template <typename T> - static String convert(const DOCTEST_REF_WRAP(T)) { - return "{?}"; - } - }; - - template <> - struct StringMakerBase<true> - { - template <typename T> - static String convert(const DOCTEST_REF_WRAP(T) in) { - std::ostream* stream = createStream(); - *stream << in; - String result = getStreamResult(stream); - freeStream(stream); - return result; - } - }; - - DOCTEST_INTERFACE String rawMemoryToString(const void* object, unsigned size); - - template <typename T> - String rawMemoryToString(const DOCTEST_REF_WRAP(T) object) { - return rawMemoryToString(&object, sizeof(object)); - } - - class NullType - {}; - - template <class T, class U> - struct Typelist - { - typedef T Head; - typedef U Tail; - }; - - // type of recursive function - template <class TList, class Callable> - struct ForEachType; - - // Recursion rule - template <class Head, class Tail, class Callable> - struct ForEachType<Typelist<Head, Tail>, Callable> : public ForEachType<Tail, Callable> - { - enum - { - value = 1 + ForEachType<Tail, Callable>::value - }; - - explicit ForEachType(Callable& callable) - : ForEachType<Tail, Callable>(callable) { -#if defined(_MSC_VER) && _MSC_VER <= 1900 - callable.operator()<value, Head>(); -#else // _MSC_VER - callable.template operator()<value, Head>(); -#endif // _MSC_VER - } - }; - - // Recursion end - template <class Head, class Callable> - struct ForEachType<Typelist<Head, NullType>, Callable> - { - public: - enum - { - value = 0 - }; - - explicit ForEachType(Callable& callable) { -#if defined(_MSC_VER) && _MSC_VER <= 1900 - callable.operator()<value, Head>(); -#else // _MSC_VER - callable.template operator()<value, Head>(); -#endif // _MSC_VER - } - }; - - template <typename T> - const char* type_to_string() { - return "<>"; - } -} // namespace detail - -template <typename T1 = detail::NullType, typename T2 = detail::NullType, - typename T3 = detail::NullType, typename T4 = detail::NullType, - typename T5 = detail::NullType, typename T6 = detail::NullType, - typename T7 = detail::NullType, typename T8 = detail::NullType, - typename T9 = detail::NullType, typename T10 = detail::NullType, - typename T11 = detail::NullType, typename T12 = detail::NullType, - typename T13 = detail::NullType, typename T14 = detail::NullType, - typename T15 = detail::NullType, typename T16 = detail::NullType, - typename T17 = detail::NullType, typename T18 = detail::NullType, - typename T19 = detail::NullType, typename T20 = detail::NullType, - typename T21 = detail::NullType, typename T22 = detail::NullType, - typename T23 = detail::NullType, typename T24 = detail::NullType, - typename T25 = detail::NullType, typename T26 = detail::NullType, - typename T27 = detail::NullType, typename T28 = detail::NullType, - typename T29 = detail::NullType, typename T30 = detail::NullType, - typename T31 = detail::NullType, typename T32 = detail::NullType, - typename T33 = detail::NullType, typename T34 = detail::NullType, - typename T35 = detail::NullType, typename T36 = detail::NullType, - typename T37 = detail::NullType, typename T38 = detail::NullType, - typename T39 = detail::NullType, typename T40 = detail::NullType, - typename T41 = detail::NullType, typename T42 = detail::NullType, - typename T43 = detail::NullType, typename T44 = detail::NullType, - typename T45 = detail::NullType, typename T46 = detail::NullType, - typename T47 = detail::NullType, typename T48 = detail::NullType, - typename T49 = detail::NullType, typename T50 = detail::NullType, - typename T51 = detail::NullType, typename T52 = detail::NullType, - typename T53 = detail::NullType, typename T54 = detail::NullType, - typename T55 = detail::NullType, typename T56 = detail::NullType, - typename T57 = detail::NullType, typename T58 = detail::NullType, - typename T59 = detail::NullType, typename T60 = detail::NullType> -struct Types -{ -private: - typedef typename Types<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, - T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, T31, - T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, - T46, T47, T48, T49, T50, T51, T52, T53, T54, T55, T56, T57, T58, T59, - T60>::Result TailResult; - -public: - typedef detail::Typelist<T1, TailResult> Result; -}; - -template <> -struct Types<> -{ typedef detail::NullType Result; }; - -template <typename T> -struct StringMaker : detail::StringMakerBase<detail::has_insertion_operator<T>::value> -{}; - -template <typename T> -struct StringMaker<T*> -{ - template <typename U> - static String convert(U* p) { - if(p) - return detail::rawMemoryToString(p); - return "NULL"; - } -}; - -template <typename R, typename C> -struct StringMaker<R C::*> -{ - static String convert(R C::*p) { - if(p) - return detail::rawMemoryToString(p); - return "NULL"; - } -}; - -template <typename T> -String toString(const DOCTEST_REF_WRAP(T) value) { - return StringMaker<T>::convert(value); -} - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -DOCTEST_INTERFACE String toString(char* in); -DOCTEST_INTERFACE String toString(const char* in); -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -DOCTEST_INTERFACE String toString(bool in); -DOCTEST_INTERFACE String toString(float in); -DOCTEST_INTERFACE String toString(double in); -DOCTEST_INTERFACE String toString(double long in); - -DOCTEST_INTERFACE String toString(char in); -DOCTEST_INTERFACE String toString(char signed in); -DOCTEST_INTERFACE String toString(char unsigned in); -DOCTEST_INTERFACE String toString(int short in); -DOCTEST_INTERFACE String toString(int short unsigned in); -DOCTEST_INTERFACE String toString(int in); -DOCTEST_INTERFACE String toString(int unsigned in); -DOCTEST_INTERFACE String toString(int long in); -DOCTEST_INTERFACE String toString(int long unsigned in); - -#ifdef DOCTEST_CONFIG_WITH_LONG_LONG -DOCTEST_INTERFACE String toString(int long long in); -DOCTEST_INTERFACE String toString(int long long unsigned in); -#endif // DOCTEST_CONFIG_WITH_LONG_LONG - -#ifdef DOCTEST_CONFIG_WITH_NULLPTR -DOCTEST_INTERFACE String toString(std::nullptr_t in); -#endif // DOCTEST_CONFIG_WITH_NULLPTR - -class DOCTEST_INTERFACE Approx -{ -public: - explicit Approx(double value); - - Approx operator()(double value) const { - Approx approx(value); - approx.epsilon(m_epsilon); - approx.scale(m_scale); - return approx; - } - - template <typename T> - explicit Approx(const T& value, - typename detail::traits::enable_if< - detail::traits::is_constructible<double, T>::value>::type* = - static_cast<T*>(detail::getNull())) { - *this = Approx(static_cast<double>(value)); - } - - // clang-format off - // overloads for double - the first one is necessary as it is in the implementation part of doctest - // as for the others - keeping them for potentially faster compile times - DOCTEST_INTERFACE friend bool operator==(double lhs, Approx const& rhs); - friend bool operator==(Approx const& lhs, double rhs) { return operator==(rhs, lhs); } - friend bool operator!=(double lhs, Approx const& rhs) { return !operator==(lhs, rhs); } - friend bool operator!=(Approx const& lhs, double rhs) { return !operator==(rhs, lhs); } - friend bool operator<=(double lhs, Approx const& rhs) { return lhs < rhs.m_value || lhs == rhs; } - friend bool operator<=(Approx const& lhs, double rhs) { return lhs.m_value < rhs || lhs == rhs; } - friend bool operator>=(double lhs, Approx const& rhs) { return lhs > rhs.m_value || lhs == rhs; } - friend bool operator>=(Approx const& lhs, double rhs) { return lhs.m_value > rhs || lhs == rhs; } - friend bool operator< (double lhs, Approx const& rhs) { return lhs < rhs.m_value && lhs != rhs; } - friend bool operator< (Approx const& lhs, double rhs) { return lhs.m_value < rhs && lhs != rhs; } - friend bool operator> (double lhs, Approx const& rhs) { return lhs > rhs.m_value && lhs != rhs; } - friend bool operator> (Approx const& lhs, double rhs) { return lhs.m_value > rhs && lhs != rhs; } - -#define DOCTEST_APPROX_PREFIX \ - template <typename T> friend typename detail::traits::enable_if<detail::traits::is_constructible<double, T>::value, bool>::type - - DOCTEST_APPROX_PREFIX operator==(const T& lhs, const Approx& rhs) { return operator==(double(lhs), rhs); } - DOCTEST_APPROX_PREFIX operator==(const Approx& lhs, const T& rhs) { return operator==(rhs, lhs); } - DOCTEST_APPROX_PREFIX operator!=(const T& lhs, const Approx& rhs) { return !operator==(lhs, rhs); } - DOCTEST_APPROX_PREFIX operator!=(const Approx& lhs, const T& rhs) { return !operator==(rhs, lhs); } - DOCTEST_APPROX_PREFIX operator<=(const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator<=(const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator>=(const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator>=(const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) || lhs == rhs; } - DOCTEST_APPROX_PREFIX operator< (const T& lhs, const Approx& rhs) { return double(lhs) < rhs.m_value && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator< (const Approx& lhs, const T& rhs) { return lhs.m_value < double(rhs) && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator> (const T& lhs, const Approx& rhs) { return double(lhs) > rhs.m_value && lhs != rhs; } - DOCTEST_APPROX_PREFIX operator> (const Approx& lhs, const T& rhs) { return lhs.m_value > double(rhs) && lhs != rhs; } -#undef DOCTEST_APPROX_PREFIX - // clang-format on - - Approx& epsilon(double newEpsilon) { - m_epsilon = (newEpsilon); - return *this; - } - - template <typename T> - typename detail::traits::enable_if<detail::traits::is_constructible<double, T>::value, - Approx&>::type - epsilon(const T& newEpsilon) { - m_epsilon = static_cast<double>(newEpsilon); - return *this; - } - - Approx& scale(double newScale) { - m_scale = (newScale); - return *this; - } - - template <typename T> - typename detail::traits::enable_if<detail::traits::is_constructible<double, T>::value, - Approx&>::type - scale(const T& newScale) { - m_scale = static_cast<double>(newScale); - return *this; - } - - String toString() const; - -private: - double m_epsilon; - double m_scale; - double m_value; -}; - -template <> -inline String toString<Approx>(const DOCTEST_REF_WRAP(Approx) value) { - return value.toString(); -} - -#if !defined(DOCTEST_CONFIG_DISABLE) - -namespace detail -{ - // the function type this library works with - typedef void (*funcType)(); - - namespace assertType - { - enum Enum - { - // macro traits - - is_warn = 1, - is_check = 2, - is_require = 4, - - is_throws = 8, - is_throws_as = 16, - is_nothrow = 32, - - is_fast = 64, // not checked anywhere - used just to distinguish the types - is_false = 128, - is_unary = 256, - - is_eq = 512, - is_ne = 1024, - - is_lt = 2048, - is_gt = 4096, - - is_ge = 8192, - is_le = 16384, - - // macro types - - DT_WARN = is_warn, - DT_CHECK = is_check, - DT_REQUIRE = is_require, - - DT_WARN_FALSE = is_false | is_warn, - DT_CHECK_FALSE = is_false | is_check, - DT_REQUIRE_FALSE = is_false | is_require, - - DT_WARN_THROWS = is_throws | is_warn, - DT_CHECK_THROWS = is_throws | is_check, - DT_REQUIRE_THROWS = is_throws | is_require, - - DT_WARN_THROWS_AS = is_throws_as | is_warn, - DT_CHECK_THROWS_AS = is_throws_as | is_check, - DT_REQUIRE_THROWS_AS = is_throws_as | is_require, - - DT_WARN_NOTHROW = is_nothrow | is_warn, - DT_CHECK_NOTHROW = is_nothrow | is_check, - DT_REQUIRE_NOTHROW = is_nothrow | is_require, - - DT_WARN_EQ = is_eq | is_warn, - DT_CHECK_EQ = is_eq | is_check, - DT_REQUIRE_EQ = is_eq | is_require, - - DT_WARN_NE = is_ne | is_warn, - DT_CHECK_NE = is_ne | is_check, - DT_REQUIRE_NE = is_ne | is_require, - - DT_WARN_GT = is_gt | is_warn, - DT_CHECK_GT = is_gt | is_check, - DT_REQUIRE_GT = is_gt | is_require, - - DT_WARN_LT = is_lt | is_warn, - DT_CHECK_LT = is_lt | is_check, - DT_REQUIRE_LT = is_lt | is_require, - - DT_WARN_GE = is_ge | is_warn, - DT_CHECK_GE = is_ge | is_check, - DT_REQUIRE_GE = is_ge | is_require, - - DT_WARN_LE = is_le | is_warn, - DT_CHECK_LE = is_le | is_check, - DT_REQUIRE_LE = is_le | is_require, - - DT_WARN_UNARY = is_unary | is_warn, - DT_CHECK_UNARY = is_unary | is_check, - DT_REQUIRE_UNARY = is_unary | is_require, - - DT_WARN_UNARY_FALSE = is_false | is_unary | is_warn, - DT_CHECK_UNARY_FALSE = is_false | is_unary | is_check, - DT_REQUIRE_UNARY_FALSE = is_false | is_unary | is_require, - - DT_FAST_WARN_EQ = is_fast | is_eq | is_warn, - DT_FAST_CHECK_EQ = is_fast | is_eq | is_check, - DT_FAST_REQUIRE_EQ = is_fast | is_eq | is_require, - - DT_FAST_WARN_NE = is_fast | is_ne | is_warn, - DT_FAST_CHECK_NE = is_fast | is_ne | is_check, - DT_FAST_REQUIRE_NE = is_fast | is_ne | is_require, - - DT_FAST_WARN_GT = is_fast | is_gt | is_warn, - DT_FAST_CHECK_GT = is_fast | is_gt | is_check, - DT_FAST_REQUIRE_GT = is_fast | is_gt | is_require, - - DT_FAST_WARN_LT = is_fast | is_lt | is_warn, - DT_FAST_CHECK_LT = is_fast | is_lt | is_check, - DT_FAST_REQUIRE_LT = is_fast | is_lt | is_require, - - DT_FAST_WARN_GE = is_fast | is_ge | is_warn, - DT_FAST_CHECK_GE = is_fast | is_ge | is_check, - DT_FAST_REQUIRE_GE = is_fast | is_ge | is_require, - - DT_FAST_WARN_LE = is_fast | is_le | is_warn, - DT_FAST_CHECK_LE = is_fast | is_le | is_check, - DT_FAST_REQUIRE_LE = is_fast | is_le | is_require, - - DT_FAST_WARN_UNARY = is_fast | is_unary | is_warn, - DT_FAST_CHECK_UNARY = is_fast | is_unary | is_check, - DT_FAST_REQUIRE_UNARY = is_fast | is_unary | is_require, - - DT_FAST_WARN_UNARY_FALSE = is_fast | is_false | is_unary | is_warn, - DT_FAST_CHECK_UNARY_FALSE = is_fast | is_false | is_unary | is_check, - DT_FAST_REQUIRE_UNARY_FALSE = is_fast | is_false | is_unary | is_require - }; - } // namespace assertType - - DOCTEST_INTERFACE const char* getAssertString(assertType::Enum val); - - // clang-format off - template<class T> struct decay_array { typedef T type; }; - template<class T, unsigned N> struct decay_array<T[N]> { typedef T* type; }; - template<class T> struct decay_array<T[]> { typedef T* type; }; - - template<class T> struct not_char_pointer { enum { value = 1 }; }; - template<> struct not_char_pointer<char*> { enum { value = 0 }; }; - template<> struct not_char_pointer<const char*> { enum { value = 0 }; }; - - template<class T> struct can_use_op : not_char_pointer<typename decay_array<T>::type> {}; - // clang-format on - - struct TestFailureException - {}; - - DOCTEST_INTERFACE bool checkIfShouldThrow(assertType::Enum assert_type); - DOCTEST_INTERFACE void fastAssertThrowIfFlagSet(int flags); - DOCTEST_INTERFACE void throwException(); - - struct TestAccessibleContextState - { - bool no_throw; // to skip exceptions-related assertion macros - bool success; // include successful assertions in output - }; - - struct ContextState; - - DOCTEST_INTERFACE TestAccessibleContextState* getTestsContextState(); - - struct DOCTEST_INTERFACE SubcaseSignature - { - const char* m_name; - const char* m_file; - int m_line; - - SubcaseSignature(const char* name, const char* file, int line) - : m_name(name) - , m_file(file) - , m_line(line) {} - - bool operator<(const SubcaseSignature& other) const; - }; - - // cppcheck-suppress copyCtorAndEqOperator - struct DOCTEST_INTERFACE Subcase - { - SubcaseSignature m_signature; - bool m_entered; - - Subcase(const char* name, const char* file, int line); - Subcase(const Subcase& other); - ~Subcase(); - - operator bool() const { return m_entered; } - }; - - template <typename L, typename R> - String stringifyBinaryExpr(const DOCTEST_REF_WRAP(L) lhs, const char* op, - const DOCTEST_REF_WRAP(R) rhs) { - return toString(lhs) + op + toString(rhs); - } - - struct DOCTEST_INTERFACE Result - { - bool m_passed; - String m_decomposition; - - ~Result(); - - DOCTEST_NOINLINE Result(bool passed = false, const String& decomposition = String()) - : m_passed(passed) - , m_decomposition(decomposition) {} - - DOCTEST_NOINLINE Result(const Result& other) - : m_passed(other.m_passed) - , m_decomposition(other.m_decomposition) {} - - Result& operator=(const Result& other); - - operator bool() { return !m_passed; } - - // clang-format off - // forbidding some expressions based on this table: http://en.cppreference.com/w/cpp/language/operator_precedence - template <typename R> Result& operator& (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator^ (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator| (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator&& (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator|| (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator== (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator!= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator< (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator> (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator<= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator>= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator+= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator-= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator*= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator/= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator%= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator<<=(const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator>>=(const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator&= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator^= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - template <typename R> Result& operator|= (const R&) { DOCTEST_STATIC_ASSERT(deferred_false<R>::value, Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); return *this; } - // clang-format on - }; - -#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wsign-compare" -//#pragma clang diagnostic ignored "-Wdouble-promotion" -//#pragma clang diagnostic ignored "-Wconversion" -//#pragma clang diagnostic ignored "-Wfloat-equal" -#endif // __clang__ - -#if defined(__GNUC__) && !defined(__clang__) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) -#pragma GCC diagnostic push -#endif // > gcc 4.6 -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wsign-compare" -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 5) -//#pragma GCC diagnostic ignored "-Wdouble-promotion" -#endif // > gcc 4.5 -//#pragma GCC diagnostic ignored "-Wconversion" -//#pragma GCC diagnostic ignored "-Wfloat-equal" -#endif // __GNUC__ - -#ifdef _MSC_VER -#pragma warning(push) -// http://stackoverflow.com/questions/39479163 what's the difference between C4018 and C4389 -#pragma warning(disable : 4389) // 'operator' : signed/unsigned mismatch -#pragma warning(disable : 4018) // 'expression' : signed/unsigned mismatch -//#pragma warning(disable : 4805) // 'operation' : unsafe mix of type 'type' and type 'type' in operation -#endif // _MSC_VER - -#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - -// clang-format off -#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_COMPARISON_RETURN_TYPE bool -#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_COMPARISON_RETURN_TYPE typename traits::enable_if<can_use_op<L>::value || can_use_op<R>::value, bool>::type - inline bool eq(const char* lhs, const char* rhs) { return String(lhs) == String(rhs); } - inline bool ne(const char* lhs, const char* rhs) { return String(lhs) != String(rhs); } - inline bool lt(const char* lhs, const char* rhs) { return String(lhs) < String(rhs); } - inline bool gt(const char* lhs, const char* rhs) { return String(lhs) > String(rhs); } - inline bool le(const char* lhs, const char* rhs) { return String(lhs) <= String(rhs); } - inline bool ge(const char* lhs, const char* rhs) { return String(lhs) >= String(rhs); } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - - template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE eq(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs == rhs; } - template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE ne(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs != rhs; } - template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE lt(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs < rhs; } - template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE gt(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs > rhs; } - template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE le(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs <= rhs; } - template <typename L, typename R> DOCTEST_COMPARISON_RETURN_TYPE ge(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) { return lhs >= rhs; } -// clang-format on - -#ifndef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_CMP_EQ(l, r) l == r -#define DOCTEST_CMP_NE(l, r) l != r -#define DOCTEST_CMP_GT(l, r) l > r -#define DOCTEST_CMP_LT(l, r) l < r -#define DOCTEST_CMP_GE(l, r) l >= r -#define DOCTEST_CMP_LE(l, r) l <= r -#else // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -#define DOCTEST_CMP_EQ(l, r) eq(l, r) -#define DOCTEST_CMP_NE(l, r) ne(l, r) -#define DOCTEST_CMP_GT(l, r) gt(l, r) -#define DOCTEST_CMP_LT(l, r) lt(l, r) -#define DOCTEST_CMP_GE(l, r) ge(l, r) -#define DOCTEST_CMP_LE(l, r) le(l, r) -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - -#define DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(op, op_str, op_macro) \ - template <typename R> \ - DOCTEST_NOINLINE Result operator op(const DOCTEST_REF_WRAP(R) rhs) { \ - bool res = op_macro(lhs, rhs); \ - if(m_assert_type & assertType::is_false) \ - res = !res; \ - if(!res || doctest::detail::getTestsContextState()->success) \ - return Result(res, stringifyBinaryExpr(lhs, op_str, rhs)); \ - return Result(res); \ - } - -#define DOCTEST_FORBIT_EXPRESSION(op) \ - template <typename R> \ - Expression_lhs& operator op(const R&) { \ - DOCTEST_STATIC_ASSERT(deferred_false<R>::value, \ - Expression_Too_Complex_Please_Rewrite_As_Binary_Comparison); \ - return *this; \ - } - - template <typename L> - // cppcheck-suppress copyCtorAndEqOperator - struct Expression_lhs - { - L lhs; - assertType::Enum m_assert_type; - - explicit Expression_lhs(L in, assertType::Enum assert_type) - : lhs(in) - , m_assert_type(assert_type) {} - - Expression_lhs(const Expression_lhs& other) - : lhs(other.lhs) {} - - DOCTEST_NOINLINE operator Result() { - bool res = !!lhs; - if(m_assert_type & assertType::is_false) //!OCLINT bitwise operator in conditional - res = !res; - - if(!res || getTestsContextState()->success) - return Result(res, toString(lhs)); - return Result(res); - } - - // clang-format off - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(==, " == ", DOCTEST_CMP_EQ) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(!=, " != ", DOCTEST_CMP_NE) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>, " > ", DOCTEST_CMP_GT) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<, " < ", DOCTEST_CMP_LT) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(>=, " >= ", DOCTEST_CMP_GE) //!OCLINT bitwise operator in conditional - DOCTEST_DO_BINARY_EXPRESSION_COMPARISON(<=, " <= ", DOCTEST_CMP_LE) //!OCLINT bitwise operator in conditional - // clang-format on - - // forbidding some expressions based on this table: http://en.cppreference.com/w/cpp/language/operator_precedence - DOCTEST_FORBIT_EXPRESSION(&) - DOCTEST_FORBIT_EXPRESSION (^) - DOCTEST_FORBIT_EXPRESSION(|) - DOCTEST_FORBIT_EXPRESSION(&&) - DOCTEST_FORBIT_EXPRESSION(||) - DOCTEST_FORBIT_EXPRESSION(=) - DOCTEST_FORBIT_EXPRESSION(+=) - DOCTEST_FORBIT_EXPRESSION(-=) - DOCTEST_FORBIT_EXPRESSION(*=) - DOCTEST_FORBIT_EXPRESSION(/=) - DOCTEST_FORBIT_EXPRESSION(%=) - DOCTEST_FORBIT_EXPRESSION(<<=) - DOCTEST_FORBIT_EXPRESSION(>>=) - DOCTEST_FORBIT_EXPRESSION(&=) - DOCTEST_FORBIT_EXPRESSION(^=) - DOCTEST_FORBIT_EXPRESSION(|=) - // these 2 are unfortunate because they should be allowed - they have higher precedence over the comparisons, but the - // ExpressionDecomposer class uses the left shift operator to capture the left operand of the binary expression... - DOCTEST_FORBIT_EXPRESSION(<<) - DOCTEST_FORBIT_EXPRESSION(>>) - }; - -#ifndef DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif // __clang__ - -#if defined(__GNUC__) && !defined(__clang__) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) -#pragma GCC diagnostic pop -#endif // > gcc 4.6 -#endif // __GNUC__ - -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER - -#endif // DOCTEST_CONFIG_NO_COMPARISON_WARNING_SUPPRESSION - - struct ExpressionDecomposer - { - assertType::Enum m_assert_type; - - ExpressionDecomposer(assertType::Enum assert_type) - : m_assert_type(assert_type) {} - - // The right operator for capturing expressions is "<=" instead of "<<" (based on the operator precedence table) - // but then there will be warnings from GCC about "-Wparentheses" and since "_Pragma()" is problematic this will stay for now... - // https://github.com/philsquared/Catch/issues/870 - // https://github.com/philsquared/Catch/issues/565 - template <typename L> - Expression_lhs<const DOCTEST_REF_WRAP(L)> operator<<(const DOCTEST_REF_WRAP(L) operand) { - return Expression_lhs<const DOCTEST_REF_WRAP(L)>(operand, m_assert_type); - } - }; - - struct DOCTEST_INTERFACE TestCase - { - // not used for determining uniqueness - funcType m_test; // a function pointer to the test case - String m_full_name; // contains the name (only for templated test cases!) + the template type - const char* m_name; // name of the test case - const char* m_type; // for templated test cases - gets appended to the real name - const char* m_test_suite; // the test suite in which the test was added - const char* m_description; - bool m_skip; - bool m_may_fail; - bool m_should_fail; - int m_expected_failures; - double m_timeout; - - // fields by which uniqueness of test cases shall be determined - const char* m_file; // the file in which the test was registered - unsigned m_line; // the line where the test was registered - int m_template_id; // an ID used to distinguish between the different versions of a templated test case - - TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite, - const char* type = "", int template_id = -1); - - // for gcc 4.7 - DOCTEST_NOINLINE ~TestCase() {} - - TestCase& operator*(const char* in); - - template <typename T> - TestCase& operator*(const T& in) { - in.fill(*this); - return *this; - } - - TestCase(const TestCase& other) { *this = other; } - - TestCase& operator=(const TestCase& other); - - bool operator<(const TestCase& other) const; - }; - - // forward declarations of functions used by the macros - DOCTEST_INTERFACE int regTest(const TestCase& tc); - DOCTEST_INTERFACE int setTestSuite(const TestSuite& ts); - - DOCTEST_INTERFACE void addFailedAssert(assertType::Enum assert_type); - - DOCTEST_INTERFACE void logTestStart(const TestCase& tc); - DOCTEST_INTERFACE void logTestEnd(); - - DOCTEST_INTERFACE void logTestException(const String& what, bool crash = false); - - DOCTEST_INTERFACE void logAssert(bool passed, const char* decomposition, bool threw, - const String& exception, const char* expr, - assertType::Enum assert_type, const char* file, int line); - - DOCTEST_INTERFACE void logAssertThrows(bool threw, const char* expr, - assertType::Enum assert_type, const char* file, - int line); - - DOCTEST_INTERFACE void logAssertThrowsAs(bool threw, bool threw_as, const char* as, - const String& exception, const char* expr, - assertType::Enum assert_type, const char* file, - int line); - - DOCTEST_INTERFACE void logAssertNothrow(bool threw, const String& exception, const char* expr, - assertType::Enum assert_type, const char* file, - int line); - - DOCTEST_INTERFACE bool isDebuggerActive(); - DOCTEST_INTERFACE void writeToDebugConsole(const String&); - - namespace binaryAssertComparison - { - enum Enum - { - eq = 0, - ne, - gt, - lt, - ge, - le - }; - } // namespace binaryAssertComparison - - // clang-format off - template <int, class L, class R> struct RelationalComparator { bool operator()(const DOCTEST_REF_WRAP(L), const DOCTEST_REF_WRAP(R) ) const { return false; } }; - template <class L, class R> struct RelationalComparator<0, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return eq(lhs, rhs); } }; - template <class L, class R> struct RelationalComparator<1, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return ne(lhs, rhs); } }; - template <class L, class R> struct RelationalComparator<2, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return gt(lhs, rhs); } }; - template <class L, class R> struct RelationalComparator<3, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return lt(lhs, rhs); } }; - template <class L, class R> struct RelationalComparator<4, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return ge(lhs, rhs); } }; - template <class L, class R> struct RelationalComparator<5, L, R> { bool operator()(const DOCTEST_REF_WRAP(L) lhs, const DOCTEST_REF_WRAP(R) rhs) const { return le(lhs, rhs); } }; - // clang-format on - - struct DOCTEST_INTERFACE ResultBuilder - { - assertType::Enum m_assert_type; - const char* m_file; - int m_line; - const char* m_expr; - const char* m_exception_type; - - Result m_result; - bool m_threw; - bool m_threw_as; - bool m_failed; - String m_exception; - - ResultBuilder(assertType::Enum assert_type, const char* file, int line, const char* expr, - const char* exception_type = ""); - - ~ResultBuilder(); - - void setResult(const Result& res) { m_result = res; } - - template <int comparison, typename L, typename R> - DOCTEST_NOINLINE void binary_assert(const DOCTEST_REF_WRAP(L) lhs, - const DOCTEST_REF_WRAP(R) rhs) { - m_result.m_passed = RelationalComparator<comparison, L, R>()(lhs, rhs); - if(!m_result.m_passed || getTestsContextState()->success) - m_result.m_decomposition = stringifyBinaryExpr(lhs, ", ", rhs); - } - - template <typename L> - DOCTEST_NOINLINE void unary_assert(const DOCTEST_REF_WRAP(L) val) { - m_result.m_passed = !!val; - - if(m_assert_type & assertType::is_false) //!OCLINT bitwise operator in conditional - m_result.m_passed = !m_result.m_passed; - - if(!m_result.m_passed || getTestsContextState()->success) - m_result.m_decomposition = toString(val); - } - - void unexpectedExceptionOccurred(); - - bool log(); - void react() const; - }; - - namespace assertAction - { - enum Enum - { - nothing = 0, - dbgbreak = 1, - shouldthrow = 2 - }; - } // namespace assertAction - - template <int comparison, typename L, typename R> - DOCTEST_NOINLINE int fast_binary_assert(assertType::Enum assert_type, const char* file, - int line, const char* expr, - const DOCTEST_REF_WRAP(L) lhs, - const DOCTEST_REF_WRAP(R) rhs) { - ResultBuilder rb(assert_type, file, line, expr); - - rb.m_result.m_passed = RelationalComparator<comparison, L, R>()(lhs, rhs); - - if(!rb.m_result.m_passed || getTestsContextState()->success) - rb.m_result.m_decomposition = stringifyBinaryExpr(lhs, ", ", rhs); - - int res = 0; - - if(rb.log()) - res |= assertAction::dbgbreak; - - if(rb.m_failed && checkIfShouldThrow(assert_type)) - res |= assertAction::shouldthrow; - -#ifdef DOCTEST_CONFIG_SUPER_FAST_ASSERTS - // ######################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK TO SEE THE FAILING ASSERTION - // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ######################################################################################### - if(res & assertAction::dbgbreak) - DOCTEST_BREAK_INTO_DEBUGGER(); - fastAssertThrowIfFlagSet(res); -#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - - return res; - } - - template <typename L> - DOCTEST_NOINLINE int fast_unary_assert(assertType::Enum assert_type, const char* file, int line, - const char* val_str, const DOCTEST_REF_WRAP(L) val) { - ResultBuilder rb(assert_type, file, line, val_str); - - rb.m_result.m_passed = !!val; - - if(assert_type & assertType::is_false) //!OCLINT bitwise operator in conditional - rb.m_result.m_passed = !rb.m_result.m_passed; - - if(!rb.m_result.m_passed || getTestsContextState()->success) - rb.m_result.m_decomposition = toString(val); - - int res = 0; - - if(rb.log()) - res |= assertAction::dbgbreak; - - if(rb.m_failed && checkIfShouldThrow(assert_type)) - res |= assertAction::shouldthrow; - -#ifdef DOCTEST_CONFIG_SUPER_FAST_ASSERTS - // ######################################################################################### - // IF THE DEBUGGER BREAKS HERE - GO 1 LEVEL UP IN THE CALLSTACK TO SEE THE FAILING ASSERTION - // THIS IS THE EFFECT OF HAVING 'DOCTEST_CONFIG_SUPER_FAST_ASSERTS' DEFINED - // ######################################################################################### - if(res & assertAction::dbgbreak) - DOCTEST_BREAK_INTO_DEBUGGER(); - fastAssertThrowIfFlagSet(res); -#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - - return res; - } - - struct DOCTEST_INTERFACE IExceptionTranslator //!OCLINT destructor of virtual class - { - virtual ~IExceptionTranslator(); - virtual bool translate(String&) const = 0; - }; - - template <typename T> - class ExceptionTranslator : public IExceptionTranslator //!OCLINT destructor of virtual class - { - public: - explicit ExceptionTranslator(String (*translateFunction)(T)) - : m_translateFunction(translateFunction) {} - - bool translate(String& res) const { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - try { - throw; - // cppcheck-suppress catchExceptionByValue - } catch(T ex) { // NOLINT - res = m_translateFunction(ex); //!OCLINT parameter reassignment - return true; - } catch(...) {} //!OCLINT - empty catch statement -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - ((void)res); // to silence -Wunused-parameter - return false; - } - - protected: - String (*m_translateFunction)(T); - }; - - DOCTEST_INTERFACE void registerExceptionTranslatorImpl( - const IExceptionTranslator* translateFunction); - - // FIX FOR VISUAL STUDIO VERSIONS PRIOR TO 2015 - they failed to compile the call to operator<< with - // std::ostream passed as a reference noting that there is a use of an undefined type (which there isn't) - DOCTEST_INTERFACE void writeStringToStream(std::ostream* stream, const String& str); - - template <bool C> - struct StringStreamBase - { - template <typename T> - static void convert(std::ostream* stream, const T& in) { - writeStringToStream(stream, toString(in)); - } - - // always treat char* as a string in this context - no matter - // if DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING is defined - static void convert(std::ostream* stream, const char* in) { - writeStringToStream(stream, String(in)); - } - }; - - template <> - struct StringStreamBase<true> - { - template <typename T> - static void convert(std::ostream* stream, const T& in) { - *stream << in; - } - }; - - template <typename T> - struct StringStream : StringStreamBase<has_insertion_operator<T>::value> - {}; - - template <typename T> - void toStream(std::ostream* stream, const T& value) { - StringStream<T>::convert(stream, value); - } - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - DOCTEST_INTERFACE void toStream(std::ostream* stream, char* in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, const char* in); -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - DOCTEST_INTERFACE void toStream(std::ostream* stream, bool in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, float in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, double in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, double long in); - - DOCTEST_INTERFACE void toStream(std::ostream* stream, char in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, char signed in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, char unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, int short in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, int short unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, int in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, int unsigned in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, int long in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, int long unsigned in); - -#ifdef DOCTEST_CONFIG_WITH_LONG_LONG - DOCTEST_INTERFACE void toStream(std::ostream* stream, int long long in); - DOCTEST_INTERFACE void toStream(std::ostream* stream, int long long unsigned in); -#endif // DOCTEST_CONFIG_WITH_LONG_LONG - - struct IContextScope //!OCLINT destructor of virtual class - { virtual void build(std::ostream*) = 0; }; - - DOCTEST_INTERFACE void addToContexts(IContextScope* ptr); - DOCTEST_INTERFACE void popFromContexts(); - DOCTEST_INTERFACE void useContextIfExceptionOccurred(IContextScope* ptr); - - // cppcheck-suppress copyCtorAndEqOperator - class ContextBuilder - { - friend class ContextScope; - - struct ICapture //!OCLINT destructor of virtual class - { virtual void toStream(std::ostream*) const = 0; }; - - template <typename T> - struct Capture : ICapture //!OCLINT destructor of virtual class - { - const T* capture; - - explicit Capture(const T* in) - : capture(in) {} - virtual void toStream(std::ostream* stream) const { // override - doctest::detail::toStream(stream, *capture); - } - }; - - struct Chunk - { - char buf[sizeof(Capture<char>)]; // place to construct a Capture<T> - }; - - struct Node - { - Chunk chunk; - Node* next; - }; - - Chunk stackChunks[DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK]; - int numCaptures; - Node* head; - Node* tail; - - void build(std::ostream* stream) const { - int curr = 0; - // iterate over small buffer - while(curr < numCaptures && curr < DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK) - reinterpret_cast<const ICapture*>(stackChunks[curr++].buf)->toStream(stream); - // iterate over list - Node* curr_elem = head; - while(curr < numCaptures) { - reinterpret_cast<const ICapture*>(curr_elem->chunk.buf)->toStream(stream); - curr_elem = curr_elem->next; - ++curr; - } - } - - // steal the contents of the other - acting as a move constructor... - DOCTEST_NOINLINE ContextBuilder(ContextBuilder& other) - : numCaptures(other.numCaptures) - , head(other.head) - , tail(other.tail) { - other.numCaptures = 0; - other.head = 0; - other.tail = 0; - my_memcpy(stackChunks, other.stackChunks, - unsigned(int(sizeof(Chunk)) * DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK)); - } - - public: - // cppcheck-suppress uninitMemberVar - DOCTEST_NOINLINE ContextBuilder() // NOLINT - : numCaptures(0) - , head(0) - , tail(0) {} - - template <typename T> - DOCTEST_NOINLINE ContextBuilder& operator<<(T& in) { - Capture<T> temp(&in); - - // construct either on stack or on heap - // copy the bytes for the whole object - including the vtable because we cant construct - // the object directly in the buffer using placement new - need the <new> header... - if(numCaptures < DOCTEST_CONFIG_NUM_CAPTURES_ON_STACK) { - my_memcpy(stackChunks[numCaptures].buf, &temp, sizeof(Chunk)); - } else { - Node* curr = new Node; - curr->next = 0; - if(tail) { - tail->next = curr; - tail = curr; - } else { - head = tail = curr; - } - - my_memcpy(tail->chunk.buf, &temp, sizeof(Chunk)); - } - ++numCaptures; - return *this; - } - - DOCTEST_NOINLINE ~ContextBuilder() { - // free the linked list - the ones on the stack are left as-is - // no destructors are called at all - there is no need - while(head) { - Node* next = head->next; - delete head; - head = next; - } - } - -#ifdef DOCTEST_CONFIG_WITH_RVALUE_REFERENCES - template <typename T> - ContextBuilder& operator<<(const T&&) { - DOCTEST_STATIC_ASSERT( - deferred_false<T>::value, - Cannot_pass_temporaries_or_rvalues_to_the_streaming_operator_because_it_caches_pointers_to_the_passed_objects_for_lazy_evaluation); - return *this; - } -#endif // DOCTEST_CONFIG_WITH_RVALUE_REFERENCES - }; - - class ContextScope : public IContextScope //!OCLINT destructor of virtual class - { - ContextBuilder contextBuilder; - bool built; - - public: - DOCTEST_NOINLINE explicit ContextScope(ContextBuilder& temp) - : contextBuilder(temp) - , built(false) { - addToContexts(this); - } - - DOCTEST_NOINLINE ~ContextScope() { - if(!built) - useContextIfExceptionOccurred(this); - popFromContexts(); - } - - void build(std::ostream* stream) { - built = true; - contextBuilder.build(stream); - } - }; - - class DOCTEST_INTERFACE MessageBuilder - { - std::ostream* m_stream; - const char* m_file; - int m_line; - doctest::detail::assertType::Enum m_severity; - - public: - MessageBuilder(const char* file, int line, doctest::detail::assertType::Enum severity); - ~MessageBuilder(); - - template <typename T> - MessageBuilder& operator<<(const T& in) { - doctest::detail::toStream(m_stream, in); - return *this; - } - - bool log(); - void react(); - }; -} // namespace detail - -struct test_suite -{ - const char* data; - test_suite(const char* in) - : data(in) {} - void fill(detail::TestCase& state) const { state.m_test_suite = data; } - void fill(detail::TestSuite& state) const { state.m_test_suite = data; } -}; - -struct description -{ - const char* data; - description(const char* in) - : data(in) {} - void fill(detail::TestCase& state) const { state.m_description = data; } - void fill(detail::TestSuite& state) const { state.m_description = data; } -}; - -struct skip -{ - bool data; - skip(bool in = true) - : data(in) {} - void fill(detail::TestCase& state) const { state.m_skip = data; } - void fill(detail::TestSuite& state) const { state.m_skip = data; } -}; - -struct timeout -{ - double data; - timeout(double in) - : data(in) {} - void fill(detail::TestCase& state) const { state.m_timeout = data; } - void fill(detail::TestSuite& state) const { state.m_timeout = data; } -}; - -struct may_fail -{ - bool data; - may_fail(bool in = true) - : data(in) {} - void fill(detail::TestCase& state) const { state.m_may_fail = data; } - void fill(detail::TestSuite& state) const { state.m_may_fail = data; } -}; - -struct should_fail -{ - bool data; - should_fail(bool in = true) - : data(in) {} - void fill(detail::TestCase& state) const { state.m_should_fail = data; } - void fill(detail::TestSuite& state) const { state.m_should_fail = data; } -}; - -struct expected_failures -{ - int data; - expected_failures(int in) - : data(in) {} - void fill(detail::TestCase& state) const { state.m_expected_failures = data; } - void fill(detail::TestSuite& state) const { state.m_expected_failures = data; } -}; - -#endif // DOCTEST_CONFIG_DISABLE - -#ifndef DOCTEST_CONFIG_DISABLE -template <typename T> -int registerExceptionTranslator(String (*translateFunction)(T)) { -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wexit-time-destructors" -#endif // __clang__ - static detail::ExceptionTranslator<T> exceptionTranslator(translateFunction); -#if defined(__clang__) -#pragma clang diagnostic pop -#endif // __clang__ - detail::registerExceptionTranslatorImpl(&exceptionTranslator); - return 0; -} - -#else // DOCTEST_CONFIG_DISABLE -template <typename T> -int registerExceptionTranslator(String (*)(T)) { - return 0; -} -#endif // DOCTEST_CONFIG_DISABLE - -DOCTEST_INTERFACE bool isRunningInTest(); - -// cppcheck-suppress noCopyConstructor -class DOCTEST_INTERFACE Context -{ -#if !defined(DOCTEST_CONFIG_DISABLE) - detail::ContextState* p; - - void parseArgs(int argc, const char* const* argv, bool withDefaults = false); - -#endif // DOCTEST_CONFIG_DISABLE - -public: - explicit Context(int argc = 0, const char* const* argv = 0); - - ~Context(); - - void applyCommandLine(int argc, const char* const* argv); - - void addFilter(const char* filter, const char* value); - void clearFilters(); - void setOption(const char* option, int value); - void setOption(const char* option, const char* value); - - bool shouldExit(); - - int run(); -}; - -} // namespace doctest - -// if registering is not disabled -#if !defined(DOCTEST_CONFIG_DISABLE) - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_EXPAND_VA_ARGS(...) __VA_ARGS__ -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_EXPAND_VA_ARGS -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#define DOCTEST_STRIP_PARENS(x) x -#define DOCTEST_HANDLE_BRACED_VA_ARGS(expr) DOCTEST_STRIP_PARENS(DOCTEST_EXPAND_VA_ARGS expr) - -// registers the test by initializing a dummy var with a function -#define DOCTEST_REGISTER_FUNCTION(f, decorators) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = doctest::detail::regTest( \ - doctest::detail::TestCase(f, __FILE__, __LINE__, \ - doctest_detail_test_suite_ns::getCurrentTestSuite()) * \ - decorators); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() - -#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, decorators) \ - namespace \ - { \ - struct der : base \ - { void f(); }; \ - static void func() { \ - der v; \ - v.f(); \ - } \ - DOCTEST_REGISTER_FUNCTION(func, decorators) \ - } \ - inline DOCTEST_NOINLINE void der::f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, decorators) \ - static void f(); \ - DOCTEST_REGISTER_FUNCTION(f, decorators) \ - static void f() - -// for registering tests -#define DOCTEST_TEST_CASE(decorators) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), decorators) - -// for registering tests with a fixture -#define DOCTEST_TEST_CASE_FIXTURE(c, decorators) \ - DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), c, \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), decorators) - -// for converting types to strings without the <typeinfo> header and demangling -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TYPE_TO_STRING_IMPL(...) \ - template <> \ - inline const char* type_to_string<__VA_ARGS__>() { \ - return "<" #__VA_ARGS__ ">"; \ - } -#define DOCTEST_TYPE_TO_STRING(...) \ - namespace doctest \ - { \ - namespace detail \ - { DOCTEST_TYPE_TO_STRING_IMPL(__VA_ARGS__) } \ - } \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TYPE_TO_STRING_IMPL(x) \ - template <> \ - inline const char* type_to_string<x>() { \ - return "<" #x ">"; \ - } -#define DOCTEST_TYPE_TO_STRING(x) \ - namespace doctest \ - { \ - namespace detail \ - { DOCTEST_TYPE_TO_STRING_IMPL(x) } \ - } \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -// for typed tests -#define DOCTEST_TEST_CASE_TEMPLATE_IMPL(decorators, T, types, anon) \ - template <typename T> \ - inline void anon(); \ - struct DOCTEST_CAT(anon, FUNCTOR) \ - { \ - template <int Index, typename Type> \ - void operator()() { \ - doctest::detail::regTest( \ - doctest::detail::TestCase(anon<Type>, __FILE__, __LINE__, \ - doctest_detail_test_suite_ns::getCurrentTestSuite(), \ - doctest::detail::type_to_string<Type>(), Index) * \ - decorators); \ - } \ - }; \ - inline int DOCTEST_CAT(anon, REG_FUNC)() { \ - DOCTEST_CAT(anon, FUNCTOR) registrar; \ - doctest::detail::ForEachType<DOCTEST_HANDLE_BRACED_VA_ARGS(types)::Result, \ - DOCTEST_CAT(anon, FUNCTOR)> \ - doIt(registrar); \ - return 0; \ - } \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = DOCTEST_CAT(anon, REG_FUNC)(); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - template <typename T> \ - inline void anon() - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TEST_CASE_TEMPLATE(decorators, T, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_IMPL(decorators, T, (__VA_ARGS__), \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TEST_CASE_TEMPLATE(decorators, T, types) \ - DOCTEST_TEST_CASE_TEMPLATE_IMPL(decorators, T, types, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(decorators, T, id, anon) \ - template <typename T> \ - inline void anon(); \ - struct DOCTEST_CAT(id, _FUNCTOR) \ - { \ - int m_line; \ - DOCTEST_CAT(id, _FUNCTOR) \ - (int line) \ - : m_line(line) {} \ - template <int Index, typename Type> \ - void operator()() { \ - doctest::detail::regTest( \ - doctest::detail::TestCase(anon<Type>, __FILE__, __LINE__, \ - doctest_detail_test_suite_ns::getCurrentTestSuite(), \ - doctest::detail::type_to_string<Type>(), \ - m_line * 1000 + Index) * \ - decorators); \ - } \ - }; \ - template <typename T> \ - inline void anon() - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(decorators, T, id) \ - DOCTEST_TEST_CASE_TEMPLATE_DEFINE_IMPL(decorators, T, id, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)) - -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, types, anon) \ - static int DOCTEST_CAT(anon, REG_FUNC)() { \ - DOCTEST_CAT(id, _FUNCTOR) registrar(__LINE__); \ - doctest::detail::ForEachType<DOCTEST_HANDLE_BRACED_VA_ARGS(types)::Result, \ - DOCTEST_CAT(id, _FUNCTOR)> \ - doIt(registrar); \ - return 0; \ - } \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_CAT(anon, DUMMY)) = DOCTEST_CAT(anon, REG_FUNC)(); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, ...) \ - DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, (__VA_ARGS__), \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, types) \ - DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE_IMPL(id, types, DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -// for subcases -#if defined(__GNUC__) -#define DOCTEST_SUBCASE(name) \ - if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUBCASE_) \ - __attribute__((unused)) = \ - doctest::detail::Subcase(name, __FILE__, __LINE__)) -#else // __GNUC__ -#define DOCTEST_SUBCASE(name) \ - if(const doctest::detail::Subcase & DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUBCASE_) = \ - doctest::detail::Subcase(name, __FILE__, __LINE__)) -#endif // __GNUC__ - -// for grouping tests in test suites by using code blocks -#define DOCTEST_TEST_SUITE_IMPL(decorators, ns_name) \ - namespace ns_name \ - { \ - namespace doctest_detail_test_suite_ns \ - { \ - inline DOCTEST_NOINLINE doctest::detail::TestSuite& getCurrentTestSuite() { \ - static doctest::detail::TestSuite data; \ - static bool inited = false; \ - if(!inited) { \ - data* decorators; \ - inited = true; \ - } \ - return data; \ - } \ - } \ - } \ - namespace ns_name - -#define DOCTEST_TEST_SUITE(decorators) \ - DOCTEST_TEST_SUITE_IMPL(decorators, DOCTEST_ANONYMOUS(_DOCTEST_ANON_SUITE_)) - -// for starting a testsuite block -#define DOCTEST_TEST_SUITE_BEGIN(decorators) \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = \ - doctest::detail::setTestSuite(doctest::detail::TestSuite() * decorators); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for ending a testsuite block -#define DOCTEST_TEST_SUITE_END \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_VAR_)) = \ - doctest::detail::setTestSuite(doctest::detail::TestSuite() * ""); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for registering exception translators -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(translatorName, signature) \ - static doctest::String translatorName(signature); \ - DOCTEST_GLOBAL_NO_WARNINGS(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)) = \ - doctest::registerExceptionTranslator(translatorName); \ - DOCTEST_GLOBAL_NO_WARNINGS_END() \ - static doctest::String translatorName(signature) - -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ - DOCTEST_REGISTER_EXCEPTION_TRANSLATOR_IMPL(DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_), \ - signature) - -// for logging -#define DOCTEST_INFO(x) \ - doctest::detail::ContextScope DOCTEST_ANONYMOUS(_DOCTEST_CAPTURE_)( \ - doctest::detail::ContextBuilder() << x) -#define DOCTEST_CAPTURE(x) DOCTEST_INFO(#x " := " << x) - -#define DOCTEST_ADD_AT_IMPL(type, file, line, mb, x) \ - do { \ - doctest::detail::MessageBuilder mb(file, line, doctest::detail::assertType::type); \ - mb << x; \ - if(mb.log()) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - mb.react(); \ - } while((void)0, 0) - -// clang-format off -#define DOCTEST_ADD_MESSAGE_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_warn, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_check, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -#define DOCTEST_ADD_FAIL_AT(file, line, x) DOCTEST_ADD_AT_IMPL(is_require, file, line, DOCTEST_ANONYMOUS(_DOCTEST_MESSAGE_), x) -// clang-format on - -#define DOCTEST_MESSAGE(x) DOCTEST_ADD_MESSAGE_AT(__FILE__, __LINE__, x) -#define DOCTEST_FAIL_CHECK(x) DOCTEST_ADD_FAIL_CHECK_AT(__FILE__, __LINE__, x) -#define DOCTEST_FAIL(x) DOCTEST_ADD_FAIL_AT(__FILE__, __LINE__, x) - -#if __cplusplus >= 201402L || (defined(_MSC_VER) && _MSC_VER >= 1910) -template <class T, T x> -constexpr T to_lvalue = x; -#define DOCTEST_TO_LVALUE(...) to_lvalue<decltype(__VA_ARGS__), __VA_ARGS__> -#else -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TO_LVALUE(...) TO_LVALUE_CAN_BE_USED_ONLY_IN_CPP14_MODE_OR_WITH_VS_2017_OR_NEWER -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TO_LVALUE(x) TO_LVALUE_CAN_BE_USED_ONLY_IN_CPP14_MODE_OR_WITH_VS_2017_OR_NEWER -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#endif // TO_LVALUE hack for logging macros like INFO() - -// common code in asserts - for convenience -#define DOCTEST_ASSERT_LOG_AND_REACT(rb) \ - if(rb.log()) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - rb.react() - -#ifdef DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#define DOCTEST_WRAP_IN_TRY(x) x; -#else // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS -#define DOCTEST_WRAP_IN_TRY(x) \ - try { \ - x; \ - } catch(...) { _DOCTEST_RB.unexpectedExceptionOccurred(); } -#endif // DOCTEST_CONFIG_NO_TRY_CATCH_IN_ASSERTS - -#define DOCTEST_ASSERT_IMPLEMENT_3(expr, assert_type) \ - doctest::detail::ResultBuilder _DOCTEST_RB( \ - doctest::detail::assertType::assert_type, __FILE__, __LINE__, \ - DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(expr))); \ - DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.setResult( \ - doctest::detail::ExpressionDecomposer(doctest::detail::assertType::assert_type) \ - << DOCTEST_HANDLE_BRACED_VA_ARGS(expr))) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB) - -#if defined(__clang__) -#define DOCTEST_ASSERT_IMPLEMENT_2(expr, assert_type) \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Woverloaded-shift-op-parentheses\"") \ - DOCTEST_ASSERT_IMPLEMENT_3(expr, assert_type); \ - _Pragma("clang diagnostic pop") -#else // __clang__ -#define DOCTEST_ASSERT_IMPLEMENT_2(expr, assert_type) DOCTEST_ASSERT_IMPLEMENT_3(expr, assert_type); -#endif // __clang__ - -#define DOCTEST_ASSERT_IMPLEMENT_1(expr, assert_type) \ - do { \ - DOCTEST_ASSERT_IMPLEMENT_2(expr, assert_type); \ - } while((void)0, 0) - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN(...) DOCTEST_ASSERT_IMPLEMENT_1((__VA_ARGS__), DT_WARN) -#define DOCTEST_CHECK(...) DOCTEST_ASSERT_IMPLEMENT_1((__VA_ARGS__), DT_CHECK) -#define DOCTEST_REQUIRE(...) DOCTEST_ASSERT_IMPLEMENT_1((__VA_ARGS__), DT_REQUIRE) -#define DOCTEST_WARN_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1((__VA_ARGS__), DT_WARN_FALSE) -#define DOCTEST_CHECK_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1((__VA_ARGS__), DT_CHECK_FALSE) -#define DOCTEST_REQUIRE_FALSE(...) DOCTEST_ASSERT_IMPLEMENT_1((__VA_ARGS__), DT_REQUIRE_FALSE) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN(expr) DOCTEST_ASSERT_IMPLEMENT_1(expr, DT_WARN) -#define DOCTEST_CHECK(expr) DOCTEST_ASSERT_IMPLEMENT_1(expr, DT_CHECK) -#define DOCTEST_REQUIRE(expr) DOCTEST_ASSERT_IMPLEMENT_1(expr, DT_REQUIRE) -#define DOCTEST_WARN_FALSE(expr) DOCTEST_ASSERT_IMPLEMENT_1(expr, DT_WARN_FALSE) -#define DOCTEST_CHECK_FALSE(expr) DOCTEST_ASSERT_IMPLEMENT_1(expr, DT_CHECK_FALSE) -#define DOCTEST_REQUIRE_FALSE(expr) DOCTEST_ASSERT_IMPLEMENT_1(expr, DT_REQUIRE_FALSE) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -// clang-format off -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2((cond), DT_WARN); } while((void)0, 0) -#define DOCTEST_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2((cond), DT_CHECK); } while((void)0, 0) -#define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2((cond), DT_REQUIRE); } while((void)0, 0) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2((cond), DT_WARN_FALSE); } while((void)0, 0) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2((cond), DT_CHECK_FALSE); } while((void)0, 0) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2((cond), DT_REQUIRE_FALSE); } while((void)0, 0) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(cond, DT_WARN); } while((void)0, 0) -#define DOCTEST_CHECK_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(cond, DT_CHECK); } while((void)0, 0) -#define DOCTEST_REQUIRE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(cond, DT_REQUIRE); } while((void)0, 0) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(cond, DT_WARN_FALSE); } while((void)0, 0) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(cond, DT_CHECK_FALSE); } while((void)0, 0) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) do { DOCTEST_INFO(msg); DOCTEST_ASSERT_IMPLEMENT_2(cond, DT_REQUIRE_FALSE); } while((void)0, 0) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -// clang-format on - -#define DOCTEST_ASSERT_THROWS(expr, assert_type) \ - do { \ - if(!doctest::detail::getTestsContextState()->no_throw) { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::detail::assertType::assert_type, \ - __FILE__, __LINE__, #expr); \ - try { \ - expr; \ - } catch(...) { _DOCTEST_RB.m_threw = true; } \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } \ - } while((void)0, 0) - -#define DOCTEST_ASSERT_THROWS_AS(expr, as, assert_type) \ - do { \ - if(!doctest::detail::getTestsContextState()->no_throw) { \ - doctest::detail::ResultBuilder _DOCTEST_RB( \ - doctest::detail::assertType::assert_type, __FILE__, __LINE__, #expr, \ - DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(as))); \ - try { \ - expr; \ - } catch(DOCTEST_HANDLE_BRACED_VA_ARGS(as)) { \ - _DOCTEST_RB.m_threw = true; \ - _DOCTEST_RB.m_threw_as = true; \ - } catch(...) { _DOCTEST_RB.unexpectedExceptionOccurred(); } \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } \ - } while((void)0, 0) - -#define DOCTEST_ASSERT_NOTHROW(expr, assert_type) \ - do { \ - if(!doctest::detail::getTestsContextState()->no_throw) { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::detail::assertType::assert_type, \ - __FILE__, __LINE__, #expr); \ - try { \ - expr; \ - } catch(...) { _DOCTEST_RB.unexpectedExceptionOccurred(); } \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } \ - } while((void)0, 0) - -#define DOCTEST_WARN_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, DT_WARN_THROWS) -#define DOCTEST_CHECK_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, DT_CHECK_THROWS) -#define DOCTEST_REQUIRE_THROWS(expr) DOCTEST_ASSERT_THROWS(expr, DT_REQUIRE_THROWS) - -// clang-format off -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, (__VA_ARGS__), DT_WARN_THROWS_AS) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, (__VA_ARGS__), DT_CHECK_THROWS_AS) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) DOCTEST_ASSERT_THROWS_AS(expr, (__VA_ARGS__), DT_REQUIRE_THROWS_AS) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, DT_WARN_THROWS_AS) -#define DOCTEST_CHECK_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, DT_CHECK_THROWS_AS) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ex) DOCTEST_ASSERT_THROWS_AS(expr, ex, DT_REQUIRE_THROWS_AS) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -// clang-format on - -#define DOCTEST_WARN_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_WARN_NOTHROW) -#define DOCTEST_CHECK_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_CHECK_NOTHROW) -#define DOCTEST_REQUIRE_NOTHROW(expr) DOCTEST_ASSERT_NOTHROW(expr, DT_REQUIRE_NOTHROW) - -// clang-format off -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS(expr); } while((void)0, 0) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS(expr); } while((void)0, 0) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS(expr); } while((void)0, 0) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_THROWS_AS(expr, ex); } while((void)0, 0) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_THROWS_AS(expr, ex); } while((void)0, 0) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_THROWS_AS(expr, ex); } while((void)0, 0) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_WARN_NOTHROW(expr); } while((void)0, 0) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_CHECK_NOTHROW(expr); } while((void)0, 0) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) do { DOCTEST_INFO(msg); DOCTEST_REQUIRE_NOTHROW(expr); } while((void)0, 0) -// clang-format on - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_BINARY_ASSERT(assert_type, expr, comp) \ - do { \ - doctest::detail::ResultBuilder _DOCTEST_RB( \ - doctest::detail::assertType::assert_type, __FILE__, __LINE__, \ - DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(expr))); \ - DOCTEST_WRAP_IN_TRY( \ - _DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>( \ - DOCTEST_HANDLE_BRACED_VA_ARGS(expr))) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } while((void)0, 0) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_BINARY_ASSERT(assert_type, lhs, rhs, comp) \ - do { \ - doctest::detail::ResultBuilder _DOCTEST_RB(doctest::detail::assertType::assert_type, \ - __FILE__, __LINE__, #lhs ", " #rhs); \ - DOCTEST_WRAP_IN_TRY( \ - _DOCTEST_RB.binary_assert<doctest::detail::binaryAssertComparison::comp>(lhs, \ - rhs)) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } while((void)0, 0) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#define DOCTEST_UNARY_ASSERT(assert_type, expr) \ - do { \ - doctest::detail::ResultBuilder _DOCTEST_RB( \ - doctest::detail::assertType::assert_type, __FILE__, __LINE__, \ - DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(expr))); \ - DOCTEST_WRAP_IN_TRY(_DOCTEST_RB.unary_assert(DOCTEST_HANDLE_BRACED_VA_ARGS(expr))) \ - DOCTEST_ASSERT_LOG_AND_REACT(_DOCTEST_RB); \ - } while((void)0, 0) - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_EQ(...) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, (__VA_ARGS__), eq) -#define DOCTEST_CHECK_EQ(...) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, (__VA_ARGS__), eq) -#define DOCTEST_REQUIRE_EQ(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, (__VA_ARGS__), eq) -#define DOCTEST_WARN_NE(...) DOCTEST_BINARY_ASSERT(DT_WARN_NE, (__VA_ARGS__), ne) -#define DOCTEST_CHECK_NE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, (__VA_ARGS__), ne) -#define DOCTEST_REQUIRE_NE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, (__VA_ARGS__), ne) -#define DOCTEST_WARN_GT(...) DOCTEST_BINARY_ASSERT(DT_WARN_GT, (__VA_ARGS__), gt) -#define DOCTEST_CHECK_GT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, (__VA_ARGS__), gt) -#define DOCTEST_REQUIRE_GT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, (__VA_ARGS__), gt) -#define DOCTEST_WARN_LT(...) DOCTEST_BINARY_ASSERT(DT_WARN_LT, (__VA_ARGS__), lt) -#define DOCTEST_CHECK_LT(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, (__VA_ARGS__), lt) -#define DOCTEST_REQUIRE_LT(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, (__VA_ARGS__), lt) -#define DOCTEST_WARN_GE(...) DOCTEST_BINARY_ASSERT(DT_WARN_GE, (__VA_ARGS__), ge) -#define DOCTEST_CHECK_GE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, (__VA_ARGS__), ge) -#define DOCTEST_REQUIRE_GE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, (__VA_ARGS__), ge) -#define DOCTEST_WARN_LE(...) DOCTEST_BINARY_ASSERT(DT_WARN_LE, (__VA_ARGS__), le) -#define DOCTEST_CHECK_LE(...) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, (__VA_ARGS__), le) -#define DOCTEST_REQUIRE_LE(...) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, (__VA_ARGS__), le) - -#define DOCTEST_WARN_UNARY(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, (__VA_ARGS__)) -#define DOCTEST_CHECK_UNARY(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, (__VA_ARGS__)) -#define DOCTEST_REQUIRE_UNARY(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, (__VA_ARGS__)) -#define DOCTEST_WARN_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, (__VA_ARGS__)) -#define DOCTEST_CHECK_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, (__VA_ARGS__)) -#define DOCTEST_REQUIRE_UNARY_FALSE(...) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, (__VA_ARGS__)) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_EQ(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_EQ, lhs, rhs, eq) -#define DOCTEST_CHECK_EQ(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_EQ, lhs, rhs, eq) -#define DOCTEST_REQUIRE_EQ(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_EQ, lhs, rhs, eq) -#define DOCTEST_WARN_NE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_NE, lhs, rhs, ne) -#define DOCTEST_CHECK_NE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_NE, lhs, rhs, ne) -#define DOCTEST_REQUIRE_NE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_NE, lhs, rhs, ne) -#define DOCTEST_WARN_GT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_GT, lhs, rhs, gt) -#define DOCTEST_CHECK_GT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_GT, lhs, rhs, gt) -#define DOCTEST_REQUIRE_GT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GT, lhs, rhs, gt) -#define DOCTEST_WARN_LT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_LT, lhs, rhs, lt) -#define DOCTEST_CHECK_LT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_LT, lhs, rhs, lt) -#define DOCTEST_REQUIRE_LT(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LT, lhs, rhs, lt) -#define DOCTEST_WARN_GE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_GE, lhs, rhs, ge) -#define DOCTEST_CHECK_GE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_GE, lhs, rhs, ge) -#define DOCTEST_REQUIRE_GE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_GE, lhs, rhs, ge) -#define DOCTEST_WARN_LE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_WARN_LE, lhs, rhs, le) -#define DOCTEST_CHECK_LE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_CHECK_LE, lhs, rhs, le) -#define DOCTEST_REQUIRE_LE(lhs, rhs) DOCTEST_BINARY_ASSERT(DT_REQUIRE_LE, lhs, rhs, le) - -#define DOCTEST_WARN_UNARY(v) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY, v) -#define DOCTEST_CHECK_UNARY(v) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY, v) -#define DOCTEST_REQUIRE_UNARY(v) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY, v) -#define DOCTEST_WARN_UNARY_FALSE(v) DOCTEST_UNARY_ASSERT(DT_WARN_UNARY_FALSE, v) -#define DOCTEST_CHECK_UNARY_FALSE(v) DOCTEST_UNARY_ASSERT(DT_CHECK_UNARY_FALSE, v) -#define DOCTEST_REQUIRE_UNARY_FALSE(v) DOCTEST_UNARY_ASSERT(DT_REQUIRE_UNARY_FALSE, v) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#ifndef DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_FAST_BINARY_ASSERT(assert_type, expr, comparison) \ - do { \ - int _DOCTEST_FAST_RES = doctest::detail::fast_binary_assert< \ - doctest::detail::binaryAssertComparison::comparison>( \ - doctest::detail::assertType::assert_type, __FILE__, __LINE__, \ - DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(expr)), \ - DOCTEST_HANDLE_BRACED_VA_ARGS(expr)); \ - if(_DOCTEST_FAST_RES & doctest::detail::assertAction::dbgbreak) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - doctest::detail::fastAssertThrowIfFlagSet(_DOCTEST_FAST_RES); \ - } while((void)0, 0) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_FAST_BINARY_ASSERT(assert_type, lhs, rhs, comparison) \ - do { \ - int _DOCTEST_FAST_RES = doctest::detail::fast_binary_assert< \ - doctest::detail::binaryAssertComparison::comparison>( \ - doctest::detail::assertType::assert_type, __FILE__, __LINE__, #lhs ", " #rhs, lhs, \ - rhs); \ - if(_DOCTEST_FAST_RES & doctest::detail::assertAction::dbgbreak) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - doctest::detail::fastAssertThrowIfFlagSet(_DOCTEST_FAST_RES); \ - } while((void)0, 0) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#define DOCTEST_FAST_UNARY_ASSERT(assert_type, expr) \ - do { \ - int _DOCTEST_FAST_RES = doctest::detail::fast_unary_assert( \ - doctest::detail::assertType::assert_type, __FILE__, __LINE__, \ - DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(expr)), \ - DOCTEST_HANDLE_BRACED_VA_ARGS(expr)); \ - if(_DOCTEST_FAST_RES & doctest::detail::assertAction::dbgbreak) \ - DOCTEST_BREAK_INTO_DEBUGGER(); \ - doctest::detail::fastAssertThrowIfFlagSet(_DOCTEST_FAST_RES); \ - } while((void)0, 0) - -#else // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_FAST_BINARY_ASSERT(assert_type, expr, comparison) \ - doctest::detail::fast_binary_assert<doctest::detail::binaryAssertComparison::comparison>( \ - doctest::detail::assertType::assert_type, __FILE__, __LINE__, \ - DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(expr)), \ - DOCTEST_HANDLE_BRACED_VA_ARGS(expr)) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_FAST_BINARY_ASSERT(assert_type, lhs, rhs, comparison) \ - doctest::detail::fast_binary_assert<doctest::detail::binaryAssertComparison::comparison>( \ - doctest::detail::assertType::assert_type, __FILE__, __LINE__, #lhs ", " #rhs, lhs, \ - rhs) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#define DOCTEST_FAST_UNARY_ASSERT(assert_type, expr) \ - doctest::detail::fast_unary_assert(doctest::detail::assertType::assert_type, __FILE__, \ - __LINE__, \ - DOCTEST_TOSTR(DOCTEST_HANDLE_BRACED_VA_ARGS(expr)), \ - DOCTEST_HANDLE_BRACED_VA_ARGS(expr)) - -#endif // DOCTEST_CONFIG_SUPER_FAST_ASSERTS - -// clang-format off -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_FAST_WARN_EQ(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_EQ, (__VA_ARGS__), eq) -#define DOCTEST_FAST_CHECK_EQ(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_EQ, (__VA_ARGS__), eq) -#define DOCTEST_FAST_REQUIRE_EQ(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_EQ, (__VA_ARGS__), eq) -#define DOCTEST_FAST_WARN_NE(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_NE, (__VA_ARGS__), ne) -#define DOCTEST_FAST_CHECK_NE(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_NE, (__VA_ARGS__), ne) -#define DOCTEST_FAST_REQUIRE_NE(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_NE, (__VA_ARGS__), ne) -#define DOCTEST_FAST_WARN_GT(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_GT, (__VA_ARGS__), gt) -#define DOCTEST_FAST_CHECK_GT(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_GT, (__VA_ARGS__), gt) -#define DOCTEST_FAST_REQUIRE_GT(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_GT, (__VA_ARGS__), gt) -#define DOCTEST_FAST_WARN_LT(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_LT, (__VA_ARGS__), lt) -#define DOCTEST_FAST_CHECK_LT(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_LT, (__VA_ARGS__), lt) -#define DOCTEST_FAST_REQUIRE_LT(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_LT, (__VA_ARGS__), lt) -#define DOCTEST_FAST_WARN_GE(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_GE, (__VA_ARGS__), ge) -#define DOCTEST_FAST_CHECK_GE(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_GE, (__VA_ARGS__), ge) -#define DOCTEST_FAST_REQUIRE_GE(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_GE, (__VA_ARGS__), ge) -#define DOCTEST_FAST_WARN_LE(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_LE, (__VA_ARGS__), le) -#define DOCTEST_FAST_CHECK_LE(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_LE, (__VA_ARGS__), le) -#define DOCTEST_FAST_REQUIRE_LE(...) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_LE, (__VA_ARGS__), le) - -#define DOCTEST_FAST_WARN_UNARY(...) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_WARN_UNARY, (__VA_ARGS__)) -#define DOCTEST_FAST_CHECK_UNARY(...) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_CHECK_UNARY, (__VA_ARGS__)) -#define DOCTEST_FAST_REQUIRE_UNARY(...) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_REQUIRE_UNARY, (__VA_ARGS__)) -#define DOCTEST_FAST_WARN_UNARY_FALSE(...) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_WARN_UNARY_FALSE, (__VA_ARGS__)) -#define DOCTEST_FAST_CHECK_UNARY_FALSE(...) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_CHECK_UNARY_FALSE, (__VA_ARGS__)) -#define DOCTEST_FAST_REQUIRE_UNARY_FALSE(...) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_REQUIRE_UNARY_FALSE, (__VA_ARGS__)) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_FAST_WARN_EQ(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_EQ, l, r, eq) -#define DOCTEST_FAST_CHECK_EQ(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_EQ, l, r, eq) -#define DOCTEST_FAST_REQUIRE_EQ(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_EQ, l, r, eq) -#define DOCTEST_FAST_WARN_NE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_NE, l, r, ne) -#define DOCTEST_FAST_CHECK_NE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_NE, l, r, ne) -#define DOCTEST_FAST_REQUIRE_NE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_NE, l, r, ne) -#define DOCTEST_FAST_WARN_GT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_GT, l, r, gt) -#define DOCTEST_FAST_CHECK_GT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_GT, l, r, gt) -#define DOCTEST_FAST_REQUIRE_GT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_GT, l, r, gt) -#define DOCTEST_FAST_WARN_LT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_LT, l, r, lt) -#define DOCTEST_FAST_CHECK_LT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_LT, l, r, lt) -#define DOCTEST_FAST_REQUIRE_LT(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_LT, l, r, lt) -#define DOCTEST_FAST_WARN_GE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_GE, l, r, ge) -#define DOCTEST_FAST_CHECK_GE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_GE, l, r, ge) -#define DOCTEST_FAST_REQUIRE_GE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_GE, l, r, ge) -#define DOCTEST_FAST_WARN_LE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_WARN_LE, l, r, le) -#define DOCTEST_FAST_CHECK_LE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_CHECK_LE, l, r, le) -#define DOCTEST_FAST_REQUIRE_LE(l, r) DOCTEST_FAST_BINARY_ASSERT(DT_FAST_REQUIRE_LE, l, r, le) - -#define DOCTEST_FAST_WARN_UNARY(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_WARN_UNARY, v) -#define DOCTEST_FAST_CHECK_UNARY(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_CHECK_UNARY, v) -#define DOCTEST_FAST_REQUIRE_UNARY(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_REQUIRE_UNARY, v) -#define DOCTEST_FAST_WARN_UNARY_FALSE(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_WARN_UNARY_FALSE, v) -#define DOCTEST_FAST_CHECK_UNARY_FALSE(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_CHECK_UNARY_FALSE, v) -#define DOCTEST_FAST_REQUIRE_UNARY_FALSE(v) DOCTEST_FAST_UNARY_ASSERT(DT_FAST_REQUIRE_UNARY_FALSE, v) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -// clang-format on - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS - -#undef DOCTEST_WARN_THROWS -#undef DOCTEST_CHECK_THROWS -#undef DOCTEST_REQUIRE_THROWS -#undef DOCTEST_WARN_THROWS_AS -#undef DOCTEST_CHECK_THROWS_AS -#undef DOCTEST_REQUIRE_THROWS_AS -#undef DOCTEST_WARN_NOTHROW -#undef DOCTEST_CHECK_NOTHROW -#undef DOCTEST_REQUIRE_NOTHROW - -#undef DOCTEST_WARN_THROWS_MESSAGE -#undef DOCTEST_CHECK_THROWS_MESSAGE -#undef DOCTEST_REQUIRE_THROWS_MESSAGE -#undef DOCTEST_WARN_THROWS_AS_MESSAGE -#undef DOCTEST_CHECK_THROWS_AS_MESSAGE -#undef DOCTEST_REQUIRE_THROWS_AS_MESSAGE -#undef DOCTEST_WARN_NOTHROW_MESSAGE -#undef DOCTEST_CHECK_NOTHROW_MESSAGE -#undef DOCTEST_REQUIRE_NOTHROW_MESSAGE - -#ifdef DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#define DOCTEST_WARN_THROWS(expr) ((void)0) -#define DOCTEST_CHECK_THROWS(expr) ((void)0) -#define DOCTEST_REQUIRE_THROWS(expr) ((void)0) -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_THROWS_AS(expr, ex) ((void)0) -#define DOCTEST_CHECK_THROWS_AS(expr, ex) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ex) ((void)0) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_NOTHROW(expr) ((void)0) -#define DOCTEST_CHECK_NOTHROW(expr) ((void)0) -#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0) - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0) - -#else // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#undef DOCTEST_REQUIRE -#undef DOCTEST_REQUIRE_FALSE -#undef DOCTEST_REQUIRE_MESSAGE -#undef DOCTEST_REQUIRE_FALSE_MESSAGE -#undef DOCTEST_REQUIRE_EQ -#undef DOCTEST_REQUIRE_NE -#undef DOCTEST_REQUIRE_GT -#undef DOCTEST_REQUIRE_LT -#undef DOCTEST_REQUIRE_GE -#undef DOCTEST_REQUIRE_LE -#undef DOCTEST_REQUIRE_UNARY -#undef DOCTEST_REQUIRE_UNARY_FALSE -#undef DOCTEST_FAST_REQUIRE_EQ -#undef DOCTEST_FAST_REQUIRE_NE -#undef DOCTEST_FAST_REQUIRE_GT -#undef DOCTEST_FAST_REQUIRE_LT -#undef DOCTEST_FAST_REQUIRE_GE -#undef DOCTEST_FAST_REQUIRE_LE -#undef DOCTEST_FAST_REQUIRE_UNARY -#undef DOCTEST_FAST_REQUIRE_UNARY_FALSE - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS_BUT_WITH_ALL_ASSERTS - -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - -// ================================================================================================= -// == WHAT FOLLOWS IS VERSIONS OF THE MACROS THAT DO NOT DO ANY REGISTERING! == -// == THIS CAN BE ENABLED BY DEFINING DOCTEST_CONFIG_DISABLE GLOBALLY! == -// ================================================================================================= -#else // DOCTEST_CONFIG_DISABLE - -#define DOCTEST_IMPLEMENT_FIXTURE(der, base, func, name) \ - namespace \ - { \ - template <typename T> \ - struct der : base \ - { void f(); }; \ - } \ - template <typename T> \ - inline void der<T>::f() - -#define DOCTEST_CREATE_AND_REGISTER_FUNCTION(f, name) \ - template <typename T> \ - static inline void f() - -// for registering tests -#define DOCTEST_TEST_CASE(name) \ - DOCTEST_CREATE_AND_REGISTER_FUNCTION(DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) - -// for registering tests with a fixture -#define DOCTEST_TEST_CASE_FIXTURE(x, name) \ - DOCTEST_IMPLEMENT_FIXTURE(DOCTEST_ANONYMOUS(_DOCTEST_ANON_CLASS_), x, \ - DOCTEST_ANONYMOUS(_DOCTEST_ANON_FUNC_), name) - -// for converting types to strings without the <typeinfo> header and demangling -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TYPE_TO_STRING(...) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) -#define DOCTEST_TYPE_TO_STRING_IMPL(...) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_TYPE_TO_STRING(x) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) -#define DOCTEST_TYPE_TO_STRING_IMPL(x) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -// for typed tests -#define DOCTEST_TEST_CASE_TEMPLATE(name, type, types) \ - template <typename type> \ - inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)() - -#define DOCTEST_TEST_CASE_TEMPLATE_DEFINE(name, type, id) \ - template <typename type> \ - inline void DOCTEST_ANONYMOUS(_DOCTEST_ANON_TMP_)() - -#define DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE(id, types) \ - typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for subcases -#define DOCTEST_SUBCASE(name) - -// for a testsuite block -#define DOCTEST_TEST_SUITE(name) namespace - -// for starting a testsuite block -#define DOCTEST_TEST_SUITE_BEGIN(name) typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -// for ending a testsuite block -#define DOCTEST_TEST_SUITE_END typedef int DOCTEST_ANONYMOUS(_DOCTEST_ANON_FOR_SEMICOLON_) - -#define DOCTEST_REGISTER_EXCEPTION_TRANSLATOR(signature) \ - template <typename T> \ - static inline doctest::String DOCTEST_ANONYMOUS(_DOCTEST_ANON_TRANSLATOR_)(signature) - -#define DOCTEST_INFO(x) ((void)0) -#define DOCTEST_CAPTURE(x) ((void)0) -#define DOCTEST_ADD_MESSAGE_AT(file, line, x) ((void)0) -#define DOCTEST_ADD_FAIL_CHECK_AT(file, line, x) ((void)0) -#define DOCTEST_ADD_FAIL_AT(file, line, x) ((void)0) -#define DOCTEST_MESSAGE(x) ((void)0) -#define DOCTEST_FAIL_CHECK(x) ((void)0) -#define DOCTEST_FAIL(x) ((void)0) - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN(...) ((void)0) -#define DOCTEST_CHECK(...) ((void)0) -#define DOCTEST_REQUIRE(...) ((void)0) -#define DOCTEST_WARN_FALSE(...) ((void)0) -#define DOCTEST_CHECK_FALSE(...) ((void)0) -#define DOCTEST_REQUIRE_FALSE(...) ((void)0) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN(expr) ((void)0) -#define DOCTEST_CHECK(expr) ((void)0) -#define DOCTEST_REQUIRE(expr) ((void)0) -#define DOCTEST_WARN_FALSE(expr) ((void)0) -#define DOCTEST_CHECK_FALSE(expr) ((void)0) -#define DOCTEST_REQUIRE_FALSE(expr) ((void)0) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#define DOCTEST_WARN_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_CHECK_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_REQUIRE_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_WARN_FALSE_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_CHECK_FALSE_MESSAGE(cond, msg) ((void)0) -#define DOCTEST_REQUIRE_FALSE_MESSAGE(cond, msg) ((void)0) - -#define DOCTEST_WARN_THROWS(expr) ((void)0) -#define DOCTEST_CHECK_THROWS(expr) ((void)0) -#define DOCTEST_REQUIRE_THROWS(expr) ((void)0) -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_CHECK_THROWS_AS(expr, ...) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ...) ((void)0) -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_THROWS_AS(expr, ex) ((void)0) -#define DOCTEST_CHECK_THROWS_AS(expr, ex) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS(expr, ex) ((void)0) -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS -#define DOCTEST_WARN_NOTHROW(expr) ((void)0) -#define DOCTEST_CHECK_NOTHROW(expr) ((void)0) -#define DOCTEST_REQUIRE_NOTHROW(expr) ((void)0) - -#define DOCTEST_WARN_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_WARN_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_CHECK_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_REQUIRE_THROWS_AS_MESSAGE(expr, ex, msg) ((void)0) -#define DOCTEST_WARN_NOTHROW_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_CHECK_NOTHROW_MESSAGE(expr, msg) ((void)0) -#define DOCTEST_REQUIRE_NOTHROW_MESSAGE(expr, msg) ((void)0) - -#ifdef DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#define DOCTEST_WARN_EQ(...) ((void)0) -#define DOCTEST_CHECK_EQ(...) ((void)0) -#define DOCTEST_REQUIRE_EQ(...) ((void)0) -#define DOCTEST_WARN_NE(...) ((void)0) -#define DOCTEST_CHECK_NE(...) ((void)0) -#define DOCTEST_REQUIRE_NE(...) ((void)0) -#define DOCTEST_WARN_GT(...) ((void)0) -#define DOCTEST_CHECK_GT(...) ((void)0) -#define DOCTEST_REQUIRE_GT(...) ((void)0) -#define DOCTEST_WARN_LT(...) ((void)0) -#define DOCTEST_CHECK_LT(...) ((void)0) -#define DOCTEST_REQUIRE_LT(...) ((void)0) -#define DOCTEST_WARN_GE(...) ((void)0) -#define DOCTEST_CHECK_GE(...) ((void)0) -#define DOCTEST_REQUIRE_GE(...) ((void)0) -#define DOCTEST_WARN_LE(...) ((void)0) -#define DOCTEST_CHECK_LE(...) ((void)0) -#define DOCTEST_REQUIRE_LE(...) ((void)0) - -#define DOCTEST_WARN_UNARY(...) ((void)0) -#define DOCTEST_CHECK_UNARY(...) ((void)0) -#define DOCTEST_REQUIRE_UNARY(...) ((void)0) -#define DOCTEST_WARN_UNARY_FALSE(...) ((void)0) -#define DOCTEST_CHECK_UNARY_FALSE(...) ((void)0) -#define DOCTEST_REQUIRE_UNARY_FALSE(...) ((void)0) - -#define DOCTEST_FAST_WARN_EQ(...) ((void)0) -#define DOCTEST_FAST_CHECK_EQ(...) ((void)0) -#define DOCTEST_FAST_REQUIRE_EQ(...) ((void)0) -#define DOCTEST_FAST_WARN_NE(...) ((void)0) -#define DOCTEST_FAST_CHECK_NE(...) ((void)0) -#define DOCTEST_FAST_REQUIRE_NE(...) ((void)0) -#define DOCTEST_FAST_WARN_GT(...) ((void)0) -#define DOCTEST_FAST_CHECK_GT(...) ((void)0) -#define DOCTEST_FAST_REQUIRE_GT(...) ((void)0) -#define DOCTEST_FAST_WARN_LT(...) ((void)0) -#define DOCTEST_FAST_CHECK_LT(...) ((void)0) -#define DOCTEST_FAST_REQUIRE_LT(...) ((void)0) -#define DOCTEST_FAST_WARN_GE(...) ((void)0) -#define DOCTEST_FAST_CHECK_GE(...) ((void)0) -#define DOCTEST_FAST_REQUIRE_GE(...) ((void)0) -#define DOCTEST_FAST_WARN_LE(...) ((void)0) -#define DOCTEST_FAST_CHECK_LE(...) ((void)0) -#define DOCTEST_FAST_REQUIRE_LE(...) ((void)0) - -#define DOCTEST_FAST_WARN_UNARY(...) ((void)0) -#define DOCTEST_FAST_CHECK_UNARY(...) ((void)0) -#define DOCTEST_FAST_REQUIRE_UNARY(...) ((void)0) -#define DOCTEST_FAST_WARN_UNARY_FALSE(...) ((void)0) -#define DOCTEST_FAST_CHECK_UNARY_FALSE(...) ((void)0) -#define DOCTEST_FAST_REQUIRE_UNARY_FALSE(...) ((void)0) - -#else // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#define DOCTEST_WARN_EQ(lhs, rhs) ((void)0) -#define DOCTEST_CHECK_EQ(lhs, rhs) ((void)0) -#define DOCTEST_REQUIRE_EQ(lhs, rhs) ((void)0) -#define DOCTEST_WARN_NE(lhs, rhs) ((void)0) -#define DOCTEST_CHECK_NE(lhs, rhs) ((void)0) -#define DOCTEST_REQUIRE_NE(lhs, rhs) ((void)0) -#define DOCTEST_WARN_GT(lhs, rhs) ((void)0) -#define DOCTEST_CHECK_GT(lhs, rhs) ((void)0) -#define DOCTEST_REQUIRE_GT(lhs, rhs) ((void)0) -#define DOCTEST_WARN_LT(lhs, rhs) ((void)0) -#define DOCTEST_CHECK_LT(lhs, rhs) ((void)0) -#define DOCTEST_REQUIRE_LT(lhs, rhs) ((void)0) -#define DOCTEST_WARN_GE(lhs, rhs) ((void)0) -#define DOCTEST_CHECK_GE(lhs, rhs) ((void)0) -#define DOCTEST_REQUIRE_GE(lhs, rhs) ((void)0) -#define DOCTEST_WARN_LE(lhs, rhs) ((void)0) -#define DOCTEST_CHECK_LE(lhs, rhs) ((void)0) -#define DOCTEST_REQUIRE_LE(lhs, rhs) ((void)0) - -#define DOCTEST_WARN_UNARY(val) ((void)0) -#define DOCTEST_CHECK_UNARY(val) ((void)0) -#define DOCTEST_REQUIRE_UNARY(val) ((void)0) -#define DOCTEST_WARN_UNARY_FALSE(val) ((void)0) -#define DOCTEST_CHECK_UNARY_FALSE(val) ((void)0) -#define DOCTEST_REQUIRE_UNARY_FALSE(val) ((void)0) - -#define DOCTEST_FAST_WARN_EQ(lhs, rhs) ((void)0) -#define DOCTEST_FAST_CHECK_EQ(lhs, rhs) ((void)0) -#define DOCTEST_FAST_REQUIRE_EQ(lhs, rhs) ((void)0) -#define DOCTEST_FAST_WARN_NE(lhs, rhs) ((void)0) -#define DOCTEST_FAST_CHECK_NE(lhs, rhs) ((void)0) -#define DOCTEST_FAST_REQUIRE_NE(lhs, rhs) ((void)0) -#define DOCTEST_FAST_WARN_GT(lhs, rhs) ((void)0) -#define DOCTEST_FAST_CHECK_GT(lhs, rhs) ((void)0) -#define DOCTEST_FAST_REQUIRE_GT(lhs, rhs) ((void)0) -#define DOCTEST_FAST_WARN_LT(lhs, rhs) ((void)0) -#define DOCTEST_FAST_CHECK_LT(lhs, rhs) ((void)0) -#define DOCTEST_FAST_REQUIRE_LT(lhs, rhs) ((void)0) -#define DOCTEST_FAST_WARN_GE(lhs, rhs) ((void)0) -#define DOCTEST_FAST_CHECK_GE(lhs, rhs) ((void)0) -#define DOCTEST_FAST_REQUIRE_GE(lhs, rhs) ((void)0) -#define DOCTEST_FAST_WARN_LE(lhs, rhs) ((void)0) -#define DOCTEST_FAST_CHECK_LE(lhs, rhs) ((void)0) -#define DOCTEST_FAST_REQUIRE_LE(lhs, rhs) ((void)0) - -#define DOCTEST_FAST_WARN_UNARY(val) ((void)0) -#define DOCTEST_FAST_CHECK_UNARY(val) ((void)0) -#define DOCTEST_FAST_REQUIRE_UNARY(val) ((void)0) -#define DOCTEST_FAST_WARN_UNARY_FALSE(val) ((void)0) -#define DOCTEST_FAST_CHECK_UNARY_FALSE(val) ((void)0) -#define DOCTEST_FAST_REQUIRE_UNARY_FALSE(val) ((void)0) - -#endif // DOCTEST_CONFIG_WITH_VARIADIC_MACROS - -#endif // DOCTEST_CONFIG_DISABLE - -// BDD style macros -// clang-format off -#define DOCTEST_SCENARIO(name) TEST_CASE(" Scenario: " name) -#define DOCTEST_GIVEN(name) SUBCASE(" Given: " name) -#define DOCTEST_WHEN(name) SUBCASE(" When: " name) -#define DOCTEST_AND_WHEN(name) SUBCASE("And when: " name) -#define DOCTEST_THEN(name) SUBCASE(" Then: " name) -#define DOCTEST_AND_THEN(name) SUBCASE(" And: " name) -// clang-format on - -// == SHORT VERSIONS OF THE MACROS -#if !defined(DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES) - -#define TEST_CASE DOCTEST_TEST_CASE -#define TEST_CASE_FIXTURE DOCTEST_TEST_CASE_FIXTURE -#define TYPE_TO_STRING DOCTEST_TYPE_TO_STRING -#define TEST_CASE_TEMPLATE DOCTEST_TEST_CASE_TEMPLATE -#define TEST_CASE_TEMPLATE_DEFINE DOCTEST_TEST_CASE_TEMPLATE_DEFINE -#define TEST_CASE_TEMPLATE_INSTANTIATE DOCTEST_TEST_CASE_TEMPLATE_INSTANTIATE -#define SUBCASE DOCTEST_SUBCASE -#define TEST_SUITE DOCTEST_TEST_SUITE -#define TEST_SUITE_BEGIN DOCTEST_TEST_SUITE_BEGIN -#define TEST_SUITE_END DOCTEST_TEST_SUITE_END -#define REGISTER_EXCEPTION_TRANSLATOR DOCTEST_REGISTER_EXCEPTION_TRANSLATOR -#define INFO DOCTEST_INFO -#define CAPTURE DOCTEST_CAPTURE -#define ADD_MESSAGE_AT DOCTEST_ADD_MESSAGE_AT -#define ADD_FAIL_CHECK_AT DOCTEST_ADD_FAIL_CHECK_AT -#define ADD_FAIL_AT DOCTEST_ADD_FAIL_AT -#define MESSAGE DOCTEST_MESSAGE -#define FAIL_CHECK DOCTEST_FAIL_CHECK -#define FAIL DOCTEST_FAIL -#define TO_LVALUE DOCTEST_TO_LVALUE - -#define WARN DOCTEST_WARN -#define WARN_FALSE DOCTEST_WARN_FALSE -#define WARN_THROWS DOCTEST_WARN_THROWS -#define WARN_THROWS_AS DOCTEST_WARN_THROWS_AS -#define WARN_NOTHROW DOCTEST_WARN_NOTHROW -#define CHECK DOCTEST_CHECK -#define CHECK_FALSE DOCTEST_CHECK_FALSE -#define CHECK_THROWS DOCTEST_CHECK_THROWS -#define CHECK_THROWS_AS DOCTEST_CHECK_THROWS_AS -#define CHECK_NOTHROW DOCTEST_CHECK_NOTHROW -#define REQUIRE DOCTEST_REQUIRE -#define REQUIRE_FALSE DOCTEST_REQUIRE_FALSE -#define REQUIRE_THROWS DOCTEST_REQUIRE_THROWS -#define REQUIRE_THROWS_AS DOCTEST_REQUIRE_THROWS_AS -#define REQUIRE_NOTHROW DOCTEST_REQUIRE_NOTHROW - -#define WARN_MESSAGE DOCTEST_WARN_MESSAGE -#define WARN_FALSE_MESSAGE DOCTEST_WARN_FALSE_MESSAGE -#define WARN_THROWS_MESSAGE DOCTEST_WARN_THROWS_MESSAGE -#define WARN_THROWS_AS_MESSAGE DOCTEST_WARN_THROWS_AS_MESSAGE -#define WARN_NOTHROW_MESSAGE DOCTEST_WARN_NOTHROW_MESSAGE -#define CHECK_MESSAGE DOCTEST_CHECK_MESSAGE -#define CHECK_FALSE_MESSAGE DOCTEST_CHECK_FALSE_MESSAGE -#define CHECK_THROWS_MESSAGE DOCTEST_CHECK_THROWS_MESSAGE -#define CHECK_THROWS_AS_MESSAGE DOCTEST_CHECK_THROWS_AS_MESSAGE -#define CHECK_NOTHROW_MESSAGE DOCTEST_CHECK_NOTHROW_MESSAGE -#define REQUIRE_MESSAGE DOCTEST_REQUIRE_MESSAGE -#define REQUIRE_FALSE_MESSAGE DOCTEST_REQUIRE_FALSE_MESSAGE -#define REQUIRE_THROWS_MESSAGE DOCTEST_REQUIRE_THROWS_MESSAGE -#define REQUIRE_THROWS_AS_MESSAGE DOCTEST_REQUIRE_THROWS_AS_MESSAGE -#define REQUIRE_NOTHROW_MESSAGE DOCTEST_REQUIRE_NOTHROW_MESSAGE - -#define SCENARIO DOCTEST_SCENARIO -#define GIVEN DOCTEST_GIVEN -#define WHEN DOCTEST_WHEN -#define AND_WHEN DOCTEST_AND_WHEN -#define THEN DOCTEST_THEN -#define AND_THEN DOCTEST_AND_THEN - -#define WARN_EQ DOCTEST_WARN_EQ -#define CHECK_EQ DOCTEST_CHECK_EQ -#define REQUIRE_EQ DOCTEST_REQUIRE_EQ -#define WARN_NE DOCTEST_WARN_NE -#define CHECK_NE DOCTEST_CHECK_NE -#define REQUIRE_NE DOCTEST_REQUIRE_NE -#define WARN_GT DOCTEST_WARN_GT -#define CHECK_GT DOCTEST_CHECK_GT -#define REQUIRE_GT DOCTEST_REQUIRE_GT -#define WARN_LT DOCTEST_WARN_LT -#define CHECK_LT DOCTEST_CHECK_LT -#define REQUIRE_LT DOCTEST_REQUIRE_LT -#define WARN_GE DOCTEST_WARN_GE -#define CHECK_GE DOCTEST_CHECK_GE -#define REQUIRE_GE DOCTEST_REQUIRE_GE -#define WARN_LE DOCTEST_WARN_LE -#define CHECK_LE DOCTEST_CHECK_LE -#define REQUIRE_LE DOCTEST_REQUIRE_LE -#define WARN_UNARY DOCTEST_WARN_UNARY -#define CHECK_UNARY DOCTEST_CHECK_UNARY -#define REQUIRE_UNARY DOCTEST_REQUIRE_UNARY -#define WARN_UNARY_FALSE DOCTEST_WARN_UNARY_FALSE -#define CHECK_UNARY_FALSE DOCTEST_CHECK_UNARY_FALSE -#define REQUIRE_UNARY_FALSE DOCTEST_REQUIRE_UNARY_FALSE - -#define FAST_WARN_EQ DOCTEST_FAST_WARN_EQ -#define FAST_CHECK_EQ DOCTEST_FAST_CHECK_EQ -#define FAST_REQUIRE_EQ DOCTEST_FAST_REQUIRE_EQ -#define FAST_WARN_NE DOCTEST_FAST_WARN_NE -#define FAST_CHECK_NE DOCTEST_FAST_CHECK_NE -#define FAST_REQUIRE_NE DOCTEST_FAST_REQUIRE_NE -#define FAST_WARN_GT DOCTEST_FAST_WARN_GT -#define FAST_CHECK_GT DOCTEST_FAST_CHECK_GT -#define FAST_REQUIRE_GT DOCTEST_FAST_REQUIRE_GT -#define FAST_WARN_LT DOCTEST_FAST_WARN_LT -#define FAST_CHECK_LT DOCTEST_FAST_CHECK_LT -#define FAST_REQUIRE_LT DOCTEST_FAST_REQUIRE_LT -#define FAST_WARN_GE DOCTEST_FAST_WARN_GE -#define FAST_CHECK_GE DOCTEST_FAST_CHECK_GE -#define FAST_REQUIRE_GE DOCTEST_FAST_REQUIRE_GE -#define FAST_WARN_LE DOCTEST_FAST_WARN_LE -#define FAST_CHECK_LE DOCTEST_FAST_CHECK_LE -#define FAST_REQUIRE_LE DOCTEST_FAST_REQUIRE_LE -#define FAST_WARN_UNARY DOCTEST_FAST_WARN_UNARY -#define FAST_CHECK_UNARY DOCTEST_FAST_CHECK_UNARY -#define FAST_REQUIRE_UNARY DOCTEST_FAST_REQUIRE_UNARY -#define FAST_WARN_UNARY_FALSE DOCTEST_FAST_WARN_UNARY_FALSE -#define FAST_CHECK_UNARY_FALSE DOCTEST_FAST_CHECK_UNARY_FALSE -#define FAST_REQUIRE_UNARY_FALSE DOCTEST_FAST_REQUIRE_UNARY_FALSE - -#endif // DOCTEST_CONFIG_NO_SHORT_MACRO_NAMES - -// this is here to clear the 'current test suite' for the current translation unit - at the top -DOCTEST_TEST_SUITE_END(); - -// add stringification for primitive/fundamental types -namespace doctest -{ -namespace detail -{ - DOCTEST_TYPE_TO_STRING_IMPL(bool) - DOCTEST_TYPE_TO_STRING_IMPL(float) - DOCTEST_TYPE_TO_STRING_IMPL(double) - DOCTEST_TYPE_TO_STRING_IMPL(long double) - DOCTEST_TYPE_TO_STRING_IMPL(char) - DOCTEST_TYPE_TO_STRING_IMPL(signed char) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned char) - DOCTEST_TYPE_TO_STRING_IMPL(wchar_t) - DOCTEST_TYPE_TO_STRING_IMPL(short int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned short int) - DOCTEST_TYPE_TO_STRING_IMPL(int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned int) - DOCTEST_TYPE_TO_STRING_IMPL(long int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned long int) -#ifdef DOCTEST_CONFIG_WITH_LONG_LONG - DOCTEST_TYPE_TO_STRING_IMPL(long long int) - DOCTEST_TYPE_TO_STRING_IMPL(unsigned long long int) -#endif // DOCTEST_CONFIG_WITH_LONG_LONG -} // namespace detail -} // namespace doctest - -#endif // DOCTEST_LIBRARY_INCLUDED - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif // __clang__ - -#if defined(__GNUC__) && !defined(__clang__) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) -#pragma GCC diagnostic pop -#endif // > gcc 4.6 -#endif // __GNUC__ - -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER - -#ifndef DOCTEST_SINGLE_HEADER -#define DOCTEST_SINGLE_HEADER -#endif // DOCTEST_SINGLE_HEADER - -#if defined(__clang__) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunknown-pragmas" -#pragma clang diagnostic ignored "-Wpadded" -#pragma clang diagnostic ignored "-Wglobal-constructors" -#pragma clang diagnostic ignored "-Wexit-time-destructors" -#pragma clang diagnostic ignored "-Wmissing-prototypes" -#pragma clang diagnostic ignored "-Wsign-conversion" -#pragma clang diagnostic ignored "-Wshorten-64-to-32" -#pragma clang diagnostic ignored "-Wmissing-variable-declarations" -#pragma clang diagnostic ignored "-Wswitch" -#pragma clang diagnostic ignored "-Wswitch-enum" -#pragma clang diagnostic ignored "-Wcovered-switch-default" -#pragma clang diagnostic ignored "-Wmissing-noreturn" -#pragma clang diagnostic ignored "-Wunused-local-typedef" -#pragma clang diagnostic ignored "-Wdisabled-macro-expansion" -#pragma clang diagnostic ignored "-Wmissing-braces" -#pragma clang diagnostic ignored "-Wmissing-field-initializers" -#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" -#pragma clang diagnostic ignored "-Wc++11-long-long" -#endif // __clang__ - -#if defined(__GNUC__) && !defined(__clang__) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) -#pragma GCC diagnostic push -#endif // > gcc 4.6 -#pragma GCC diagnostic ignored "-Wunknown-pragmas" -#pragma GCC diagnostic ignored "-Wconversion" -#pragma GCC diagnostic ignored "-Weffc++" -#pragma GCC diagnostic ignored "-Wsign-conversion" -#pragma GCC diagnostic ignored "-Wstrict-overflow" -#pragma GCC diagnostic ignored "-Wmissing-field-initializers" -#pragma GCC diagnostic ignored "-Wmissing-braces" -#pragma GCC diagnostic ignored "-Wmissing-declarations" -#pragma GCC diagnostic ignored "-Winline" -#pragma GCC diagnostic ignored "-Wswitch" -#pragma GCC diagnostic ignored "-Wswitch-enum" -#pragma GCC diagnostic ignored "-Wswitch-default" -#pragma GCC diagnostic ignored "-Wunsafe-loop-optimizations" -#pragma GCC diagnostic ignored "-Wlong-long" -#pragma GCC diagnostic ignored "-Wold-style-cast" -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) -#pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" -#endif // > gcc 4.6 -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 7) -#pragma GCC diagnostic ignored "-Wunused-local-typedefs" -#endif // > gcc 4.7 -#if __GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ > 3) -#pragma GCC diagnostic ignored "-Wuseless-cast" -#endif // > gcc 5.3 -#endif // __GNUC__ - -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4996) // The compiler encountered a deprecated declaration -#pragma warning(disable : 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data -#pragma warning(disable : 4706) // assignment within conditional expression -#pragma warning(disable : 4512) // 'class' : assignment operator could not be generated -#pragma warning(disable : 4127) // conditional expression is constant -#pragma warning(disable : 4530) // C++ exception handler used, but unwind semantics are not enabled -#pragma warning(disable : 4577) // 'noexcept' used with no exception handling mode specified -#endif // _MSC_VER - -#if defined(DOCTEST_CONFIG_IMPLEMENT) || !defined(DOCTEST_SINGLE_HEADER) -#ifndef DOCTEST_LIBRARY_IMPLEMENTATION -#define DOCTEST_LIBRARY_IMPLEMENTATION - -#ifndef DOCTEST_SINGLE_HEADER -#include "doctest_fwd.h" -#endif // DOCTEST_SINGLE_HEADER - -#if defined(__clang__) && defined(DOCTEST_NO_CPP11_COMPAT) -#pragma clang diagnostic ignored "-Wc++98-compat" -#pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif // __clang__ && DOCTEST_NO_CPP11_COMPAT - -// snprintf() not in the C++98 standard -#ifdef _MSC_VER -#define DOCTEST_SNPRINTF _snprintf -#else -#define DOCTEST_SNPRINTF std::snprintf -#endif - -#define DOCTEST_LOG_START() \ - do { \ - if(!contextState->hasLoggedCurrentTestStart) { \ - doctest::detail::logTestStart(*contextState->currentTest); \ - contextState->hasLoggedCurrentTestStart = true; \ - } \ - } while(false) - -// required includes - will go only in one translation unit! -#include <ctime> -#include <cmath> -// borland (Embarcadero) compiler requires math.h and not cmath - https://github.com/onqtam/doctest/pull/37 -#ifdef __BORLANDC__ -#include <math.h> -#endif // __BORLANDC__ -#include <new> -#include <cstdio> -#include <cstdlib> -#include <cstring> -#include <limits> -#include <utility> -#include <sstream> -#include <iomanip> -#include <vector> -#include <set> -#include <exception> -#include <stdexcept> -#include <csignal> -#include <cfloat> -#ifndef _MSC_VER -#include <stdint.h> -#endif // _MSC_VER - -namespace doctest -{ -namespace detail -{ - // lowers ascii letters - char tolower(const char c) { return (c >= 'A' && c <= 'Z') ? static_cast<char>(c + 32) : c; } - - template <typename T> - T my_max(const T& lhs, const T& rhs) { - return lhs > rhs ? lhs : rhs; - } - - // case insensitive strcmp - int stricmp(char const* a, char const* b) { - for(;; a++, b++) { - int d = tolower(*a) - tolower(*b); - if(d != 0 || !*a) - return d; - } - } - - void my_memcpy(void* dest, const void* src, unsigned num) { - const char* csrc = static_cast<const char*>(src); - char* cdest = static_cast<char*>(dest); - for(unsigned i = 0; i < num; ++i) - cdest[i] = csrc[i]; - } - - // not using std::strlen() because of valgrind errors when optimizations are turned on - // 'Invalid read of size 4' when the test suite len (with '\0') is not a multiple of 4 - // for details see http://stackoverflow.com/questions/35671155 - unsigned my_strlen(const char* in) { - const char* temp = in; - while(temp && *temp) - ++temp; - return unsigned(temp - in); - } - - template <typename T> - String fpToString(T value, int precision) { - std::ostringstream oss; - oss << std::setprecision(precision) << std::fixed << value; - std::string d = oss.str(); - size_t i = d.find_last_not_of('0'); - if(i != std::string::npos && i != d.size() - 1) { - if(d[i] == '.') - i++; - d = d.substr(0, i + 1); - } - return d.c_str(); - } - - struct Endianness - { - enum Arch - { - Big, - Little - }; - - static Arch which() { - union _ - { - int asInt; - char asChar[sizeof(int)]; - } u; - - u.asInt = 1; // NOLINT - return (u.asChar[sizeof(int) - 1] == 1) ? Big : Little; // NOLINT - } - }; - - String rawMemoryToString(const void* object, unsigned size) { - // Reverse order for little endian architectures - int i = 0, end = static_cast<int>(size), inc = 1; - if(Endianness::which() == Endianness::Little) { - i = end - 1; - end = inc = -1; - } - - unsigned char const* bytes = static_cast<unsigned char const*>(object); - std::ostringstream os; - os << "0x" << std::setfill('0') << std::hex; - for(; i != end; i += inc) - os << std::setw(2) << static_cast<unsigned>(bytes[i]); - return os.str().c_str(); - } - - std::ostream* createStream() { return new std::ostringstream(); } - String getStreamResult(std::ostream* in) { - return static_cast<std::ostringstream*>(in)->str().c_str(); // NOLINT - } - void freeStream(std::ostream* in) { delete in; } - -#ifndef DOCTEST_CONFIG_DISABLE - - // this holds both parameters for the command line and runtime data for tests - struct ContextState : TestAccessibleContextState //!OCLINT too many fields - { - // == parameters from the command line - - std::vector<std::vector<String> > filters; - - String order_by; // how tests should be ordered - unsigned rand_seed; // the seed for rand ordering - - unsigned first; // the first (matching) test to be executed - unsigned last; // the last (matching) test to be executed - - int abort_after; // stop tests after this many failed assertions - int subcase_filter_levels; // apply the subcase filters for the first N levels - bool case_sensitive; // if filtering should be case sensitive - bool exit; // if the program should be exited after the tests are ran/whatever - bool duration; // print the time duration of each test case - bool no_exitcode; // if the framework should return 0 as the exitcode - bool no_run; // to not run the tests at all (can be done with an "*" exclude) - bool no_version; // to not print the version of the framework - bool no_colors; // if output to the console should be colorized - bool force_colors; // forces the use of colors even when a tty cannot be detected - bool no_breaks; // to not break into the debugger - bool no_skip; // don't skip test cases which are marked to be skipped - bool no_path_in_filenames; // if the path to files should be removed from the output - bool no_line_numbers; // if source code line numbers should be omitted from the output - bool no_skipped_summary; // don't print "skipped" in the summary !!! UNDOCUMENTED !!! - - bool help; // to print the help - bool version; // to print the version - bool count; // if only the count of matching tests is to be retreived - bool list_test_cases; // to list all tests matching the filters - bool list_test_suites; // to list all suites matching the filters - - // == data for the tests being ran - - unsigned numTestsPassingFilters; - unsigned numTestSuitesPassingFilters; - unsigned numFailed; - const TestCase* currentTest; - bool hasLoggedCurrentTestStart; - int numAssertionsForCurrentTestcase; - int numAssertions; - int numFailedAssertionsForCurrentTestcase; - int numFailedAssertions; - bool hasCurrentTestFailed; - - std::vector<IContextScope*> contexts; // for logging with INFO() and friends - std::vector<std::string> exceptionalContexts; // logging from INFO() due to an exception - - // stuff for subcases - std::set<SubcaseSignature> subcasesPassed; - std::set<int> subcasesEnteredLevels; - std::vector<Subcase> subcasesStack; - int subcasesCurrentLevel; - bool subcasesHasSkipped; - - void resetRunData() { - numTestsPassingFilters = 0; - numTestSuitesPassingFilters = 0; - numFailed = 0; - numAssertions = 0; - numFailedAssertions = 0; - numFailedAssertionsForCurrentTestcase = 0; - } - - // cppcheck-suppress uninitMemberVar - ContextState() - : filters(8) // 8 different filters total - { - resetRunData(); - } - }; - - ContextState* contextState = 0; -#endif // DOCTEST_CONFIG_DISABLE -} // namespace detail - -void String::copy(const String& other) { - if(other.isOnStack()) { - detail::my_memcpy(buf, other.buf, len); - } else { - setOnHeap(); - data.size = other.data.size; - data.capacity = data.size + 1; - data.ptr = new char[data.capacity]; - detail::my_memcpy(data.ptr, other.data.ptr, data.size + 1); - } -} - -String::String(const char* in) { - unsigned in_len = detail::my_strlen(in); - if(in_len <= last) { - detail::my_memcpy(buf, in, in_len + 1); - setLast(last - in_len); - } else { - setOnHeap(); - data.size = in_len; - data.capacity = data.size + 1; - data.ptr = new char[data.capacity]; - detail::my_memcpy(data.ptr, in, in_len + 1); - } -} - -String& String::operator+=(const String& other) { - unsigned my_old_size = size(); - unsigned other_size = other.size(); - unsigned total_size = my_old_size + other_size; - if(isOnStack()) { - if(total_size < len) { - // append to the current stack space - detail::my_memcpy(buf + my_old_size, other.c_str(), other_size + 1); - setLast(last - total_size); - } else { - // alloc new chunk - char* temp = new char[total_size + 1]; - // copy current data to new location before writing in the union - detail::my_memcpy(temp, buf, my_old_size); // skip the +1 ('\0') for speed - // update data in union - setOnHeap(); - data.size = total_size; - data.capacity = data.size + 1; - data.ptr = temp; - // transfer the rest of the data - detail::my_memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } - } else { - if(data.capacity > total_size) { - // append to the current heap block - data.size = total_size; - detail::my_memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } else { - // resize - data.capacity *= 2; - if(data.capacity <= total_size) - data.capacity = total_size + 1; - // alloc new chunk - char* temp = new char[data.capacity]; - // copy current data to new location before releasing it - detail::my_memcpy(temp, data.ptr, my_old_size); // skip the +1 ('\0') for speed - // release old chunk - delete[] data.ptr; - // update the rest of the union members - data.size = total_size; - data.ptr = temp; - // transfer the rest of the data - detail::my_memcpy(data.ptr + my_old_size, other.c_str(), other_size + 1); - } - } - - return *this; -} - -#ifdef DOCTEST_CONFIG_WITH_RVALUE_REFERENCES -String::String(String&& other) { - detail::my_memcpy(buf, other.buf, len); - other.buf[0] = '\0'; - other.setLast(); -} - -String& String::operator=(String&& other) { - if(!isOnStack()) - delete[] data.ptr; - detail::my_memcpy(buf, other.buf, len); - other.buf[0] = '\0'; - other.setLast(); - return *this; -} -#endif // DOCTEST_CONFIG_WITH_RVALUE_REFERENCES - -int String::compare(const char* other, bool no_case) const { - if(no_case) - return detail::stricmp(c_str(), other); - return std::strcmp(c_str(), other); -} - -int String::compare(const String& other, bool no_case) const { - return compare(other.c_str(), no_case); -} - -std::ostream& operator<<(std::ostream& stream, const String& in) { - stream << in.c_str(); - return stream; -} - -Approx::Approx(double value) - : m_epsilon(static_cast<double>(std::numeric_limits<float>::epsilon()) * 100) - , m_scale(1.0) - , m_value(value) {} - -bool operator==(double lhs, Approx const& rhs) { - // Thanks to Richard Harris for his help refining this formula - return std::fabs(lhs - rhs.m_value) < - rhs.m_epsilon * (rhs.m_scale + detail::my_max(std::fabs(lhs), std::fabs(rhs.m_value))); -} - -String Approx::toString() const { return String("Approx( ") + doctest::toString(m_value) + " )"; } - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -String toString(char* in) { return toString(static_cast<const char*>(in)); } -String toString(const char* in) { return String("\"") + (in ? in : "{null string}") + "\""; } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING -String toString(bool in) { return in ? "true" : "false"; } -String toString(float in) { return detail::fpToString(in, 5) + "f"; } -String toString(double in) { return detail::fpToString(in, 10); } -String toString(double long in) { return detail::fpToString(in, 15); } - -String toString(char in) { - char buf[64]; - std::sprintf(buf, "%d", in); - return buf; -} - -String toString(char signed in) { - char buf[64]; - std::sprintf(buf, "%d", in); - return buf; -} - -String toString(char unsigned in) { - char buf[64]; - std::sprintf(buf, "%ud", in); - return buf; -} - -String toString(int short in) { - char buf[64]; - std::sprintf(buf, "%d", in); - return buf; -} - -String toString(int short unsigned in) { - char buf[64]; - std::sprintf(buf, "%u", in); - return buf; -} - -String toString(int in) { - char buf[64]; - std::sprintf(buf, "%d", in); - return buf; -} - -String toString(int unsigned in) { - char buf[64]; - std::sprintf(buf, "%u", in); - return buf; -} - -String toString(int long in) { - char buf[64]; - std::sprintf(buf, "%ld", in); - return buf; -} - -String toString(int long unsigned in) { - char buf[64]; - std::sprintf(buf, "%lu", in); - return buf; -} - -#ifdef DOCTEST_CONFIG_WITH_LONG_LONG -String toString(int long long in) { - char buf[64]; - std::sprintf(buf, "%lld", in); - return buf; -} -String toString(int long long unsigned in) { - char buf[64]; - std::sprintf(buf, "%llu", in); - return buf; -} -#endif // DOCTEST_CONFIG_WITH_LONG_LONG - -#ifdef DOCTEST_CONFIG_WITH_NULLPTR -String toString(std::nullptr_t) { return "nullptr"; } -#endif // DOCTEST_CONFIG_WITH_NULLPTR - -} // namespace doctest - -#ifdef DOCTEST_CONFIG_DISABLE -namespace doctest -{ -bool isRunningInTest() { return false; } -Context::Context(int, const char* const*) {} -Context::~Context() {} -void Context::applyCommandLine(int, const char* const*) {} -void Context::addFilter(const char*, const char*) {} -void Context::clearFilters() {} -void Context::setOption(const char*, int) {} -void Context::setOption(const char*, const char*) {} -bool Context::shouldExit() { return false; } -int Context::run() { return 0; } -} // namespace doctest -#else // DOCTEST_CONFIG_DISABLE - -#if !defined(DOCTEST_CONFIG_COLORS_NONE) -#if !defined(DOCTEST_CONFIG_COLORS_WINDOWS) && !defined(DOCTEST_CONFIG_COLORS_ANSI) -#ifdef DOCTEST_PLATFORM_WINDOWS -#define DOCTEST_CONFIG_COLORS_WINDOWS -#else // linux -#define DOCTEST_CONFIG_COLORS_ANSI -#endif // platform -#endif // DOCTEST_CONFIG_COLORS_WINDOWS && DOCTEST_CONFIG_COLORS_ANSI -#endif // DOCTEST_CONFIG_COLORS_NONE - -#define DOCTEST_PRINTF_COLORED(buffer, color) \ - do { \ - doctest::detail::Color col(color); \ - std::printf("%s", buffer); \ - } while((void)0, 0) - -// the buffer size used for snprintf() calls -#if !defined(DOCTEST_SNPRINTF_BUFFER_LENGTH) -#define DOCTEST_SNPRINTF_BUFFER_LENGTH 1024 -#endif // DOCTEST_SNPRINTF_BUFFER_LENGTH - -#if defined(_MSC_VER) || defined(__MINGW32__) -#if defined(_MSC_VER) && _MSC_VER >= 1700 -#define DOCTEST_WINDOWS_SAL_IN_OPT _In_opt_ -#else // _MSC_VER -#define DOCTEST_WINDOWS_SAL_IN_OPT -#endif // _MSC_VER -extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA( - DOCTEST_WINDOWS_SAL_IN_OPT const char*); -extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); -#endif // _MSC_VER || __MINGW32__ - -#ifdef DOCTEST_CONFIG_COLORS_ANSI -#include <unistd.h> -#endif // DOCTEST_CONFIG_COLORS_ANSI - -#ifdef _WIN32 - -// defines for a leaner windows.h -#ifndef WIN32_MEAN_AND_LEAN -#define WIN32_MEAN_AND_LEAN -#endif // WIN32_MEAN_AND_LEAN -#ifndef VC_EXTRA_LEAN -#define VC_EXTRA_LEAN -#endif // VC_EXTRA_LEAN -#ifndef NOMINMAX -#define NOMINMAX -#endif // NOMINMAX - -// not sure what AfxWin.h is for - here I do what Catch does -#ifdef __AFXDLL -#include <AfxWin.h> -#else -#include <windows.h> -#endif -#include <io.h> - -#else // _WIN32 - -#include <sys/time.h> - -#endif // _WIN32 - -namespace doctest_detail_test_suite_ns -{ -// holds the current test suite -doctest::detail::TestSuite& getCurrentTestSuite() { - static doctest::detail::TestSuite data; - return data; -} -} // namespace doctest_detail_test_suite_ns - -namespace doctest -{ -namespace detail -{ - TestCase::TestCase(funcType test, const char* file, unsigned line, const TestSuite& test_suite, - const char* type, int template_id) - : m_test(test) - , m_name(0) - , m_type(type) - , m_test_suite(test_suite.m_test_suite) - , m_description(test_suite.m_description) - , m_skip(test_suite.m_skip) - , m_may_fail(test_suite.m_may_fail) - , m_should_fail(test_suite.m_should_fail) - , m_expected_failures(test_suite.m_expected_failures) - , m_timeout(test_suite.m_timeout) - , m_file(file) - , m_line(line) - , m_template_id(template_id) {} - - TestCase& TestCase::operator*(const char* in) { - m_name = in; - // make a new name with an appended type for templated test case - if(m_template_id != -1) { - m_full_name = String(m_name) + m_type; - // redirect the name to point to the newly constructed full name - m_name = m_full_name.c_str(); - } - return *this; - } - - TestCase& TestCase::operator=(const TestCase& other) { - m_test = other.m_test; - m_full_name = other.m_full_name; - m_name = other.m_name; - m_type = other.m_type; - m_test_suite = other.m_test_suite; - m_description = other.m_description; - m_skip = other.m_skip; - m_may_fail = other.m_may_fail; - m_should_fail = other.m_should_fail; - m_expected_failures = other.m_expected_failures; - m_timeout = other.m_timeout; - m_file = other.m_file; - m_line = other.m_line; - m_template_id = other.m_template_id; - - if(m_template_id != -1) - m_name = m_full_name.c_str(); - return *this; - } - - bool TestCase::operator<(const TestCase& other) const { - if(m_line != other.m_line) - return m_line < other.m_line; - int file_cmp = std::strcmp(m_file, other.m_file); - if(file_cmp != 0) - return file_cmp < 0; - return m_template_id < other.m_template_id; - } - - const char* getAssertString(assertType::Enum val) { - switch(val) { //!OCLINT missing default in switch statements - // clang-format off - case assertType::DT_WARN : return "WARN"; - case assertType::DT_CHECK : return "CHECK"; - case assertType::DT_REQUIRE : return "REQUIRE"; - - case assertType::DT_WARN_FALSE : return "WARN_FALSE"; - case assertType::DT_CHECK_FALSE : return "CHECK_FALSE"; - case assertType::DT_REQUIRE_FALSE : return "REQUIRE_FALSE"; - - case assertType::DT_WARN_THROWS : return "WARN_THROWS"; - case assertType::DT_CHECK_THROWS : return "CHECK_THROWS"; - case assertType::DT_REQUIRE_THROWS : return "REQUIRE_THROWS"; - - case assertType::DT_WARN_THROWS_AS : return "WARN_THROWS_AS"; - case assertType::DT_CHECK_THROWS_AS : return "CHECK_THROWS_AS"; - case assertType::DT_REQUIRE_THROWS_AS : return "REQUIRE_THROWS_AS"; - - case assertType::DT_WARN_NOTHROW : return "WARN_NOTHROW"; - case assertType::DT_CHECK_NOTHROW : return "CHECK_NOTHROW"; - case assertType::DT_REQUIRE_NOTHROW : return "REQUIRE_NOTHROW"; - - case assertType::DT_WARN_EQ : return "WARN_EQ"; - case assertType::DT_CHECK_EQ : return "CHECK_EQ"; - case assertType::DT_REQUIRE_EQ : return "REQUIRE_EQ"; - case assertType::DT_WARN_NE : return "WARN_NE"; - case assertType::DT_CHECK_NE : return "CHECK_NE"; - case assertType::DT_REQUIRE_NE : return "REQUIRE_NE"; - case assertType::DT_WARN_GT : return "WARN_GT"; - case assertType::DT_CHECK_GT : return "CHECK_GT"; - case assertType::DT_REQUIRE_GT : return "REQUIRE_GT"; - case assertType::DT_WARN_LT : return "WARN_LT"; - case assertType::DT_CHECK_LT : return "CHECK_LT"; - case assertType::DT_REQUIRE_LT : return "REQUIRE_LT"; - case assertType::DT_WARN_GE : return "WARN_GE"; - case assertType::DT_CHECK_GE : return "CHECK_GE"; - case assertType::DT_REQUIRE_GE : return "REQUIRE_GE"; - case assertType::DT_WARN_LE : return "WARN_LE"; - case assertType::DT_CHECK_LE : return "CHECK_LE"; - case assertType::DT_REQUIRE_LE : return "REQUIRE_LE"; - - case assertType::DT_WARN_UNARY : return "WARN_UNARY"; - case assertType::DT_CHECK_UNARY : return "CHECK_UNARY"; - case assertType::DT_REQUIRE_UNARY : return "REQUIRE_UNARY"; - case assertType::DT_WARN_UNARY_FALSE : return "WARN_UNARY_FALSE"; - case assertType::DT_CHECK_UNARY_FALSE : return "CHECK_UNARY_FALSE"; - case assertType::DT_REQUIRE_UNARY_FALSE : return "REQUIRE_UNARY_FALSE"; - - case assertType::DT_FAST_WARN_EQ : return "FAST_WARN_EQ"; - case assertType::DT_FAST_CHECK_EQ : return "FAST_CHECK_EQ"; - case assertType::DT_FAST_REQUIRE_EQ : return "FAST_REQUIRE_EQ"; - case assertType::DT_FAST_WARN_NE : return "FAST_WARN_NE"; - case assertType::DT_FAST_CHECK_NE : return "FAST_CHECK_NE"; - case assertType::DT_FAST_REQUIRE_NE : return "FAST_REQUIRE_NE"; - case assertType::DT_FAST_WARN_GT : return "FAST_WARN_GT"; - case assertType::DT_FAST_CHECK_GT : return "FAST_CHECK_GT"; - case assertType::DT_FAST_REQUIRE_GT : return "FAST_REQUIRE_GT"; - case assertType::DT_FAST_WARN_LT : return "FAST_WARN_LT"; - case assertType::DT_FAST_CHECK_LT : return "FAST_CHECK_LT"; - case assertType::DT_FAST_REQUIRE_LT : return "FAST_REQUIRE_LT"; - case assertType::DT_FAST_WARN_GE : return "FAST_WARN_GE"; - case assertType::DT_FAST_CHECK_GE : return "FAST_CHECK_GE"; - case assertType::DT_FAST_REQUIRE_GE : return "FAST_REQUIRE_GE"; - case assertType::DT_FAST_WARN_LE : return "FAST_WARN_LE"; - case assertType::DT_FAST_CHECK_LE : return "FAST_CHECK_LE"; - case assertType::DT_FAST_REQUIRE_LE : return "FAST_REQUIRE_LE"; - - case assertType::DT_FAST_WARN_UNARY : return "FAST_WARN_UNARY"; - case assertType::DT_FAST_CHECK_UNARY : return "FAST_CHECK_UNARY"; - case assertType::DT_FAST_REQUIRE_UNARY : return "FAST_REQUIRE_UNARY"; - case assertType::DT_FAST_WARN_UNARY_FALSE : return "FAST_WARN_UNARY_FALSE"; - case assertType::DT_FAST_CHECK_UNARY_FALSE : return "FAST_CHECK_UNARY_FALSE"; - case assertType::DT_FAST_REQUIRE_UNARY_FALSE: return "FAST_REQUIRE_UNARY_FALSE"; - // clang-format on - } - return ""; - } - - bool checkIfShouldThrow(assertType::Enum assert_type) { - if(assert_type & assertType::is_require) //!OCLINT bitwise operator in conditional - return true; - - if((assert_type & assertType::is_check) //!OCLINT bitwise operator in conditional - && contextState->abort_after > 0 && - contextState->numFailedAssertions >= contextState->abort_after) - return true; - - return false; - } - void fastAssertThrowIfFlagSet(int flags) { - if(flags & assertAction::shouldthrow) //!OCLINT bitwise operator in conditional - throwException(); - } - void throwException() { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - throw TestFailureException(); -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - } - - // matching of a string against a wildcard mask (case sensitivity configurable) taken from - // http://www.emoticode.net/c/simple-wildcard-string-compare-globbing-function.html - int wildcmp(const char* str, const char* wild, bool caseSensitive) { - const char* cp = 0; - const char* mp = 0; - - // rolled my own tolower() to not include more headers - while((*str) && (*wild != '*')) { - if((caseSensitive ? (*wild != *str) : (tolower(*wild) != tolower(*str))) && - (*wild != '?')) { - return 0; - } - wild++; - str++; - } - - while(*str) { - if(*wild == '*') { - if(!*++wild) { - return 1; - } - mp = wild; - cp = str + 1; - } else if((caseSensitive ? (*wild == *str) : (tolower(*wild) == tolower(*str))) || - (*wild == '?')) { - wild++; - str++; - } else { - wild = mp; //!OCLINT parameter reassignment - str = cp++; //!OCLINT parameter reassignment - } - } - - while(*wild == '*') { - wild++; - } - return !*wild; - } - - //// C string hash function (djb2) - taken from http://www.cse.yorku.ca/~oz/hash.html - //unsigned hashStr(unsigned const char* str) { - // unsigned long hash = 5381; - // char c; - // while((c = *str++)) - // hash = ((hash << 5) + hash) + c; // hash * 33 + c - // return hash; - //} - - // checks if the name matches any of the filters (and can be configured what to do when empty) - bool matchesAny(const char* name, const std::vector<String>& filters, int matchEmpty, - bool caseSensitive) { - if(filters.empty() && matchEmpty) - return true; - for(unsigned i = 0; i < filters.size(); ++i) - if(wildcmp(name, filters[i].c_str(), caseSensitive)) - return true; - return false; - } - -#ifdef _WIN32 - - typedef unsigned long long UInt64; - - UInt64 getCurrentTicks() { - static UInt64 hz = 0, hzo = 0; - if(!hz) { - QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&hz)); - QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&hzo)); - } - UInt64 t; - QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER*>(&t)); - return ((t - hzo) * 1000000) / hz; - } -#else // _WIN32 - - typedef uint64_t UInt64; - - UInt64 getCurrentTicks() { - timeval t; - gettimeofday(&t, 0); - return static_cast<UInt64>(t.tv_sec) * 1000000 + static_cast<UInt64>(t.tv_usec); - } -#endif // _WIN32 - - class Timer - { - public: - Timer() - : m_ticks(0) {} - void start() { m_ticks = getCurrentTicks(); } - unsigned int getElapsedMicroseconds() const { - return static_cast<unsigned int>(getCurrentTicks() - m_ticks); - } - unsigned int getElapsedMilliseconds() const { - return static_cast<unsigned int>(getElapsedMicroseconds() / 1000); - } - double getElapsedSeconds() const { return getElapsedMicroseconds() / 1000000.0; } - - private: - UInt64 m_ticks; - }; - - TestAccessibleContextState* getTestsContextState() { return contextState; } - - bool SubcaseSignature::operator<(const SubcaseSignature& other) const { - if(m_line != other.m_line) - return m_line < other.m_line; - if(std::strcmp(m_file, other.m_file) != 0) - return std::strcmp(m_file, other.m_file) < 0; - return std::strcmp(m_name, other.m_name) < 0; - } - - Subcase::Subcase(const char* name, const char* file, int line) - : m_signature(name, file, line) - , m_entered(false) { - ContextState* s = contextState; - - // if we have already completed it - if(s->subcasesPassed.count(m_signature) != 0) - return; - - // check subcase filters - if(s->subcasesCurrentLevel < s->subcase_filter_levels) { - if(!matchesAny(m_signature.m_name, s->filters[6], 1, s->case_sensitive)) - return; - if(matchesAny(m_signature.m_name, s->filters[7], 0, s->case_sensitive)) - return; - } - - // if a Subcase on the same level has already been entered - if(s->subcasesEnteredLevels.count(s->subcasesCurrentLevel) != 0) { - s->subcasesHasSkipped = true; - return; - } - - s->subcasesStack.push_back(*this); - if(s->hasLoggedCurrentTestStart) - logTestEnd(); - s->hasLoggedCurrentTestStart = false; - - s->subcasesEnteredLevels.insert(s->subcasesCurrentLevel++); - m_entered = true; - } - - Subcase::Subcase(const Subcase& other) - : m_signature(other.m_signature.m_name, other.m_signature.m_file, - other.m_signature.m_line) - , m_entered(other.m_entered) {} - - Subcase::~Subcase() { - if(m_entered) { - ContextState* s = contextState; - - s->subcasesCurrentLevel--; - // only mark the subcase as passed if no subcases have been skipped - if(s->subcasesHasSkipped == false) - s->subcasesPassed.insert(m_signature); - - if(!s->subcasesStack.empty()) - s->subcasesStack.pop_back(); - if(s->hasLoggedCurrentTestStart) - logTestEnd(); - s->hasLoggedCurrentTestStart = false; - } - } - - Result::~Result() {} - - Result& Result::operator=(const Result& other) { - m_passed = other.m_passed; - m_decomposition = other.m_decomposition; - - return *this; - } - - // for sorting tests by file/line - int fileOrderComparator(const void* a, const void* b) { - const TestCase* lhs = *static_cast<TestCase* const*>(a); - const TestCase* rhs = *static_cast<TestCase* const*>(b); -#ifdef _MSC_VER - // this is needed because MSVC gives different case for drive letters - // for __FILE__ when evaluated in a header and a source file - int res = stricmp(lhs->m_file, rhs->m_file); -#else // _MSC_VER - int res = std::strcmp(lhs->m_file, rhs->m_file); -#endif // _MSC_VER - if(res != 0) - return res; - return static_cast<int>(lhs->m_line - rhs->m_line); - } - - // for sorting tests by suite/file/line - int suiteOrderComparator(const void* a, const void* b) { - const TestCase* lhs = *static_cast<TestCase* const*>(a); - const TestCase* rhs = *static_cast<TestCase* const*>(b); - - int res = std::strcmp(lhs->m_test_suite, rhs->m_test_suite); - if(res != 0) - return res; - return fileOrderComparator(a, b); - } - - // for sorting tests by name/suite/file/line - int nameOrderComparator(const void* a, const void* b) { - const TestCase* lhs = *static_cast<TestCase* const*>(a); - const TestCase* rhs = *static_cast<TestCase* const*>(b); - - int res_name = std::strcmp(lhs->m_name, rhs->m_name); - if(res_name != 0) - return res_name; - return suiteOrderComparator(a, b); - } - - // sets the current test suite - int setTestSuite(const TestSuite& ts) { - doctest_detail_test_suite_ns::getCurrentTestSuite() = ts; - return 0; - } - - // all the registered tests - std::set<TestCase>& getRegisteredTests() { - static std::set<TestCase> data; - return data; - } - - // used by the macros for registering tests - int regTest(const TestCase& tc) { - getRegisteredTests().insert(tc); - return 0; - } - - struct Color - { - enum Code - { - None = 0, - White, - Red, - Green, - Blue, - Cyan, - Yellow, - Grey, - - Bright = 0x10, - - BrightRed = Bright | Red, - BrightGreen = Bright | Green, - LightGrey = Bright | Grey, - BrightWhite = Bright | White - }; - explicit Color(Code code) { use(code); } - ~Color() { use(None); } - - static void use(Code code); - static void init(); - }; - -#ifdef DOCTEST_CONFIG_COLORS_WINDOWS - HANDLE g_stdoutHandle; - WORD g_originalForegroundAttributes; - WORD g_originalBackgroundAttributes; - bool g_attrsInitted = false; -#endif // DOCTEST_CONFIG_COLORS_WINDOWS - - void Color::init() { -#ifdef DOCTEST_CONFIG_COLORS_WINDOWS - if(!g_attrsInitted) { - g_stdoutHandle = GetStdHandle(STD_OUTPUT_HANDLE); - g_attrsInitted = true; - CONSOLE_SCREEN_BUFFER_INFO csbiInfo; - GetConsoleScreenBufferInfo(g_stdoutHandle, &csbiInfo); - g_originalForegroundAttributes = - csbiInfo.wAttributes & - ~(BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY); - g_originalBackgroundAttributes = - csbiInfo.wAttributes & - ~(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); - } -#endif // DOCTEST_CONFIG_COLORS_WINDOWS - } - - void Color::use(Code -#ifndef DOCTEST_CONFIG_COLORS_NONE - code -#endif // DOCTEST_CONFIG_COLORS_NONE - ) { - const ContextState* p = contextState; - if(p->no_colors) - return; -#ifdef DOCTEST_CONFIG_COLORS_ANSI - if(isatty(STDOUT_FILENO) == false && p->force_colors == false) - return; - - const char* col = ""; - // clang-format off - switch(code) { //!OCLINT missing break in switch statement / unnecessary default statement in covered switch statement - case Color::Red: col = "[0;31m"; break; - case Color::Green: col = "[0;32m"; break; - case Color::Blue: col = "[0;34m"; break; - case Color::Cyan: col = "[0;36m"; break; - case Color::Yellow: col = "[0;33m"; break; - case Color::Grey: col = "[1;30m"; break; - case Color::LightGrey: col = "[0;37m"; break; - case Color::BrightRed: col = "[1;31m"; break; - case Color::BrightGreen: col = "[1;32m"; break; - case Color::BrightWhite: col = "[1;37m"; break; - case Color::Bright: // invalid - case Color::None: - case Color::White: - default: col = "[0m"; - } - // clang-format on - std::printf("\033%s", col); -#endif // DOCTEST_CONFIG_COLORS_ANSI - -#ifdef DOCTEST_CONFIG_COLORS_WINDOWS - if(isatty(fileno(stdout)) == false && p->force_colors == false) - return; - -#define DOCTEST_SET_ATTR(x) \ - SetConsoleTextAttribute(g_stdoutHandle, x | g_originalBackgroundAttributes) - - // clang-format off - switch (code) { - case Color::White: DOCTEST_SET_ATTR(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; - case Color::Red: DOCTEST_SET_ATTR(FOREGROUND_RED); break; - case Color::Green: DOCTEST_SET_ATTR(FOREGROUND_GREEN); break; - case Color::Blue: DOCTEST_SET_ATTR(FOREGROUND_BLUE); break; - case Color::Cyan: DOCTEST_SET_ATTR(FOREGROUND_BLUE | FOREGROUND_GREEN); break; - case Color::Yellow: DOCTEST_SET_ATTR(FOREGROUND_RED | FOREGROUND_GREEN); break; - case Color::Grey: DOCTEST_SET_ATTR(0); break; - case Color::LightGrey: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY); break; - case Color::BrightRed: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_RED); break; - case Color::BrightGreen: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN); break; - case Color::BrightWhite: DOCTEST_SET_ATTR(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); break; - case Color::None: - case Color::Bright: // invalid - default: DOCTEST_SET_ATTR(g_originalForegroundAttributes); - } -// clang-format on -#undef DOCTEST_SET_ATTR -#endif // DOCTEST_CONFIG_COLORS_WINDOWS - } - - IExceptionTranslator::~IExceptionTranslator() {} - - std::vector<const IExceptionTranslator*>& getExceptionTranslators() { - static std::vector<const IExceptionTranslator*> data; - return data; - } - - void registerExceptionTranslatorImpl(const IExceptionTranslator* translateFunction) { - getExceptionTranslators().push_back(translateFunction); - } - - String translateActiveException() { -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - String res; - std::vector<const IExceptionTranslator*>& translators = getExceptionTranslators(); - for(size_t i = 0; i < translators.size(); ++i) - if(translators[i]->translate(res)) - return res; - // clang-format off - try { - throw; - } catch(std::exception& ex) { - return ex.what(); - } catch(std::string& msg) { - return msg.c_str(); - } catch(const char* msg) { - return msg; - } catch(...) { - return "unknown exception"; - } -// clang-format on -#else // DOCTEST_CONFIG_NO_EXCEPTIONS - return ""; -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - } - - void writeStringToStream(std::ostream* stream, const String& str) { *stream << str; } - -#ifdef DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - void toStream(std::ostream* stream, char* in) { *stream << in; } - void toStream(std::ostream* stream, const char* in) { *stream << in; } -#endif // DOCTEST_CONFIG_TREAT_CHAR_STAR_AS_STRING - void toStream(std::ostream* stream, bool in) { - *stream << std::boolalpha << in << std::noboolalpha; - } - void toStream(std::ostream* stream, float in) { *stream << in; } - void toStream(std::ostream* stream, double in) { *stream << in; } - void toStream(std::ostream* stream, double long in) { *stream << in; } - - void toStream(std::ostream* stream, char in) { *stream << in; } - void toStream(std::ostream* stream, char signed in) { *stream << in; } - void toStream(std::ostream* stream, char unsigned in) { *stream << in; } - void toStream(std::ostream* stream, int short in) { *stream << in; } - void toStream(std::ostream* stream, int short unsigned in) { *stream << in; } - void toStream(std::ostream* stream, int in) { *stream << in; } - void toStream(std::ostream* stream, int unsigned in) { *stream << in; } - void toStream(std::ostream* stream, int long in) { *stream << in; } - void toStream(std::ostream* stream, int long unsigned in) { *stream << in; } - -#ifdef DOCTEST_CONFIG_WITH_LONG_LONG - void toStream(std::ostream* stream, int long long in) { *stream << in; } - void toStream(std::ostream* stream, int long long unsigned in) { *stream << in; } -#endif // DOCTEST_CONFIG_WITH_LONG_LONG - - void addToContexts(IContextScope* ptr) { contextState->contexts.push_back(ptr); } - void popFromContexts() { contextState->contexts.pop_back(); } - void useContextIfExceptionOccurred(IContextScope* ptr) { - if(std::uncaught_exception()) { - std::ostringstream stream; - ptr->build(&stream); - contextState->exceptionalContexts.push_back(stream.str()); - } - } - - void printSummary(); - -#if !defined(DOCTEST_CONFIG_POSIX_SIGNALS) && !defined(DOCTEST_CONFIG_WINDOWS_SEH) - void reportFatal(const std::string&) {} - struct FatalConditionHandler - { - void reset() {} - }; -#else // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH - - void reportFatal(const std::string& message) { - DOCTEST_LOG_START(); - - contextState->numAssertions += contextState->numAssertionsForCurrentTestcase; - logTestException(message.c_str(), true); - logTestEnd(); - contextState->numFailed++; - - printSummary(); - } - -#ifdef DOCTEST_PLATFORM_WINDOWS - - struct SignalDefs - { - DWORD id; - const char* name; - }; - // There is no 1-1 mapping between signals and windows exceptions. - // Windows can easily distinguish between SO and SigSegV, - // but SigInt, SigTerm, etc are handled differently. - SignalDefs signalDefs[] = { - {EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"}, - {EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"}, - {EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"}, - {EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"}, - }; - - struct FatalConditionHandler - { - static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { - for(size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { - if(ExceptionInfo->ExceptionRecord->ExceptionCode == signalDefs[i].id) { - reportFatal(signalDefs[i].name); - } - } - // If its not an exception we care about, pass it along. - // This stops us from eating debugger breaks etc. - return EXCEPTION_CONTINUE_SEARCH; - } - - FatalConditionHandler() { - isSet = true; - // 32k seems enough for doctest to handle stack overflow, - // but the value was found experimentally, so there is no strong guarantee - guaranteeSize = 32 * 1024; - exceptionHandlerHandle = 0; - // Register as first handler in current chain - exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); - // Pass in guarantee size to be filled - SetThreadStackGuarantee(&guaranteeSize); - } - - static void reset() { - if(isSet) { - // Unregister handler and restore the old guarantee - RemoveVectoredExceptionHandler(exceptionHandlerHandle); - SetThreadStackGuarantee(&guaranteeSize); - exceptionHandlerHandle = 0; - isSet = false; - } - } - - ~FatalConditionHandler() { reset(); } - - private: - static bool isSet; - static ULONG guaranteeSize; - static PVOID exceptionHandlerHandle; - }; - - bool FatalConditionHandler::isSet = false; - ULONG FatalConditionHandler::guaranteeSize = 0; - PVOID FatalConditionHandler::exceptionHandlerHandle = 0; - -#else // DOCTEST_PLATFORM_WINDOWS - - struct SignalDefs - { - int id; - const char* name; - }; - SignalDefs signalDefs[] = {{SIGINT, "SIGINT - Terminal interrupt signal"}, - {SIGILL, "SIGILL - Illegal instruction signal"}, - {SIGFPE, "SIGFPE - Floating point error signal"}, - {SIGSEGV, "SIGSEGV - Segmentation violation signal"}, - {SIGTERM, "SIGTERM - Termination request signal"}, - {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}}; - - struct FatalConditionHandler - { - static bool isSet; - static struct sigaction oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)]; - static stack_t oldSigStack; - static char altStackMem[SIGSTKSZ]; - - static void handleSignal(int sig) { - std::string name = "<unknown signal>"; - for(std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { - SignalDefs& def = signalDefs[i]; - if(sig == def.id) { - name = def.name; - break; - } - } - reset(); - reportFatal(name); - raise(sig); - } - - FatalConditionHandler() { - isSet = true; - stack_t sigStack; - sigStack.ss_sp = altStackMem; - sigStack.ss_size = SIGSTKSZ; - sigStack.ss_flags = 0; - sigaltstack(&sigStack, &oldSigStack); - struct sigaction sa = {0}; - - sa.sa_handler = handleSignal; // NOLINT - sa.sa_flags = SA_ONSTACK; - for(std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { - sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); - } - } - - ~FatalConditionHandler() { reset(); } - static void reset() { - if(isSet) { - // Set signals back to previous values -- hopefully nobody overwrote them in the meantime - for(std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { - sigaction(signalDefs[i].id, &oldSigActions[i], 0); - } - // Return the old stack - sigaltstack(&oldSigStack, 0); - isSet = false; - } - } - }; - - bool FatalConditionHandler::isSet = false; - struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)] = - {}; - stack_t FatalConditionHandler::oldSigStack = {}; - char FatalConditionHandler::altStackMem[SIGSTKSZ] = {}; - -#endif // DOCTEST_PLATFORM_WINDOWS -#endif // DOCTEST_CONFIG_POSIX_SIGNALS || DOCTEST_CONFIG_WINDOWS_SEH - - // depending on the current options this will remove the path of filenames - const char* fileForOutput(const char* file) { - if(contextState->no_path_in_filenames) { - const char* back = std::strrchr(file, '\\'); - const char* forward = std::strrchr(file, '/'); - if(back || forward) { - if(back > forward) - forward = back; - return forward + 1; - } - } - return file; - } - - // depending on the current options this will substitute the line numbers with 0 - int lineForOutput(int line) { - if(contextState->no_line_numbers) - return 0; - return line; - } - -#ifdef DOCTEST_PLATFORM_MAC -#include <sys/types.h> -#include <unistd.h> -#include <sys/sysctl.h> - // The following function is taken directly from the following technical note: - // http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html - // Returns true if the current process is being debugged (either - // running under the debugger or has a debugger attached post facto). - bool isDebuggerActive() { - int mib[4]; - kinfo_proc info; - size_t size; - // Initialize the flags so that, if sysctl fails for some bizarre - // reason, we get a predictable result. - info.kp_proc.p_flag = 0; - // Initialize mib, which tells sysctl the info we want, in this case - // we're looking for information about a specific process ID. - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PID; - mib[3] = getpid(); - // Call sysctl. - size = sizeof(info); - if(sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, 0, 0) != 0) { - fprintf(stderr, "\n** Call to sysctl failed - unable to determine if debugger is " - "active **\n\n"); - return false; - } - // We're being debugged if the P_TRACED flag is set. - return ((info.kp_proc.p_flag & P_TRACED) != 0); - } -#elif defined(_MSC_VER) || defined(__MINGW32__) - bool isDebuggerActive() { return ::IsDebuggerPresent() != 0; } -#else - bool isDebuggerActive() { return false; } -#endif // Platform - -#ifdef DOCTEST_PLATFORM_WINDOWS - void myOutputDebugString(const String& text) { ::OutputDebugStringA(text.c_str()); } -#else - // TODO: integration with XCode and other IDEs - void myOutputDebugString(const String&) {} -#endif // Platform - - const char* getSeparator() { - return "===============================================================================\n"; - } - - void printToDebugConsole(const String& text) { - if(isDebuggerActive()) - myOutputDebugString(text.c_str()); - } - - void addFailedAssert(assertType::Enum assert_type) { - if((assert_type & assertType::is_warn) == 0) { //!OCLINT bitwise operator in conditional - contextState->numFailedAssertions++; - contextState->numFailedAssertionsForCurrentTestcase++; - contextState->hasCurrentTestFailed = true; - } - } - - void logTestStart(const TestCase& tc) { - char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)\n", fileForOutput(tc.m_file), - lineForOutput(tc.m_line)); - - char ts1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(ts1, DOCTEST_COUNTOF(ts1), "TEST SUITE: "); - char ts2[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(ts2, DOCTEST_COUNTOF(ts2), "%s\n", tc.m_test_suite); - char n1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(n1, DOCTEST_COUNTOF(n1), "TEST CASE: "); - char n2[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(n2, DOCTEST_COUNTOF(n2), "%s\n", tc.m_name); - char d1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(d1, DOCTEST_COUNTOF(d1), "DESCRIPTION: "); - char d2[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(d2, DOCTEST_COUNTOF(d2), "%s\n", tc.m_description); - - // hack for BDD style of macros - to not print "TEST CASE:" - char scenario[] = " Scenario:"; - if(std::string(tc.m_name).substr(0, DOCTEST_COUNTOF(scenario) - 1) == scenario) - n1[0] = '\0'; - - DOCTEST_PRINTF_COLORED(getSeparator(), Color::Yellow); - DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); - - String forDebugConsole; - if(tc.m_description) { - DOCTEST_PRINTF_COLORED(d1, Color::Yellow); - DOCTEST_PRINTF_COLORED(d2, Color::None); - forDebugConsole += d1; - forDebugConsole += d2; - } - if(tc.m_test_suite[0] != '\0') { - DOCTEST_PRINTF_COLORED(ts1, Color::Yellow); - DOCTEST_PRINTF_COLORED(ts2, Color::None); - forDebugConsole += ts1; - forDebugConsole += ts2; - } - DOCTEST_PRINTF_COLORED(n1, Color::Yellow); - DOCTEST_PRINTF_COLORED(n2, Color::None); - - String subcaseStuff; - std::vector<Subcase>& subcasesStack = contextState->subcasesStack; - for(unsigned i = 0; i < subcasesStack.size(); ++i) { - if(subcasesStack[i].m_signature.m_name[0] != '\0') { - char subcase[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(subcase, DOCTEST_COUNTOF(loc), " %s\n", - subcasesStack[i].m_signature.m_name); - DOCTEST_PRINTF_COLORED(subcase, Color::None); - subcaseStuff += subcase; - } - } - - DOCTEST_PRINTF_COLORED("\n", Color::None); - - printToDebugConsole(String(getSeparator()) + loc + forDebugConsole.c_str() + n1 + n2 + - subcaseStuff.c_str() + "\n"); - } - - void logTestEnd() {} - - void logTestException(const String& what, bool crash) { - char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - - DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), "TEST CASE FAILED!\n"); - - char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - char info2[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - info1[0] = 0; - info2[0] = 0; - DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), - crash ? "crashed:\n" : "threw exception:\n"); - DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), " %s\n", what.c_str()); - - std::string contextStr; - - if(!contextState->exceptionalContexts.empty()) { - contextStr += "with context:\n"; - for(size_t i = contextState->exceptionalContexts.size(); i > 0; --i) { - contextStr += " "; - contextStr += contextState->exceptionalContexts[i - 1]; - contextStr += "\n"; - } - } - - DOCTEST_PRINTF_COLORED(msg, Color::Red); - DOCTEST_PRINTF_COLORED(info1, Color::None); - DOCTEST_PRINTF_COLORED(info2, Color::Cyan); - DOCTEST_PRINTF_COLORED(contextStr.c_str(), Color::None); - DOCTEST_PRINTF_COLORED("\n", Color::None); - - printToDebugConsole(String(msg) + info1 + info2 + contextStr.c_str() + "\n"); - } - - String logContext() { - std::ostringstream stream; - std::vector<IContextScope*>& contexts = contextState->contexts; - if(!contexts.empty()) - stream << "with context:\n"; - for(size_t i = 0; i < contexts.size(); ++i) { - stream << " "; - contexts[i]->build(&stream); - stream << "\n"; - } - return stream.str().c_str(); - } - - const char* getFailString(assertType::Enum assert_type) { - if(assert_type & assertType::is_warn) //!OCLINT bitwise operator in conditional - return "WARNING"; - if(assert_type & assertType::is_check) //!OCLINT bitwise operator in conditional - return "ERROR"; - if(assert_type & assertType::is_require) //!OCLINT bitwise operator in conditional - return "FATAL ERROR"; - return ""; - } - - void logAssert(bool passed, const char* decomposition, bool threw, const String& exception, - const char* expr, assertType::Enum assert_type, const char* file, int line) { - char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), - lineForOutput(line)); - - char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " %s!\n", - passed ? "PASSED" : getFailString(assert_type)); - - char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n", - getAssertString(assert_type), expr); - - char info2[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - char info3[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - info2[0] = 0; - info3[0] = 0; - if(threw) { - DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "threw exception:\n"); - DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s\n", exception.c_str()); - } else { - DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "with expansion:\n"); - DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s( %s )\n", - getAssertString(assert_type), decomposition); - } - - bool isWarn = assert_type & assertType::is_warn; - DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); - DOCTEST_PRINTF_COLORED(msg, - passed ? Color::BrightGreen : isWarn ? Color::Yellow : Color::Red); - DOCTEST_PRINTF_COLORED(info1, Color::Cyan); - DOCTEST_PRINTF_COLORED(info2, Color::None); - DOCTEST_PRINTF_COLORED(info3, Color::Cyan); - String context = logContext(); - DOCTEST_PRINTF_COLORED(context.c_str(), Color::None); - DOCTEST_PRINTF_COLORED("\n", Color::None); - - printToDebugConsole(String(loc) + msg + info1 + info2 + info3 + context.c_str() + "\n"); - } - - void logAssertThrows(bool threw, const char* expr, assertType::Enum assert_type, - const char* file, int line) { - char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), - lineForOutput(line)); - - char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " %s!\n", - threw ? "PASSED" : getFailString(assert_type)); - - char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n", - getAssertString(assert_type), expr); - - char info2[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - info2[0] = 0; - - if(!threw) - DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "didn't throw at all\n"); - - bool isWarn = assert_type & assertType::is_warn; - DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); - DOCTEST_PRINTF_COLORED(msg, - threw ? Color::BrightGreen : isWarn ? Color::Yellow : Color::Red); - DOCTEST_PRINTF_COLORED(info1, Color::Cyan); - DOCTEST_PRINTF_COLORED(info2, Color::None); - String context = logContext(); - DOCTEST_PRINTF_COLORED(context.c_str(), Color::None); - DOCTEST_PRINTF_COLORED("\n", Color::None); - - printToDebugConsole(String(loc) + msg + info1 + info2 + context.c_str() + "\n"); - } - - void logAssertThrowsAs(bool threw, bool threw_as, const char* as, const String& exception, - const char* expr, assertType::Enum assert_type, const char* file, - int line) { - char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), - lineForOutput(line)); - - char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " %s!\n", - threw_as ? "PASSED" : getFailString(assert_type)); - - char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s, %s )\n", - getAssertString(assert_type), expr, as); - - char info2[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - char info3[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - info2[0] = 0; - info3[0] = 0; - - if(!threw) { //!OCLINT inverted logic - DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "didn't throw at all\n"); - } else if(!threw_as) { - DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "threw a different exception:\n"); - DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s\n", exception.c_str()); - } - - bool isWarn = assert_type & assertType::is_warn; - DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); - DOCTEST_PRINTF_COLORED(msg, - threw_as ? Color::BrightGreen : isWarn ? Color::Yellow : Color::Red); - DOCTEST_PRINTF_COLORED(info1, Color::Cyan); - DOCTEST_PRINTF_COLORED(info2, Color::None); - DOCTEST_PRINTF_COLORED(info3, Color::Cyan); - String context = logContext(); - DOCTEST_PRINTF_COLORED(context.c_str(), Color::None); - DOCTEST_PRINTF_COLORED("\n", Color::None); - - printToDebugConsole(String(loc) + msg + info1 + info2 + info3 + context.c_str() + "\n"); - } - - void logAssertNothrow(bool threw, const String& exception, const char* expr, - assertType::Enum assert_type, const char* file, int line) { - char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(file), - lineForOutput(line)); - - char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " %s!\n", - threw ? getFailString(assert_type) : "PASSED"); - - char info1[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(info1, DOCTEST_COUNTOF(info1), " %s( %s )\n", - getAssertString(assert_type), expr); - - char info2[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - char info3[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - info2[0] = 0; - info3[0] = 0; - if(threw) { - DOCTEST_SNPRINTF(info2, DOCTEST_COUNTOF(info2), "threw exception:\n"); - DOCTEST_SNPRINTF(info3, DOCTEST_COUNTOF(info3), " %s\n", exception.c_str()); - } - - bool isWarn = assert_type & assertType::is_warn; - DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); - DOCTEST_PRINTF_COLORED(msg, - threw ? isWarn ? Color::Yellow : Color::Red : Color::BrightGreen); - DOCTEST_PRINTF_COLORED(info1, Color::Cyan); - DOCTEST_PRINTF_COLORED(info2, Color::None); - DOCTEST_PRINTF_COLORED(info3, Color::Cyan); - String context = logContext(); - DOCTEST_PRINTF_COLORED(context.c_str(), Color::None); - DOCTEST_PRINTF_COLORED("\n", Color::None); - - printToDebugConsole(String(loc) + msg + info1 + info2 + info3 + context.c_str() + "\n"); - } - - ResultBuilder::ResultBuilder(assertType::Enum assert_type, const char* file, int line, - const char* expr, const char* exception_type) - : m_assert_type(assert_type) - , m_file(file) - , m_line(line) - , m_expr(expr) - , m_exception_type(exception_type) - , m_threw(false) - , m_threw_as(false) - , m_failed(false) { -#ifdef _MSC_VER - if(m_expr[0] == ' ') // this happens when variadic macros are disabled under MSVC - ++m_expr; -#endif // _MSC_VER - } - - ResultBuilder::~ResultBuilder() {} - - void ResultBuilder::unexpectedExceptionOccurred() { - m_threw = true; - - m_exception = translateActiveException(); - } - - bool ResultBuilder::log() { - if((m_assert_type & assertType::is_warn) == 0) //!OCLINT bitwise operator in conditional - contextState->numAssertionsForCurrentTestcase++; - - if(m_assert_type & assertType::is_throws) { //!OCLINT bitwise operator in conditional - m_failed = !m_threw; - } else if(m_assert_type & //!OCLINT bitwise operator in conditional - assertType::is_throws_as) { - m_failed = !m_threw_as; - } else if(m_assert_type & //!OCLINT bitwise operator in conditional - assertType::is_nothrow) { - m_failed = m_threw; - } else { - m_failed = m_result; - } - - if(m_failed || contextState->success) { - DOCTEST_LOG_START(); - - if(m_assert_type & assertType::is_throws) { //!OCLINT bitwise operator in conditional - logAssertThrows(m_threw, m_expr, m_assert_type, m_file, m_line); - } else if(m_assert_type & //!OCLINT bitwise operator in conditional - assertType::is_throws_as) { - logAssertThrowsAs(m_threw, m_threw_as, m_exception_type, m_exception, m_expr, - m_assert_type, m_file, m_line); - } else if(m_assert_type & //!OCLINT bitwise operator in conditional - assertType::is_nothrow) { - logAssertNothrow(m_threw, m_exception, m_expr, m_assert_type, m_file, m_line); - } else { - logAssert(m_result.m_passed, m_result.m_decomposition.c_str(), m_threw, m_exception, - m_expr, m_assert_type, m_file, m_line); - } - } - - if(m_failed) - addFailedAssert(m_assert_type); - - return m_failed && isDebuggerActive() && !contextState->no_breaks; // break into debugger - } - - void ResultBuilder::react() const { - if(m_failed && checkIfShouldThrow(m_assert_type)) - throwException(); - } - - MessageBuilder::MessageBuilder(const char* file, int line, - doctest::detail::assertType::Enum severity) - : m_stream(createStream()) - , m_file(file) - , m_line(line) - , m_severity(severity) {} - - bool MessageBuilder::log() { - DOCTEST_LOG_START(); - - bool is_warn = m_severity & doctest::detail::assertType::is_warn; - - // warn is just a message in this context so we dont treat it as an assert - if(!is_warn) { - contextState->numAssertionsForCurrentTestcase++; - addFailedAssert(m_severity); - } - - char loc[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(loc, DOCTEST_COUNTOF(loc), "%s(%d)", fileForOutput(m_file), - lineForOutput(m_line)); - char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), " %s!\n", - is_warn ? "MESSAGE" : getFailString(m_severity)); - - DOCTEST_PRINTF_COLORED(loc, Color::LightGrey); - DOCTEST_PRINTF_COLORED(msg, is_warn ? Color::Yellow : Color::Red); - - String info = getStreamResult(m_stream); - if(info.size()) { - DOCTEST_PRINTF_COLORED(" ", Color::None); - DOCTEST_PRINTF_COLORED(info.c_str(), Color::None); - DOCTEST_PRINTF_COLORED("\n", Color::None); - } - String context = logContext(); - DOCTEST_PRINTF_COLORED(context.c_str(), Color::None); - DOCTEST_PRINTF_COLORED("\n", Color::None); - - printToDebugConsole(String(loc) + msg + " " + info.c_str() + "\n" + context.c_str() + - "\n"); - - return isDebuggerActive() && !contextState->no_breaks && !is_warn; // break into debugger - } - - void MessageBuilder::react() { - if(m_severity & assertType::is_require) //!OCLINT bitwise operator in conditional - throwException(); - } - - MessageBuilder::~MessageBuilder() { freeStream(m_stream); } - - // the implementation of parseFlag() - bool parseFlagImpl(int argc, const char* const* argv, const char* pattern) { - for(int i = argc - 1; i >= 0; --i) { - const char* temp = std::strstr(argv[i], pattern); - if(temp && my_strlen(temp) == my_strlen(pattern)) { - // eliminate strings in which the chars before the option are not '-' - bool noBadCharsFound = true; //!OCLINT prefer early exits and continue - while(temp != argv[i]) { - if(*--temp != '-') { - noBadCharsFound = false; - break; - } - } - if(noBadCharsFound && argv[i][0] == '-') - return true; - } - } - return false; - } - - // locates a flag on the command line - bool parseFlag(int argc, const char* const* argv, const char* pattern) { -#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - if(!parseFlagImpl(argc, argv, pattern)) - return parseFlagImpl(argc, argv, pattern + 3); // 3 for "dt-" - return true; -#else // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - return parseFlagImpl(argc, argv, pattern); -#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - } - - // the implementation of parseOption() - bool parseOptionImpl(int argc, const char* const* argv, const char* pattern, String& res) { - for(int i = argc - 1; i >= 0; --i) { - const char* temp = std::strstr(argv[i], pattern); - if(temp) { //!OCLINT prefer early exits and continue - // eliminate matches in which the chars before the option are not '-' - bool noBadCharsFound = true; - const char* curr = argv[i]; - while(curr != temp) { - if(*curr++ != '-') { - noBadCharsFound = false; - break; - } - } - if(noBadCharsFound && argv[i][0] == '-') { - temp += my_strlen(pattern); - unsigned len = my_strlen(temp); - if(len) { - res = temp; - return true; - } - } - } - } - return false; - } - - // parses an option and returns the string after the '=' character - bool parseOption(int argc, const char* const* argv, const char* pattern, String& res, - const String& defaultVal = String()) { - res = defaultVal; -#ifndef DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - if(!parseOptionImpl(argc, argv, pattern, res)) - return parseOptionImpl(argc, argv, pattern + 3, res); // 3 for "dt-" - return true; -#else // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - return parseOptionImpl(argc, argv, pattern, res); -#endif // DOCTEST_CONFIG_NO_UNPREFIXED_OPTIONS - } - - // parses a comma separated list of words after a pattern in one of the arguments in argv - bool parseCommaSepArgs(int argc, const char* const* argv, const char* pattern, - std::vector<String>& res) { - String filtersString; - if(parseOption(argc, argv, pattern, filtersString)) { - // tokenize with "," as a separator - // cppcheck-suppress strtokCalled - char* pch = std::strtok(filtersString.c_str(), ","); // modifies the string - while(pch != 0) { - if(my_strlen(pch)) - res.push_back(pch); - // uses the strtok() internal state to go to the next token - // cppcheck-suppress strtokCalled - pch = std::strtok(0, ","); - } - return true; - } - return false; - } - - enum optionType - { - option_bool, - option_int - }; - - // parses an int/bool option from the command line - bool parseIntOption(int argc, const char* const* argv, const char* pattern, optionType type, - int& res) { - String parsedValue; - if(!parseOption(argc, argv, pattern, parsedValue)) - return false; - - if(type == 0) { - // boolean - const char positive[][5] = {"1", "true", "on", "yes"}; // 5 - strlen("true") + 1 - const char negative[][6] = {"0", "false", "off", "no"}; // 6 - strlen("false") + 1 - - // if the value matches any of the positive/negative possibilities - for(unsigned i = 0; i < 4; i++) { - if(parsedValue.compare(positive[i], true) == 0) { - res = 1; //!OCLINT parameter reassignment - return true; - } - if(parsedValue.compare(negative[i], true) == 0) { - res = 0; //!OCLINT parameter reassignment - return true; - } - } - } else { - // integer - int theInt = std::atoi(parsedValue.c_str()); // NOLINT - if(theInt != 0) { - res = theInt; //!OCLINT parameter reassignment - return true; - } - } - return false; - } - - void printVersion() { - if(contextState->no_version == false) { - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("doctest version is \"%s\"\n", DOCTEST_VERSION_STR); - } - } - - void printHelp() { - printVersion(); - // clang-format off - DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan); - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("boolean values: \"1/on/yes/true\" or \"0/off/no/false\"\n"); - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("filter values: \"str1,str2,str3\" (comma separated strings)\n"); - DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan); - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("filters use wildcards for matching strings\n"); - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("something passes a filter if any of the strings in a filter matches\n"); - DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan); - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("ALL FLAGS, OPTIONS AND FILTERS ALSO AVAILABLE WITH A \"dt-\" PREFIX!!!\n"); - DOCTEST_PRINTF_COLORED("[doctest]\n", Color::Cyan); - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("Query flags - the program quits after them. Available:\n\n"); - std::printf(" -?, --help, -h prints this message\n"); - std::printf(" -v, --version prints the version\n"); - std::printf(" -c, --count prints the number of matching tests\n"); - std::printf(" -ltc, --list-test-cases lists all matching tests by name\n"); - std::printf(" -lts, --list-test-suites lists all matching test suites\n\n"); - // ========================================================================================= << 79 - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("The available <int>/<string> options/filters are:\n\n"); - std::printf(" -tc, --test-case=<filters> filters tests by their name\n"); - std::printf(" -tce, --test-case-exclude=<filters> filters OUT tests by their name\n"); - std::printf(" -sf, --source-file=<filters> filters tests by their file\n"); - std::printf(" -sfe, --source-file-exclude=<filters> filters OUT tests by their file\n"); - std::printf(" -ts, --test-suite=<filters> filters tests by their test suite\n"); - std::printf(" -tse, --test-suite-exclude=<filters> filters OUT tests by their test suite\n"); - std::printf(" -sc, --subcase=<filters> filters subcases by their name\n"); - std::printf(" -sce, --subcase-exclude=<filters> filters OUT subcases by their name\n"); - std::printf(" -ob, --order-by=<string> how the tests should be ordered\n"); - std::printf(" <string> - by [file/suite/name/rand]\n"); - std::printf(" -rs, --rand-seed=<int> seed for random ordering\n"); - std::printf(" -f, --first=<int> the first test passing the filters to\n"); - std::printf(" execute - for range-based execution\n"); - std::printf(" -l, --last=<int> the last test passing the filters to\n"); - std::printf(" execute - for range-based execution\n"); - std::printf(" -aa, --abort-after=<int> stop after <int> failed assertions\n"); - std::printf(" -scfl,--subcase-filter-levels=<int> apply filters for the first <int> levels\n"); - DOCTEST_PRINTF_COLORED("\n[doctest] ", Color::Cyan); - std::printf("Bool options - can be used like flags and true is assumed. Available:\n\n"); - std::printf(" -s, --success=<bool> include successful assertions in output\n"); - std::printf(" -cs, --case-sensitive=<bool> filters being treated as case sensitive\n"); - std::printf(" -e, --exit=<bool> exits after the tests finish\n"); - std::printf(" -d, --duration=<bool> prints the time duration of each test\n"); - std::printf(" -nt, --no-throw=<bool> skips exceptions-related assert checks\n"); - std::printf(" -ne, --no-exitcode=<bool> returns (or exits) always with success\n"); - std::printf(" -nr, --no-run=<bool> skips all runtime doctest operations\n"); - std::printf(" -nv, --no-version=<bool> omit the framework version in the output\n"); - std::printf(" -nc, --no-colors=<bool> disables colors in output\n"); - std::printf(" -fc, --force-colors=<bool> use colors even when not in a tty\n"); - std::printf(" -nb, --no-breaks=<bool> disables breakpoints in debuggers\n"); - std::printf(" -ns, --no-skip=<bool> don't skip test cases marked as skip\n"); - std::printf(" -npf, --no-path-filenames=<bool> only filenames and no paths in output\n"); - std::printf(" -nln, --no-line-numbers=<bool> 0 instead of real line numbers in output\n"); - // ========================================================================================= << 79 - // clang-format on - - DOCTEST_PRINTF_COLORED("\n[doctest] ", Color::Cyan); - std::printf("for more information visit the project documentation\n\n"); - } - - void printSummary() { - const ContextState* p = contextState; - - DOCTEST_PRINTF_COLORED(getSeparator(), Color::Yellow); - if(p->count || p->list_test_cases) { - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("unskipped test cases passing the current filters: %u\n", - p->numTestsPassingFilters); - } else if(p->list_test_suites) { - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("unskipped test cases passing the current filters: %u\n", - p->numTestsPassingFilters); - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("test suites with unskipped test cases passing the current filters: %u\n", - p->numTestSuitesPassingFilters); - } else { - bool anythingFailed = p->numFailed > 0 || p->numFailedAssertions > 0; - - char buff[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "test cases: %6u", - p->numTestsPassingFilters); - DOCTEST_PRINTF_COLORED(buff, Color::None); - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); - DOCTEST_PRINTF_COLORED(buff, Color::None); - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%6d passed", - p->numTestsPassingFilters - p->numFailed); - DOCTEST_PRINTF_COLORED(buff, - (p->numTestsPassingFilters == 0 || anythingFailed) ? - Color::None : - Color::Green); - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); - DOCTEST_PRINTF_COLORED(buff, Color::None); - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%6u failed", p->numFailed); - DOCTEST_PRINTF_COLORED(buff, p->numFailed > 0 ? Color::Red : Color::None); - - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); - DOCTEST_PRINTF_COLORED(buff, Color::None); - if(p->no_skipped_summary == false) { - int numSkipped = static_cast<unsigned>(getRegisteredTests().size()) - - p->numTestsPassingFilters; - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%6d skipped", numSkipped); - DOCTEST_PRINTF_COLORED(buff, numSkipped == 0 ? Color::None : Color::Yellow); - } - DOCTEST_PRINTF_COLORED("\n", Color::None); - - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "assertions: %6d", p->numAssertions); - DOCTEST_PRINTF_COLORED(buff, Color::None); - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); - DOCTEST_PRINTF_COLORED(buff, Color::None); - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%6d passed", - p->numAssertions - p->numFailedAssertions); - DOCTEST_PRINTF_COLORED( - buff, (p->numAssertions == 0 || anythingFailed) ? Color::None : Color::Green); - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " | "); - DOCTEST_PRINTF_COLORED(buff, Color::None); - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), "%6d failed", p->numFailedAssertions); - DOCTEST_PRINTF_COLORED(buff, p->numFailedAssertions > 0 ? Color::Red : Color::None); - - DOCTEST_SNPRINTF(buff, DOCTEST_COUNTOF(buff), " |\n"); - DOCTEST_PRINTF_COLORED(buff, Color::None); - - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - DOCTEST_PRINTF_COLORED("Status: ", Color::None); - const char* result = (p->numFailed > 0) ? "FAILURE!\n" : "SUCCESS!\n"; - DOCTEST_PRINTF_COLORED(result, p->numFailed > 0 ? Color::Red : Color::Green); - } - - // remove any coloring - DOCTEST_PRINTF_COLORED("", Color::None); - } -} // namespace detail - -bool isRunningInTest() { return detail::contextState != 0; } - -Context::Context(int argc, const char* const* argv) - : p(new detail::ContextState) { - parseArgs(argc, argv, true); -} - -Context::~Context() { delete p; } - -void Context::applyCommandLine(int argc, const char* const* argv) { parseArgs(argc, argv); } - -// parses args -void Context::parseArgs(int argc, const char* const* argv, bool withDefaults) { - using namespace detail; - - // clang-format off - parseCommaSepArgs(argc, argv, "dt-source-file=", p->filters[0]); - parseCommaSepArgs(argc, argv, "dt-sf=", p->filters[0]); - parseCommaSepArgs(argc, argv, "dt-source-file-exclude=",p->filters[1]); - parseCommaSepArgs(argc, argv, "dt-sfe=", p->filters[1]); - parseCommaSepArgs(argc, argv, "dt-test-suite=", p->filters[2]); - parseCommaSepArgs(argc, argv, "dt-ts=", p->filters[2]); - parseCommaSepArgs(argc, argv, "dt-test-suite-exclude=", p->filters[3]); - parseCommaSepArgs(argc, argv, "dt-tse=", p->filters[3]); - parseCommaSepArgs(argc, argv, "dt-test-case=", p->filters[4]); - parseCommaSepArgs(argc, argv, "dt-tc=", p->filters[4]); - parseCommaSepArgs(argc, argv, "dt-test-case-exclude=", p->filters[5]); - parseCommaSepArgs(argc, argv, "dt-tce=", p->filters[5]); - parseCommaSepArgs(argc, argv, "dt-subcase=", p->filters[6]); - parseCommaSepArgs(argc, argv, "dt-sc=", p->filters[6]); - parseCommaSepArgs(argc, argv, "dt-subcase-exclude=", p->filters[7]); - parseCommaSepArgs(argc, argv, "dt-sce=", p->filters[7]); - // clang-format on - - int intRes = 0; - String strRes; - -#define DOCTEST_PARSE_AS_BOOL_OR_FLAG(name, sname, var, default) \ - if(parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), option_bool, intRes) || \ - parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), option_bool, intRes)) \ - p->var = !!intRes; \ - else if(parseFlag(argc, argv, #name) || parseFlag(argc, argv, #sname)) \ - p->var = true; \ - else if(withDefaults) \ - p->var = default - -#define DOCTEST_PARSE_INT_OPTION(name, sname, var, default) \ - if(parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), option_int, intRes) || \ - parseIntOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), option_int, intRes)) \ - p->var = intRes; \ - else if(withDefaults) \ - p->var = default - -#define DOCTEST_PARSE_STR_OPTION(name, sname, var, default) \ - if(parseOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(name, =), strRes, default) || \ - parseOption(argc, argv, DOCTEST_STR_CONCAT_TOSTR(sname, =), strRes, default) || \ - withDefaults) \ - p->var = strRes - - // clang-format off - DOCTEST_PARSE_STR_OPTION(dt-order-by, dt-ob, order_by, "file"); - DOCTEST_PARSE_INT_OPTION(dt-rand-seed, dt-rs, rand_seed, 0); - - DOCTEST_PARSE_INT_OPTION(dt-first, dt-f, first, 1); - DOCTEST_PARSE_INT_OPTION(dt-last, dt-l, last, 0); - - DOCTEST_PARSE_INT_OPTION(dt-abort-after, dt-aa, abort_after, 0); - DOCTEST_PARSE_INT_OPTION(dt-subcase-filter-levels, dt-scfl, subcase_filter_levels, 2000000000); - - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-success, dt-s, success, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-case-sensitive, dt-cs, case_sensitive, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-exit, dt-e, exit, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-duration, dt-d, duration, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-throw, dt-nt, no_throw, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-exitcode, dt-ne, no_exitcode, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-run, dt-nr, no_run, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-version, dt-nv, no_version, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-colors, dt-nc, no_colors, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-force-colors, dt-fc, force_colors, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-breaks, dt-nb, no_breaks, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-skip, dt-ns, no_skip, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-path-filenames, dt-npf, no_path_in_filenames, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-line-numbers, dt-nln, no_line_numbers, false); - DOCTEST_PARSE_AS_BOOL_OR_FLAG(dt-no-skipped-summary, dt-nss, no_skipped_summary, false); -// clang-format on - -#undef DOCTEST_PARSE_STR_OPTION -#undef DOCTEST_PARSE_INT_OPTION -#undef DOCTEST_PARSE_AS_BOOL_OR_FLAG - - if(withDefaults) { - p->help = false; - p->version = false; - p->count = false; - p->list_test_cases = false; - p->list_test_suites = false; - } - if(parseFlag(argc, argv, "dt-help") || parseFlag(argc, argv, "dt-h") || - parseFlag(argc, argv, "dt-?")) { - p->help = true; - p->exit = true; - } - if(parseFlag(argc, argv, "dt-version") || parseFlag(argc, argv, "dt-v")) { - p->version = true; - p->exit = true; - } - if(parseFlag(argc, argv, "dt-count") || parseFlag(argc, argv, "dt-c")) { - p->count = true; - p->exit = true; - } - if(parseFlag(argc, argv, "dt-list-test-cases") || parseFlag(argc, argv, "dt-ltc")) { - p->list_test_cases = true; - p->exit = true; - } - if(parseFlag(argc, argv, "dt-list-test-suites") || parseFlag(argc, argv, "dt-lts")) { - p->list_test_suites = true; - p->exit = true; - } -} - -// allows the user to add procedurally to the filters from the command line -void Context::addFilter(const char* filter, const char* value) { setOption(filter, value); } - -// allows the user to clear all filters from the command line -void Context::clearFilters() { - for(unsigned i = 0; i < p->filters.size(); ++i) - p->filters[i].clear(); -} - -// allows the user to override procedurally the int/bool options from the command line -void Context::setOption(const char* option, int value) { - setOption(option, toString(value).c_str()); -} - -// allows the user to override procedurally the string options from the command line -void Context::setOption(const char* option, const char* value) { - String argv = String("-") + option + "=" + value; - const char* lvalue = argv.c_str(); - parseArgs(1, &lvalue); -} - -// users should query this in their main() and exit the program if true -bool Context::shouldExit() { return p->exit; } - -// the main function that does all the filtering and test running -int Context::run() { - using namespace detail; - - Color::init(); - - contextState = p; - p->resetRunData(); - - // handle version, help and no_run - if(p->no_run || p->version || p->help) { - if(p->version) - printVersion(); - if(p->help) - printHelp(); - - contextState = 0; - - return EXIT_SUCCESS; - } - - printVersion(); - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("run with \"--help\" for options\n"); - - unsigned i = 0; // counter used for loops - here for VC6 - - std::set<TestCase>& registeredTests = getRegisteredTests(); - - std::vector<const TestCase*> testArray; - for(std::set<TestCase>::iterator it = registeredTests.begin(); it != registeredTests.end(); - ++it) - testArray.push_back(&(*it)); - - // sort the collected records - if(!testArray.empty()) { - if(p->order_by.compare("file", true) == 0) { - std::qsort(&testArray[0], testArray.size(), sizeof(TestCase*), fileOrderComparator); - } else if(p->order_by.compare("suite", true) == 0) { - std::qsort(&testArray[0], testArray.size(), sizeof(TestCase*), suiteOrderComparator); - } else if(p->order_by.compare("name", true) == 0) { - std::qsort(&testArray[0], testArray.size(), sizeof(TestCase*), nameOrderComparator); - } else if(p->order_by.compare("rand", true) == 0) { - std::srand(p->rand_seed); - - // random_shuffle implementation - const TestCase** first = &testArray[0]; - for(i = testArray.size() - 1; i > 0; --i) { - int idxToSwap = std::rand() % (i + 1); // NOLINT - - const TestCase* temp = first[i]; - - first[i] = first[idxToSwap]; - first[idxToSwap] = temp; - } - } - } - - if(p->list_test_cases) { - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("listing all test case names\n"); - DOCTEST_PRINTF_COLORED(getSeparator(), Color::Yellow); - } - - std::set<String> testSuitesPassingFilters; - if(p->list_test_suites) { - DOCTEST_PRINTF_COLORED("[doctest] ", Color::Cyan); - std::printf("listing all test suites\n"); - DOCTEST_PRINTF_COLORED(getSeparator(), Color::Yellow); - } - - // invoke the registered functions if they match the filter criteria (or just count them) - for(i = 0; i < testArray.size(); i++) { - const TestCase& data = *testArray[i]; - - if(data.m_skip && !p->no_skip) - continue; - - if(!matchesAny(data.m_file, p->filters[0], 1, p->case_sensitive)) - continue; - if(matchesAny(data.m_file, p->filters[1], 0, p->case_sensitive)) - continue; - if(!matchesAny(data.m_test_suite, p->filters[2], 1, p->case_sensitive)) - continue; - if(matchesAny(data.m_test_suite, p->filters[3], 0, p->case_sensitive)) - continue; - if(!matchesAny(data.m_name, p->filters[4], 1, p->case_sensitive)) - continue; - if(matchesAny(data.m_name, p->filters[5], 0, p->case_sensitive)) - continue; - - p->numTestsPassingFilters++; - - // do not execute the test if we are to only count the number of filter passing tests - if(p->count) - continue; - - // print the name of the test and don't execute it - if(p->list_test_cases) { - std::printf("%s\n", data.m_name); - continue; - } - - // print the name of the test suite if not done already and don't execute it - if(p->list_test_suites) { - if((testSuitesPassingFilters.count(data.m_test_suite) == 0) && - data.m_test_suite[0] != '\0') { - std::printf("%s\n", data.m_test_suite); - testSuitesPassingFilters.insert(data.m_test_suite); - p->numTestSuitesPassingFilters++; - } - continue; - } - - // skip the test if it is not in the execution range - if((p->last < p->numTestsPassingFilters && p->first <= p->last) || - (p->first > p->numTestsPassingFilters)) - continue; - - // execute the test if it passes all the filtering - { - p->currentTest = &data; - - bool failed = false; - p->hasLoggedCurrentTestStart = false; - p->numFailedAssertionsForCurrentTestcase = 0; - p->subcasesPassed.clear(); - double duration = 0; - Timer timer; - timer.start(); - do { - // if the start has been logged from a previous iteration of this loop - if(p->hasLoggedCurrentTestStart) - logTestEnd(); - p->hasLoggedCurrentTestStart = false; - - // if logging successful tests - force the start log - if(p->success) - DOCTEST_LOG_START(); - - // reset the assertion state - p->numAssertionsForCurrentTestcase = 0; - p->hasCurrentTestFailed = false; - - // reset some of the fields for subcases (except for the set of fully passed ones) - p->subcasesHasSkipped = false; - p->subcasesCurrentLevel = 0; - p->subcasesEnteredLevels.clear(); - - // reset stuff for logging with INFO() - p->exceptionalContexts.clear(); - -// execute the test -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - try { -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - FatalConditionHandler fatalConditionHandler; // Handle signals - data.m_test(); - fatalConditionHandler.reset(); - if(contextState->hasCurrentTestFailed) - failed = true; -#ifndef DOCTEST_CONFIG_NO_EXCEPTIONS - } catch(const TestFailureException&) { failed = true; } catch(...) { - DOCTEST_LOG_START(); - logTestException(translateActiveException()); - failed = true; - } -#endif // DOCTEST_CONFIG_NO_EXCEPTIONS - - p->numAssertions += p->numAssertionsForCurrentTestcase; - - // exit this loop if enough assertions have failed - if(p->abort_after > 0 && p->numFailedAssertions >= p->abort_after) { - p->subcasesHasSkipped = false; - DOCTEST_PRINTF_COLORED("Aborting - too many failed asserts!\n", Color::Red); - } - - } while(p->subcasesHasSkipped == true); - - duration = timer.getElapsedSeconds(); - - if(Approx(p->currentTest->m_timeout).epsilon(DBL_EPSILON) != 0 && - Approx(duration).epsilon(DBL_EPSILON) > p->currentTest->m_timeout) { - failed = true; - DOCTEST_LOG_START(); - char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), - "Test case exceeded time limit of %.6f!\n", - p->currentTest->m_timeout); - DOCTEST_PRINTF_COLORED(msg, Color::Red); - } - - if(p->duration) { - char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), "%.6f s: %s\n", duration, - p->currentTest->m_name); - DOCTEST_PRINTF_COLORED(msg, Color::None); - } - - if(data.m_should_fail) { - DOCTEST_LOG_START(); - if(failed) { - failed = false; - DOCTEST_PRINTF_COLORED("Failed as expected so marking it as not failed\n", - Color::Yellow); - } else { - failed = true; - DOCTEST_PRINTF_COLORED("Should have failed but didn't! Marking it as failed!\n", - Color::Red); - } - } else if(failed && data.m_may_fail) { - DOCTEST_LOG_START(); - failed = false; - DOCTEST_PRINTF_COLORED("Allowed to fail so marking it as not failed\n", - Color::Yellow); - } else if(data.m_expected_failures > 0) { - DOCTEST_LOG_START(); - char msg[DOCTEST_SNPRINTF_BUFFER_LENGTH]; - if(p->numFailedAssertionsForCurrentTestcase == data.m_expected_failures) { - failed = false; - DOCTEST_SNPRINTF( - msg, DOCTEST_COUNTOF(msg), - "Failed exactly %d times as expected so marking it as not failed!\n", - data.m_expected_failures); - DOCTEST_PRINTF_COLORED(msg, Color::Yellow); - } else { - failed = true; - DOCTEST_SNPRINTF(msg, DOCTEST_COUNTOF(msg), - "Didn't fail exactly %d times so marking it as failed!\n", - data.m_expected_failures); - DOCTEST_PRINTF_COLORED(msg, Color::Red); - } - } - - if(p->hasLoggedCurrentTestStart) - logTestEnd(); - - if(failed) // if any subcase has failed - the whole test case has failed - p->numFailed++; - - // stop executing tests if enough assertions have failed - if(p->abort_after > 0 && p->numFailedAssertions >= p->abort_after) - break; - } - } - - printSummary(); - - contextState = 0; - - if(p->numFailed && !p->no_exitcode) - return EXIT_FAILURE; - return EXIT_SUCCESS; -} -} // namespace doctest - -#endif // DOCTEST_CONFIG_DISABLE - -#ifdef DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN -int main(int argc, char** argv) { return doctest::Context(argc, argv).run(); } -#endif // DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN - -#endif // DOCTEST_LIBRARY_IMPLEMENTATION -#endif // DOCTEST_CONFIG_IMPLEMENT - -#if defined(__clang__) -#pragma clang diagnostic pop -#endif // __clang__ - -#if defined(__GNUC__) && !defined(__clang__) -#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) -#pragma GCC diagnostic pop -#endif // > gcc 4.6 -#endif // __GNUC__ - -#ifdef _MSC_VER -#pragma warning(pop) -#endif // _MSC_VER diff --git a/third_party/immer/tools/include/nonius.h++ b/third_party/immer/tools/include/nonius.h++ deleted file mode 100644 index 2fb3758dd800..000000000000 --- a/third_party/immer/tools/include/nonius.h++ +++ /dev/null @@ -1,4292 +0,0 @@ -// Nonius - C++ benchmarking tool -// -// Written in 2014 by Martinho Fernandes <martinho.fernandes@gmail.com> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// This file was automatically generated on 2017-07-26T10:25:52.043838Z -// Do not edit it directly - -#ifndef NONIUS_SINGLE_INCLUDE_HPP -#define NONIUS_SINGLE_INCLUDE_HPP - -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Single header root - -// #included from: nonius.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Main header - -#ifndef NONIUS_HPP -#define NONIUS_HPP - -// #included from: clock.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Clocks - -#define NONIUS_CLOCK_HPP - -// #included from: detail/compiler.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Compiler detection macros - -#define NONIUS_DETAIL_COMPILER_HPP - -#if defined(__clang__) -# define NONIUS_CLANG (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) -#elif defined(__GNUC__) -# define NONIUS_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#elif defined(_MSC_VER) -# define NONIUS_MSVC _MSC_VER -#endif - -// MSVC <chrono> is borken and had little to no testing done before shipping (Dev14/VS15 CTP fixes it) -#if defined(NONIUS_MSVC) && NONIUS_MSVC < 1900 -# ifndef NONIUS_USE_BOOST_CHRONO -# define NONIUS_USE_BOOST_CHRONO -# endif -#endif - -#ifdef NONIUS_USE_BOOST_CHRONO -# include <boost/chrono.hpp> -#else -# include <chrono> -# include <ratio> -#endif - -namespace nonius { -#ifdef NONIUS_USE_BOOST_CHRONO - namespace chrono = boost::chrono; - template <unsigned Num, unsigned Den = 1> - using ratio = boost::ratio<Num, Den>; -#else - namespace chrono = std::chrono; - template <unsigned Num, unsigned Den = 1> - using ratio = std::ratio<Num, Den>; -#endif - using milli = ratio<1, 1000>; - using micro = ratio<1, 1000000>; - using nano = ratio<1, 1000000000>; - - template <typename Clock> - using Duration = typename Clock::duration; - template <typename Clock> - using FloatDuration = chrono::duration<double, typename Clock::period>; - - template <typename Clock> - using TimePoint = typename Clock::time_point; - - using default_clock = chrono::high_resolution_clock; - - template <typename Clock> - struct now { - TimePoint<Clock> operator()() const { - return Clock::now(); - } - }; - - using fp_seconds = chrono::duration<double, ratio<1>>; -} // namespace nonius - -// #included from: benchmark.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Benchmark - -#define NONIUS_BENCHMARK_HPP - -// #included from: configuration.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Run configuration - -#define NONIUS_CONFIGURATION_HPP - -// #included from: param.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014 by Martinho Fernandes <martinho.fernandes@gmail.com> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// User-facing param - -#define NONIUS_PARAM_HPP - -// #included from: detail/meta.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014 by Martinho Fernandes <martinho.fernandes@gmail.com> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Invoke with a special case for void - -#define NONIUS_META_HPP - -#include <type_traits> -#include <utility> - -namespace nonius { - namespace detail { - template <typename> struct true_given : std::true_type {}; - struct is_callable_tester { - template <typename Fun, typename... Args> - true_given<decltype(std::declval<Fun>()(std::declval<Args>()...))> static test(int); - template <typename...> - std::false_type static test(...); - }; - template <typename T> - struct is_callable; - template <typename Fun, typename... Args> - struct is_callable<Fun(Args...)> : decltype(is_callable_tester::test<Fun, Args...>(0)) {}; - } // namespace detail -} // namespace nonius - -// #included from: detail/noexcept.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Cross-compiler noexcept support - -#define NONIUS_DETAIL_NOEXCEPT_HPP - -#if defined(NONIUS_MSVC) && NONIUS_MSVC < 1900 -# define NONIUS_NOEXCEPT -#else -# define NONIUS_NOEXCEPT noexcept -#endif - -#include <boost/lexical_cast.hpp> -#include <unordered_map> -#include <typeinfo> -#include <memory> - -namespace nonius { - -struct param_bad_operation : std::exception { - char const* what() const NONIUS_NOEXCEPT override { - return "operation not supported for this parameter type"; - } -}; - -namespace detail { - -struct eq_fn { - template <typename T> - auto operator() (T x, T y) -> decltype(x == y) { return x == y; } -}; - -struct plus_fn { - template <typename T> - auto operator() (T x, T y) -> decltype(x + y) { return x + y; } -}; - -struct mult_fn { - template <typename T> - auto operator() (T x, T y) -> decltype(x * y) { return x * y; } -}; - -} // namespace detail - -class param { - struct interface { - virtual ~interface() = default; - virtual std::istream& pull(std::istream&) = 0; - virtual std::ostream& push(std::ostream&) const = 0; - virtual bool eq(param const&) const = 0; - virtual param plus(param const&) const = 0; - virtual param mult(param const&) const = 0; - virtual param clone() const = 0; - }; - - template <typename T> - struct model : interface { - T value; - - model(T v) : value(std::move(v)) {} - std::istream& pull(std::istream& is) override { is >> value; return is; } - std::ostream& push(std::ostream& os) const override { os << value; return os; } - bool eq(param const& y) const override { return operate<bool>(detail::eq_fn{}, value, y.as<T>()); } - param plus(param const& y) const override { return operate<T>(detail::plus_fn{}, value, y.as<T>()); } - param mult(param const& y) const override { return operate<T>(detail::mult_fn{}, value, y.as<T>()); } - param clone() const override { return value; } - - template <typename R, typename Op, typename ...Args> - auto operate(Op&& op, Args&& ...xs) const - -> typename std::enable_if<detail::is_callable<Op&&(Args&&...)>::value, R>::type { - return std::forward<Op>(op)(std::forward<Args>(xs)...); - } - - template <typename R, typename Op, typename ...Args> - auto operate(Op&&, Args&&...) const - -> typename std::enable_if<!detail::is_callable<Op&&(Args&&...)>::value, R>::type { - throw param_bad_operation{}; - } - }; - -public: - template <typename T, - typename std::enable_if<!std::is_base_of<param, typename std::decay<T>::type>::value, int>::type = 0> - param(T&& v) - : impl_(new model<typename std::decay<T>::type>{std::forward<T>(v)}) {} - - template <typename T> - const T& as() const& { return dynamic_cast<model<T> const&>(*impl_).value; } - - friend std::istream& operator>>(std::istream& is, param& x) { x.writable_(); return x.impl_->pull(is); } - friend std::ostream& operator<<(std::ostream& os, const param& x) { return x.impl_->push(os); } - friend param operator+(const param& x, const param& y) { return x.impl_->plus(y); } - friend param operator*(const param& x, const param& y) { return x.impl_->mult(y); } - friend bool operator==(const param& x, const param& y) { return x.impl_->eq(y); } - - param parse(std::string const& s) const { - auto ss = std::stringstream{s}; - auto cpy = *this; - ss.exceptions(std::ios::failbit); - ss >> cpy; - return cpy; - } - -private: - void writable_() { - if (impl_.use_count() > 1) { - } - } - - std::shared_ptr<interface> impl_; -}; - -struct parameters : std::unordered_map<std::string, param> { - using base_t = std::unordered_map<std::string, param>; - using base_t::base_t; - - template <typename Tag> - auto get() const -> typename Tag::type { - return at(Tag::name()).template as<typename Tag::type>(); - } - - parameters merged(parameters m) const& { - m.insert(begin(), end()); - return m; - } - parameters merged(parameters m) && { - m.insert(std::make_move_iterator(begin()), std::make_move_iterator(end())); - return m; - } - - friend std::ostream& operator<< (std::ostream& os, const parameters& m) { - for(auto&& p : m) os << " " << p.first << " = " << p.second << "\n"; - return os; - } -}; - -struct param_registry { - parameters const& defaults() const { return defaults_; } - void add(std::string name, param v) { defaults_.emplace(name, v); } - void remove(std::string name) { defaults_.erase(name); } - -private: - parameters defaults_; -}; - -inline param_registry& global_param_registry() { - static param_registry instance; - return instance; -} - -template <typename Tag> -struct param_declaration { - using type = typename Tag::type; - param_registry& registry; - - param_declaration(type v, param_registry& r = global_param_registry()) - : registry{r} - { - r.add(Tag::name(), param{type{v}}); - } -}; - -template <typename Tag> -struct scoped_param_declaration : param_declaration<Tag> { - using param_declaration<Tag>::param_declaration; - - ~scoped_param_declaration() { - this->registry.remove(Tag::name()); - } -}; - -} /* namespace nonius */ - -#define NONIUS_PARAM(name_, ...) \ - namespace { \ - struct name_ { \ - using type = decltype(__VA_ARGS__); \ - static const char* name() { return #name_; } \ - }; \ - static auto NONIUS_DETAIL_UNIQUE_NAME(param_declaration) = \ - ::nonius::param_declaration<name_>{ (__VA_ARGS__) }; \ - } \ - // - -#include <boost/optional.hpp> -#include <string> -#include <vector> - -namespace nonius { - struct run_configuration { - std::string name; - std::string op; - param init; - param step; - std::size_t count; - }; - - struct param_configuration { - parameters map; - boost::optional<run_configuration> run; - }; - - struct configuration { - public: - int samples = 100; - double confidence_interval = 0.95; - int resamples = 100000; - std::string title = "benchmarks"; - std::string output_file; - std::string reporter; - std::string filter_pattern = ".*"; - bool list_benchmarks = false; - bool list_params = false; - bool list_reporters = false; - bool no_analysis = false; - bool verbose = false; - bool summary = false; - bool help = false; - param_configuration params; - }; -} // namespace nonius - -// #included from: environment.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Environment information - -#define NONIUS_ENVIRONMENT_HPP - -// #included from: outlier_classification.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Outlier information - -#define NONIUS_OUTLIERS_HPP - -namespace nonius { - struct outlier_classification { - int samples_seen = 0; - int low_severe = 0; // more than 3 times IQR below Q1 - int low_mild = 0; // 1.5 to 3 times IQR below Q1 - int high_mild = 0; // 1.5 to 3 times IQR above Q3 - int high_severe = 0; // more than 3 times IQR above Q3 - - int total() const { - return low_severe + low_mild + high_mild + high_severe; - } - }; -} // namespace nonius - -namespace nonius { - template <typename Duration> - struct environment_estimate { - Duration mean; - outlier_classification outliers; - - template <typename Duration2> - operator environment_estimate<Duration2>() const { - return { mean, outliers }; - } - }; - template <typename Clock> - struct environment { - using clock_type = Clock; - environment_estimate<FloatDuration<Clock>> clock_resolution; - environment_estimate<FloatDuration<Clock>> clock_cost; - //estimate function_cost; - }; -} // namespace nonius - -// #included from: execution_plan.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Execution plan - -#define NONIUS_EXECUTION_PLAN_HPP - -// #included from: optimizer.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2016 by Martinho Fernandes <rmf@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Hinting the optimizer - -#define NONIUS_OPTIMIZER_HPP - -#if defined(NONIUS_MSVC) -# include <atomic> // atomic_thread_fence -#endif - -namespace nonius { -#if defined(NONIUS_GCC) || defined(NONIUS_CLANG) - template <typename T> - inline void keep_memory(T* p) { - asm volatile("" : : "g"(p) : "memory"); - } - inline void keep_memory() { - asm volatile("" : : : "memory"); - } - - namespace detail { - inline void optimizer_barrier() { keep_memory(); } - } // namespace detail -#elif defined(NONIUS_MSVC) - -#pragma optimize("", off) - template <typename T> - inline void keep_memory(T* p) { - // thanks @milleniumbug - } - // TODO equivalent keep_memory() -#pragma optimize("", on) - - namespace detail { - inline void optimizer_barrier() { - std::atomic_thread_fence(std::memory_order_seq_cst); - } - } // namespace detail - -#endif -} // namespace nonius - -// #included from: detail/benchmark_function.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Dumb std::function implementation for consistent call overhead - -#define NONIUS_DETAIL_BENCHMARK_FUNCTION_HPP - -// #included from: chronometer.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// User-facing chronometer - -#define NONIUS_CHRONOMETER_HPP - -// #included from: detail/complete_invoke.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Invoke with a special case for void - -#define NONIUS_DETAIL_COMPLETE_INVOKE_HPP - -#include <type_traits> -#include <utility> - -namespace nonius { - namespace detail { - template <typename T> - struct complete_type { using type = T; }; - template <> - struct complete_type<void> { struct type {}; }; - - template <typename T> - using CompleteType = typename complete_type<T>::type; - - template <typename Result> - struct complete_invoker { - template <typename Fun, typename... Args> - static Result invoke(Fun&& fun, Args&&... args) { - return std::forward<Fun>(fun)(std::forward<Args>(args)...); - } - }; - template <> - struct complete_invoker<void> { - template <typename Fun, typename... Args> - static CompleteType<void> invoke(Fun&& fun, Args&&... args) { - std::forward<Fun>(fun)(std::forward<Args>(args)...); - return {}; - } - }; - template <typename Sig> - using ResultOf = typename std::result_of<Sig>::type; - - // invoke and not return void :( - template <typename Fun, typename... Args> - CompleteType<ResultOf<Fun(Args...)>> complete_invoke(Fun&& fun, Args&&... args) { - return complete_invoker<ResultOf<Fun(Args...)>>::invoke(std::forward<Fun>(fun), std::forward<Args>(args)...); - } - } // namespace detail -} // namespace nonius - -#include <boost/lexical_cast.hpp> - -namespace nonius { - namespace detail { - struct chronometer_concept { - virtual void start() = 0; - virtual void finish() = 0; - virtual ~chronometer_concept() = default; - }; - template <typename Clock> - struct chronometer_model final : public chronometer_concept { - void start() override { started = Clock::now(); } - void finish() override { finished = Clock::now(); } - - Duration<Clock> elapsed() const { return finished - started; } - - TimePoint<Clock> started; - TimePoint<Clock> finished; - }; - } // namespace detail - - struct chronometer { - public: - template <typename Fun> - void measure(Fun&& fun) { measure(std::forward<Fun>(fun), detail::is_callable<Fun(int)>()); } - - int runs() const { return k; } - - chronometer(detail::chronometer_concept& meter, int k, const parameters& p) - : impl(&meter) - , k(k) - , params(&p) - {} - - template <typename Tag> - auto param() const -> typename Tag::type { - return params->get<Tag>(); - } - - private: - template <typename Fun> - void measure(Fun&& fun, std::false_type) { - measure([&fun](int) { fun(); }); - } - template <typename Fun> - void measure(Fun&& fun, std::true_type) { - impl->start(); - for(int i = 0; i < k; ++i) fun(i); - impl->finish(); - } - - detail::chronometer_concept* impl; - int k; - const parameters* params; - }; -} // namespace nonius - -#include <type_traits> -#include <utility> -#include <memory> - -namespace nonius { - namespace detail { - template <typename T> - using Decay = typename std::decay<T>::type; - template <typename T, typename U> - struct is_related - : std::is_same<Decay<T>, Decay<U>> {}; - - /// We need to reinvent std::function because every piece of code that might add overhead - /// in a measurement context needs to have consistent performance characteristics so that we - /// can account for it in the measurement. - /// Implementations of std::function with optimizations that aren't always applicable, like - /// small buffer optimizations, are not uncommon. - /// This is effectively an implementation of std::function without any such optimizations; - /// it may be slow, but it is consistently slow. - struct benchmark_function { - private: - struct concept { - virtual benchmark_function call(parameters params) const = 0; - virtual void call(chronometer meter) const = 0; - virtual concept* clone() const = 0; - virtual ~concept() = default; - }; - template <typename Fun> - struct model : public concept { - model(Fun&& fun) : fun(std::move(fun)) {} - model(Fun const& fun) : fun(fun) {} - - model<Fun>* clone() const override { return new model<Fun>(*this); } - - benchmark_function call(parameters params) const override { - return call(params, is_callable<Fun(parameters)>()); - } - benchmark_function call(parameters params, std::true_type) const { - return fun(params); - } - benchmark_function call(parameters, std::false_type) const { - return this->clone(); - } - - void call(chronometer meter) const override { - call(meter, is_callable<Fun(chronometer)>(), is_callable<Fun(parameters)>()); - } - void call(chronometer meter, std::true_type, std::false_type) const { - fun(meter); - } - void call(chronometer meter, std::false_type, std::false_type) const { - meter.measure(fun); - } - template <typename T> - void call(chronometer, T, std::true_type) const { - // the function should be prepared first - assert(false); - } - - Fun fun; - }; - - struct do_nothing { void operator()() const {} }; - - template <typename T> - benchmark_function(model<T>* c) : f(c) {} - - public: - benchmark_function() - : f(new model<do_nothing>{{}}) - {} - - template <typename Fun, - typename std::enable_if<!is_related<Fun, benchmark_function>::value, int>::type = 0> - benchmark_function(Fun&& fun) - : f(new model<typename std::decay<Fun>::type>(std::forward<Fun>(fun))) {} - - benchmark_function(benchmark_function&& that) - : f(std::move(that.f)) {} - - benchmark_function(benchmark_function const& that) - : f(that.f->clone()) {} - - benchmark_function& operator=(benchmark_function&& that) { - f = std::move(that.f); - return *this; - } - - benchmark_function& operator=(benchmark_function const& that) { - f.reset(that.f->clone()); - return *this; - } - - benchmark_function operator()(parameters params) const { return f->call(params); } - void operator()(chronometer meter) const { f->call(meter); } - private: - std::unique_ptr<concept> f; - }; - } // namespace detail -} // namespace nonius - -// #included from: detail/repeat.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// repeat algorithm - -#define NONIUS_DETAIL_REPEAT_HPP - -#include <type_traits> -#include <utility> - -namespace nonius { - namespace detail { - template <typename Fun> - struct repeater { - void operator()(int k) const { - for(int i = 0; i < k; ++i) { - fun(); - } - } - Fun fun; - }; - template <typename Fun> - repeater<typename std::decay<Fun>::type> repeat(Fun&& fun) { - return { std::forward<Fun>(fun) }; - } - } // namespace detail -} // namespace nonius - -// #included from: detail/run_for_at_least.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Run a function for a minimum amount of time - -#define NONIUS_RUN_FOR_AT_LEAST_HPP - -// #included from: detail/measure.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Measure - -#define NONIUS_DETAIL_MEASURE_HPP - -// #included from: detail/timing.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Timing - -#define NONIUS_DETAIL_TIMING_HPP - -#include <tuple> -#include <type_traits> - -namespace nonius { - template <typename Duration, typename Result> - struct timing { - Duration elapsed; - Result result; - int iterations; - }; - template <typename Clock, typename Sig> - using TimingOf = timing<Duration<Clock>, detail::CompleteType<detail::ResultOf<Sig>>>; -} // namespace nonius - -#include <utility> - -namespace nonius { - namespace detail { - template <typename Clock, typename Fun, typename... Args> - TimingOf<Clock, Fun(Args...)> measure(Fun&& fun, Args&&... args) { - auto start = Clock::now(); - auto&& r = detail::complete_invoke(fun, std::forward<Args>(args)...); - auto end = Clock::now(); - auto delta = end - start; - return { delta, std::forward<decltype(r)>(r), 1 }; - } - } // namespace detail -} // namespace nonius - -#include <utility> -#include <type_traits> - -namespace nonius { - namespace detail { - template <typename Clock, typename Fun> - TimingOf<Clock, Fun(int)> measure_one(Fun&& fun, int iters, const parameters&, std::false_type) { - return detail::measure<Clock>(fun, iters); - } - template <typename Clock, typename Fun> - TimingOf<Clock, Fun(chronometer)> measure_one(Fun&& fun, int iters, const parameters& params, std::true_type) { - detail::chronometer_model<Clock> meter; - auto&& result = detail::complete_invoke(fun, chronometer(meter, iters, params)); - - return { meter.elapsed(), std::move(result), iters }; - } - - template <typename Clock, typename Fun> - using run_for_at_least_argument_t = typename std::conditional<detail::is_callable<Fun(chronometer)>::value, chronometer, int>::type; - - struct optimized_away_error : std::exception { - const char* what() const NONIUS_NOEXCEPT override { - return "could not measure benchmark, maybe it was optimized away"; - } - }; - - template <typename Clock, typename Fun> - TimingOf<Clock, Fun(run_for_at_least_argument_t<Clock, Fun>)> run_for_at_least(const parameters& params, Duration<Clock> how_long, int seed, Fun&& fun) { - auto iters = seed; - while(iters < (1 << 30)) { - auto&& timing = measure_one<Clock>(fun, iters, params, detail::is_callable<Fun(chronometer)>()); - - if(timing.elapsed >= how_long) { - return { timing.elapsed, std::move(timing.result), iters }; - } - iters *= 2; - } - throw optimized_away_error{}; - } - } // namespace detail -} // namespace nonius - -namespace nonius { - template <typename Duration> - struct execution_plan { - int iterations_per_sample; - Duration estimated_duration; - parameters params; - detail::benchmark_function benchmark; - Duration warmup_time; - int warmup_iterations; - - template <typename Duration2> - operator execution_plan<Duration2>() const { - return { iterations_per_sample, estimated_duration, params, benchmark, warmup_time, warmup_iterations }; - } - - template <typename Clock> - std::vector<FloatDuration<Clock>> run(configuration cfg, environment<FloatDuration<Clock>> env) const { - // warmup a bit - detail::run_for_at_least<Clock>(params, chrono::duration_cast<nonius::Duration<Clock>>(warmup_time), warmup_iterations, detail::repeat(now<Clock>{})); - - std::vector<FloatDuration<Clock>> times; - times.reserve(cfg.samples); - std::generate_n(std::back_inserter(times), cfg.samples, [this, env]{ - detail::chronometer_model<Clock> model; - detail::optimizer_barrier(); - this->benchmark(chronometer(model, iterations_per_sample, params)); - detail::optimizer_barrier(); - auto sample_time = model.elapsed() - env.clock_cost.mean; - if(sample_time < FloatDuration<Clock>::zero()) sample_time = FloatDuration<Clock>::zero(); - return sample_time / iterations_per_sample; - }); - return times; - } - }; -} // namespace nonius - -// #included from: detail/unique_name.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Unique name generator macro - -#define NONIUS_DETAIL_UNIQUE_NAME_HPP - -#define NONIUS_DETAIL_UNIQUE_NAME_LINE_CAT(name, id) NONIUS_ ## name ## _ ## id -#define NONIUS_DETAIL_UNIQUE_NAME_LINE(name, id) NONIUS_DETAIL_UNIQUE_NAME_LINE_CAT(name, id) -#ifdef __COUNTER__ -#define NONIUS_DETAIL_UNIQUE_NAME(name) NONIUS_DETAIL_UNIQUE_NAME_LINE(name, __COUNTER__) -#else // __COUNTER__ -#define NONIUS_DETAIL_UNIQUE_NAME(name) NONIUS_DETAIL_UNIQUE_NAME_LINE(name, __LINE__) -#endif // __COUNTER__ - -#include <algorithm> -#include <functional> -#include <string> -#include <vector> -#include <cmath> - -namespace nonius { - namespace detail { - const auto warmup_iterations = 10000; - const auto warmup_time = chrono::milliseconds(100); - const auto minimum_ticks = 1000; - } // namespace detail - - struct benchmark { - benchmark(std::string name, detail::benchmark_function fun) - : name(std::move(name)), fun(std::move(fun)) {} - - template <typename Clock> - execution_plan<FloatDuration<Clock>> prepare(configuration cfg, parameters params, environment<FloatDuration<Clock>> env) const { - auto bench = fun(params); - auto min_time = env.clock_resolution.mean * detail::minimum_ticks; - auto run_time = std::max(min_time, chrono::duration_cast<decltype(min_time)>(detail::warmup_time)); - auto&& test = detail::run_for_at_least<Clock>(params, chrono::duration_cast<Duration<Clock>>(run_time), 1, bench); - int new_iters = static_cast<int>(std::ceil(min_time * test.iterations / test.elapsed)); - return { new_iters, test.elapsed / test.iterations * new_iters * cfg.samples, params, bench, chrono::duration_cast<FloatDuration<Clock>>(detail::warmup_time), detail::warmup_iterations }; - } - - std::string name; - detail::benchmark_function fun; - }; - - using benchmark_registry = std::vector<benchmark>; - - inline benchmark_registry& global_benchmark_registry() { - static benchmark_registry registry; - return registry; - } - - struct benchmark_registrar { - template <typename Fun> - benchmark_registrar(benchmark_registry& registry, std::string name, Fun&& registrant) { - registry.emplace_back(std::move(name), std::forward<Fun>(registrant)); - } - }; -} // namespace nonius - -#define NONIUS_BENCHMARK(name, ...) \ - namespace { static ::nonius::benchmark_registrar NONIUS_DETAIL_UNIQUE_NAME(benchmark_registrar) (::nonius::global_benchmark_registry(), name, __VA_ARGS__); } - -// #included from: constructor.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Constructor and destructor helpers - -#define NONIUS_CONSTRUCTOR_HPP - -#include <type_traits> - -namespace nonius { - namespace detail { - template <typename T, bool Destruct> - struct object_storage - { - typedef typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type TStorage; - - object_storage() : data() {} - - object_storage(const object_storage& other) - { - new(&data) T(other.stored_object()); - } - - object_storage(object_storage&& other) - { - new(&data) T(std::move(other.stored_object())); - } - - ~object_storage() { destruct_on_exit<T>(); } - - template <typename... Args> - void construct(Args&&... args) - { - new (&data) T(std::forward<Args>(args)...); - } - - template <bool AllowManualDestruction = !Destruct> - typename std::enable_if<AllowManualDestruction>::type destruct() - { - stored_object().~T(); - } - - private: - // If this is a constructor benchmark, destruct the underlying object - template <typename U> - void destruct_on_exit(typename std::enable_if<Destruct, U>::type* = 0) { destruct<true>(); } - // Otherwise, don't - template <typename U> - void destruct_on_exit(typename std::enable_if<!Destruct, U>::type* = 0) { } - - T& stored_object() - { - return *static_cast<T*>(static_cast<void*>(&data)); - } - - TStorage data; - }; - } - - template <typename T> - using storage_for = detail::object_storage<T, true>; - - template <typename T> - using destructable_object = detail::object_storage<T, false>; -} - -// #included from: go.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Runner entry point - -#define NONIUS_GO_HPP - -// #included from: reporter.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Reporter interface - -#define NONIUS_REPORTER_HPP - -// #included from: sample_analysis.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Benchmark results - -#define NONIUS_BENCHMARK_RESULTS_HPP - -// #included from: estimate.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Statistics estimates - -#define NONIUS_ESTIMATE_HPP - -namespace nonius { - template <typename Duration> - struct estimate { - Duration point; - Duration lower_bound; - Duration upper_bound; - double confidence_interval; - - template <typename Duration2> - operator estimate<Duration2>() const { - return { point, lower_bound, upper_bound, confidence_interval }; - } - }; -} // namespace nonius - -#include <algorithm> -#include <vector> -#include <string> -#include <iterator> - -namespace nonius { - template <typename Duration> - struct sample_analysis { - std::vector<Duration> samples; - estimate<Duration> mean; - estimate<Duration> standard_deviation; - outlier_classification outliers; - double outlier_variance; - - template <typename Duration2> - operator sample_analysis<Duration2>() const { - std::vector<Duration2> samples2; - samples2.reserve(samples.size()); - std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](Duration d) { return Duration2(d); }); - return { - std::move(samples2), - mean, - standard_deviation, - outliers, - outlier_variance, - }; - } - }; -} // namespace nonius - -#include <vector> -#include <string> -#include <ios> -#include <ostream> -#include <fstream> -#include <iostream> -#include <memory> -#include <unordered_map> -#include <exception> - -namespace nonius { - struct bad_stream : virtual std::exception { - char const* what() const NONIUS_NOEXCEPT override { - return "failed to open file"; - } - }; - - struct reporter { - public: - virtual ~reporter() = default; - - void configure(configuration& cfg) { - if(cfg.output_file.empty()) { - os = [&]() -> std::ostream& { return std::cout; }; - } else { - auto ofs = std::make_shared<std::ofstream>(cfg.output_file); - os = [ofs]() -> std::ostream& { return *ofs; }; - } - report_stream().exceptions(std::ios::failbit); - if(!report_stream()) throw bad_stream(); - do_configure(cfg); - } - - void warmup_start() { - do_warmup_start(); - } - void warmup_end(int iterations) { - do_warmup_end(iterations); - } - void estimate_clock_resolution_start() { - do_estimate_clock_resolution_start(); - } - void estimate_clock_resolution_complete(environment_estimate<fp_seconds> estimate) { - do_estimate_clock_resolution_complete(estimate); - } - - void estimate_clock_cost_start() { - do_estimate_clock_cost_start(); - } - void estimate_clock_cost_complete(environment_estimate<fp_seconds> estimate) { - do_estimate_clock_cost_complete(estimate); - } - - void suite_start() { - do_suite_start(); - } - void params_start(parameters const& params) { - do_params_start(params); - } - void benchmark_start(std::string const& name) { - do_benchmark_start(name); - } - - void measurement_start(execution_plan<fp_seconds> plan) { - do_measurement_start(plan); - } - void measurement_complete(std::vector<fp_seconds> const& samples) { - do_measurement_complete(samples); - } - - void analysis_start() { - do_analysis_start(); - } - void analysis_complete(sample_analysis<fp_seconds> const& analysis) { - do_analysis_complete(analysis); - } - - void benchmark_failure(std::exception_ptr error) { - do_benchmark_failure(error); - } - void benchmark_complete() { - do_benchmark_complete(); - } - - void params_complete() { - do_params_complete(); - } - void suite_complete() { - do_suite_complete(); - } - - virtual std::string description() = 0; - - private: - virtual void do_configure(configuration& /*cfg*/) {} - - virtual void do_warmup_start() {} - virtual void do_warmup_end(int /*iterations*/) {} - - virtual void do_estimate_clock_resolution_start() {} - virtual void do_estimate_clock_resolution_complete(environment_estimate<fp_seconds> /*estimate*/) {} - - virtual void do_estimate_clock_cost_start() {} - virtual void do_estimate_clock_cost_complete(environment_estimate<fp_seconds> /*estimate*/) {} - - virtual void do_suite_start() {} - virtual void do_params_start(parameters const& /*params*/) {} - virtual void do_benchmark_start(std::string const& /*name*/) {} - - virtual void do_measurement_start(execution_plan<fp_seconds> /*plan*/) {} - virtual void do_measurement_complete(std::vector<fp_seconds> const& /*samples*/) {} - - virtual void do_analysis_start() {} // TODO make generic? - virtual void do_analysis_complete(sample_analysis<fp_seconds> const& /*analysis*/) {} - - virtual void do_benchmark_failure(std::exception_ptr /*error*/) {} - virtual void do_benchmark_complete() {} - virtual void do_params_complete() {} - virtual void do_suite_complete() {} - - protected: - std::ostream& progress_stream() { - return std::cout; - } - std::ostream& error_stream() { - return std::cerr; - } - std::ostream& report_stream() { - return os(); - } - - private: - std::function<std::ostream&()> os; - }; - - using reporter_registry = std::unordered_map<std::string, std::unique_ptr<reporter>>; - - inline reporter_registry& global_reporter_registry() { - static reporter_registry registry; - return registry; - } - - struct reporter_registrar { - reporter_registrar(reporter_registry& registry, std::string name, reporter* registrant) { - registry.emplace(std::move(name), std::unique_ptr<reporter>(registrant)); - } - }; -} // namespace nonius - -#define NONIUS_REPORTER(name, ...) \ - namespace { static ::nonius::reporter_registrar NONIUS_DETAIL_UNIQUE_NAME(reporter_registrar) (::nonius::global_reporter_registry(), name, new __VA_ARGS__()); } \ - static_assert(true, "") - -// #included from: reporters/standard_reporter.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Standard reporter - -#define NONIUS_REPORTERS_STANDARD_REPORTER_HPP - -// #included from: detail/pretty_print.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Pretty printing routines - -#define NONIUS_DETAIL_PRETTY_PRINT_HPP - -#include <ratio> -#include <ios> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <string> -#include <memory> -#include <utility> - -namespace nonius { - namespace detail { - inline double get_magnitude(fp_seconds secs) { - if(secs.count() >= 2.e0) { - return 1.e0; - } else if(secs.count() >= 2.e-3) { - return 1.e3; - } else if(secs.count() >= 2.e-6) { - return 1.e6; - } else { - return 1.e9; - } - } - inline std::string units_for_magnitude(double magnitude) { - if(magnitude <= 1.e0) return "s"; - else if(magnitude <= 1.e3) return "ms"; - else if(magnitude <= 1.e6) return "ฮผs"; - else return "ns"; - } - inline std::string pretty_duration(fp_seconds secs) { - auto magnitude = get_magnitude(secs); - auto units = units_for_magnitude(magnitude); -#ifdef NONIUS_MSVC - if(units == "ฮผs") units = "us"; -#endif - std::ostringstream ss; - ss << std::setprecision(ss.precision()); - ss << (secs.count() * magnitude) << ' ' << units; - return ss.str(); - } - inline std::string percentage(double d) { - std::ostringstream ss; - ss << std::setprecision(3); - if(d != 0 && d < 1e-5) { - ss << std::fixed; - ss << 0.0001 << "%"; - } else { - ss.unsetf(std::ios::floatfield); - ss << (100. * d) << "%"; - } - return ss.str(); - } - inline std::string percentage_ratio(double part, double whole) { - return percentage(part / whole); - } - } // namespace detail -} // namespace nonius - -#include <ratio> -#include <ios> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <string> -#include <memory> - -namespace nonius { - struct standard_reporter : reporter { - private: - std::string description() override { - return "the standard reporter"; - } - - void do_configure(configuration& cfg) override { - n_samples = cfg.samples; - verbose = cfg.verbose; - summary = cfg.summary; - n_resamples = cfg.resamples; - if(!summary && !cfg.params.map.empty()) report_stream() << "parameters\n" << cfg.params.map; - } - - void do_warmup_start() override { - if(verbose) report_stream() << "warming up\n"; - } - void do_estimate_clock_resolution_start() override { - if(verbose) report_stream() << "estimating clock resolution\n"; - } - void do_estimate_clock_resolution_complete(environment_estimate<fp_seconds> estimate) override { - if(!summary) { - if(!verbose) report_stream() << "clock resolution: "; - print_environment_estimate(estimate, estimate.outliers.samples_seen + 2); - } - } - - void do_estimate_clock_cost_start() override { - if(verbose) report_stream() << "estimating cost of a clock call\n"; - } - void do_estimate_clock_cost_complete(environment_estimate<fp_seconds> estimate) override { - if(verbose) print_environment_estimate(estimate, estimate.outliers.samples_seen); - } - - void do_params_start(parameters const& params) override { - if(!summary && !params.empty()) report_stream() << "\n\nnew round for parameters\n" << params; - } - void do_benchmark_start(std::string const& name) override { - report_stream() << '\n'; - if(!summary) report_stream() << "benchmarking "; - report_stream() << name << "\n"; - current = name; - } - - void do_measurement_start(execution_plan<fp_seconds> plan) override { - report_stream() << std::setprecision(7); - report_stream().unsetf(std::ios::floatfield); - if(!summary) report_stream() << "collecting " << n_samples << " samples, " << plan.iterations_per_sample << " iterations each, in estimated " << detail::pretty_duration(plan.estimated_duration) << "\n"; - } - void do_analysis_start() override { - if(verbose) report_stream() << "bootstrapping with " << n_resamples << " resamples\n"; - } - void do_benchmark_failure(std::exception_ptr eptr) override { - error_stream() << current << " failed to run successfully\n"; - if(!summary) { - try { - std::rethrow_exception(eptr); - } catch(std::exception& ex) { - error_stream() << "error: " << ex.what(); - } catch(...) { - error_stream() << "unknown error"; - } - } - report_stream() << "\nbenchmark aborted\n"; - } - void do_analysis_complete(sample_analysis<fp_seconds> const& analysis) override { - print_statistic_estimate("mean", analysis.mean); - print_statistic_estimate("std dev", analysis.standard_deviation); - if(!summary) print_outliers(analysis.outliers); - if(verbose) report_stream() << "variance introduced by outliers: " << detail::percentage(analysis.outlier_variance) << "\n"; - const char* effect; - if(analysis.outlier_variance < 0.01) { - effect = "unaffected"; - } else if(analysis.outlier_variance < 0.1) { - effect = "slightly inflated"; - } else if(analysis.outlier_variance < 0.5) { - effect = "moderately inflated"; - } else { - effect = "severely inflated"; - } - report_stream() << "variance is " << effect << " by outliers\n"; - } - - void print_environment_estimate(environment_estimate<fp_seconds> e, int iterations) { - report_stream() << std::setprecision(7); - report_stream().unsetf(std::ios::floatfield); - report_stream() << "mean is " << detail::pretty_duration(e.mean) << " (" << iterations << " iterations)\n"; - if(verbose) print_outliers(e.outliers); - } - void print_outlier_count(const char* description, int count, int total) { - if(count > 0) report_stream() << " " << count << " (" << detail::percentage_ratio(count, total) << ") " << description << "\n"; - } - void print_outliers(outlier_classification o) { - report_stream() << "found " << o.total() << " outliers among " << o.samples_seen << " samples (" << detail::percentage_ratio(o.total(), o.samples_seen) << ")\n"; - if(verbose) { - print_outlier_count("low severe", o.low_severe, o.samples_seen); - print_outlier_count("low mild", o.low_mild, o.samples_seen); - print_outlier_count("high mild", o.high_mild, o.samples_seen); - print_outlier_count("high severe", o.high_severe, o.samples_seen); - } - } - void print_statistic_estimate(const char* name, estimate<fp_seconds> estimate) { - report_stream() << std::setprecision(7); - report_stream().unsetf(std::ios::floatfield); - report_stream() << name << ": " << detail::pretty_duration(estimate.point); - if(!summary) { - report_stream() << ", lb " << detail::pretty_duration(estimate.lower_bound) - << ", ub " << detail::pretty_duration(estimate.upper_bound) - << ", ci " << std::setprecision(3) << estimate.confidence_interval; - } - report_stream() << "\n"; - } - - int n_samples = 0; - int n_resamples = 0; - bool verbose = false; - bool summary = false; - - std::string current; - }; - - NONIUS_REPORTER("", standard_reporter); - NONIUS_REPORTER("standard", standard_reporter); -} // namespace nonius - -// #included from: detail/estimate_clock.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Environment measurement - -#define NONIUS_DETAIL_ENVIRONMENT_HPP - -// #included from: detail/stats.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Statistical analysis tools - -#define NONIUS_DETAIL_ANALYSIS_HPP - -#include <boost/math/distributions/normal.hpp> - -#include <algorithm> -#include <functional> -#include <iterator> -#include <vector> -#include <array> -#include <random> -#include <numeric> -#include <tuple> -#include <cmath> -#include <utility> -#include <future> -#include <cstddef> - -namespace nonius { - namespace detail { - using sample = std::vector<double>; - - template <typename Iterator> - double weighted_average_quantile(int k, int q, Iterator first, Iterator last) { - auto count = last - first; - double idx = (count - 1) * k /static_cast<double>(q); - int j = static_cast<int>(idx); - double g = idx - j; - std::nth_element(first, first+j, last); - auto xj = first[j]; - if(g == 0) return xj; - - auto xj1 = *std::min_element(first+(j+1), last); - return xj + g * (xj1 - xj); - } - - template <typename Iterator> - outlier_classification classify_outliers(Iterator first, Iterator last) { - std::vector<double> copy(first, last); - - auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end()); - auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end()); - auto iqr = q3 - q1; - auto los = q1 - (iqr * 3.); - auto lom = q1 - (iqr * 1.5); - auto him = q3 + (iqr * 1.5); - auto his = q3 + (iqr * 3.); - - outlier_classification o; - for(; first != last; ++first) { - auto&& t = *first; - if(t < los) ++o.low_severe; - else if(t < lom) ++o.low_mild; - else if(t > his) ++o.high_severe; - else if(t > him) ++o.high_mild; - ++o.samples_seen; - } - return o; - } - - template <typename Iterator> - double mean(Iterator first, Iterator last) { - auto count = last - first; - double sum = std::accumulate(first, last, 0.); - return sum / count; - } - - template <typename Iterator> - double standard_deviation(Iterator first, Iterator last) { - auto m = mean(first, last); - double variance = std::accumulate(first, last, 0., [m](double a, double b) { - double diff = b - m; - return a + diff*diff; - }) / (last - first); - return std::sqrt(variance); - } - - template <typename URng, typename Iterator, typename Estimator> - sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) { - auto n = last - first; - std::uniform_int_distribution<decltype(n)> dist(0, n-1); - - sample out; - out.reserve(resamples); - std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] { - std::vector<double> resampled; - resampled.reserve(n); - std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; }); - return estimator(resampled.begin(), resampled.end()); - }); - std::sort(out.begin(), out.end()); - return out; - } - - template <typename Estimator, typename Iterator> - sample jackknife(Estimator&& estimator, Iterator first, Iterator last) { - auto n = last - first; - auto second = std::next(first); - sample results; - results.reserve(n); - - for(auto it = first; it != last; ++it) { - std::iter_swap(it, first); - results.push_back(estimator(second, last)); - } - - return results; - } - - template <typename Iterator, typename Estimator> - estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) { - namespace bm = boost::math; - - auto n_samples = last - first; - - double point = estimator(first, last); - // Degenerate case with a single sample - if(n_samples == 1) return { point, point, point, confidence_level }; - - sample jack = jackknife(estimator, first, last); - double jack_mean = mean(jack.begin(), jack.end()); - double sum_squares, sum_cubes; - std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> { - auto d = jack_mean - x; - auto d2 = d * d; - auto d3 = d2 * d; - return { sqcb.first + d2, sqcb.second + d3 }; - }); - - double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5)); - int n = static_cast<int>(resample.size()); - double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) /(double) n; - // degenerate case with uniform samples - if(prob_n == 0) return { point, point, point, confidence_level }; - - double bias = bm::quantile(bm::normal{}, prob_n); - double z1 = bm::quantile(bm::normal{}, (1. - confidence_level) / 2.); - - auto cumn = [n](double x) -> int { return std::lround(bm::cdf(bm::normal{}, x) * n); }; - auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); }; - double b1 = bias + z1; - double b2 = bias - z1; - double a1 = a(b1); - double a2 = a(b2); - auto lo = std::max(cumn(a1), 0); - auto hi = std::min(cumn(a2), n - 1); - - return { point, resample[lo], resample[hi], confidence_level }; - } - - inline double outlier_variance(estimate<double> mean, estimate<double> stddev, int n) { - double sb = stddev.point; - double mn = mean.point / n; - double mg_min = mn / 2.; - double sg = std::min(mg_min / 4., sb / std::sqrt(n)); - double sg2 = sg * sg; - double sb2 = sb * sb; - - auto c_max = [n, mn, sb2, sg2](double x) -> double { - double k = mn - x; - double d = k * k; - double nd = n * d; - double k0 = -n * nd; - double k1 = sb2 - n * sg2 + nd; - double det = k1 * k1 - 4 * sg2 * k0; - return (int)(-2. * k0 / (k1 + std::sqrt(det))); - }; - - auto var_out = [n, sb2, sg2](double c) { - double nc = n - c; - return (nc / n) * (sb2 - nc * sg2); - }; - - return std::min(var_out(1), var_out(std::min(c_max(0.), c_max(mg_min)))) / sb2; - } - - struct bootstrap_analysis { - estimate<double> mean; - estimate<double> standard_deviation; - double outlier_variance; - }; - - template <typename Iterator> - bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, Iterator first, Iterator last) { - static std::random_device entropy; - - auto n = static_cast<int>(last - first); // seriously, one can't use integral types without hell in C++ - - auto mean = &detail::mean<Iterator>; - auto stddev = &detail::standard_deviation<Iterator>; - - auto estimate = [=](double(*f)(Iterator, Iterator)) { - auto seed = entropy(); - return std::async(std::launch::async, [=]{ - std::mt19937 rng(seed); - auto resampled = resample(rng, n_resamples, first, last, f); - return bootstrap(confidence_level, first, last, resampled, f); - }); - }; - - auto mean_future = estimate(mean); - auto stddev_future = estimate(stddev); - - auto mean_estimate = mean_future.get(); - auto stddev_estimate = stddev_future.get(); - - double outlier_variance = detail::outlier_variance(mean_estimate, stddev_estimate, n); - - return { mean_estimate, stddev_estimate, outlier_variance }; - } - } // namespace detail -} // namespace nonius - -#include <algorithm> -#include <iterator> -#include <tuple> -#include <vector> -#include <cmath> - -namespace nonius { - namespace detail { - template <typename Clock> - std::vector<double> resolution(int k) { - std::vector<TimePoint<Clock>> times; - times.reserve(k+1); - std::generate_n(std::back_inserter(times), k+1, now<Clock>{}); - - std::vector<double> deltas; - deltas.reserve(k); - std::transform(std::next(times.begin()), times.end(), times.begin(), - std::back_inserter(deltas), - [](TimePoint<Clock> a, TimePoint<Clock> b) { return static_cast<double>((a - b).count()); }); - - return deltas; - } - - const auto warmup_seed = 10000; - const auto clock_resolution_estimation_time = chrono::milliseconds(500); - const auto clock_cost_estimation_time_limit = chrono::seconds(1); - const auto clock_cost_estimation_tick_limit = 100000; - const auto clock_cost_estimation_time = chrono::milliseconds(10); - const auto clock_cost_estimation_iterations = 10000; - - template <typename Clock> - int warmup() { - return run_for_at_least<Clock>({}, chrono::duration_cast<Duration<Clock>>(warmup_time), warmup_seed, &resolution<Clock>) - .iterations; - } - template <typename Clock> - environment_estimate<FloatDuration<Clock>> estimate_clock_resolution(int iterations) { - auto r = run_for_at_least<Clock>({}, chrono::duration_cast<Duration<Clock>>(clock_resolution_estimation_time), iterations, &resolution<Clock>) - .result; - return { - FloatDuration<Clock>(mean(r.begin(), r.end())), - classify_outliers(r.begin(), r.end()), - }; - } - template <typename Clock> - environment_estimate<FloatDuration<Clock>> estimate_clock_cost(FloatDuration<Clock> resolution) { - auto time_limit = std::min(resolution * clock_cost_estimation_tick_limit, FloatDuration<Clock>(clock_cost_estimation_time_limit)); - auto time_clock = [](int k) { - return detail::measure<Clock>([k]{ - for(int i = 0; i < k; ++i) { - volatile auto ignored = Clock::now(); - (void)ignored; - } - }).elapsed; - }; - time_clock(1); - int iters = clock_cost_estimation_iterations; - auto&& r = run_for_at_least<Clock>({}, chrono::duration_cast<Duration<Clock>>(clock_cost_estimation_time), iters, time_clock); - std::vector<double> times; - int nsamples = static_cast<int>(std::ceil(time_limit / r.elapsed)); - times.reserve(nsamples); - std::generate_n(std::back_inserter(times), nsamples, [time_clock, &r]{ - return (time_clock(r.iterations) / r.iterations).count(); - }); - return { - FloatDuration<Clock>(mean(times.begin(), times.end())), - classify_outliers(times.begin(), times.end()), - }; - } - } // namespace detail -} // namespace nonius - -// #included from: detail/analyse.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Run and analyse one benchmark - -#define NONIUS_DETAIL_ANALYSE_HPP - -#include <algorithm> -#include <iterator> -#include <vector> - -namespace nonius { - namespace detail { - template <typename Duration, typename Iterator> - sample_analysis<Duration> analyse(configuration cfg, environment<Duration>, Iterator first, Iterator last) { - std::vector<double> samples; - samples.reserve(last - first); - std::transform(first, last, std::back_inserter(samples), [](Duration d) { return d.count(); }); - - auto analysis = nonius::detail::analyse_samples(cfg.confidence_interval, cfg.resamples, samples.begin(), samples.end()); - auto outliers = nonius::detail::classify_outliers(samples.begin(), samples.end()); - - auto wrap_estimate = [](estimate<double> e) { - return estimate<Duration> { - Duration(e.point), - Duration(e.lower_bound), - Duration(e.upper_bound), - e.confidence_interval, - }; - }; - std::vector<Duration> samples2; - samples2.reserve(samples.size()); - std::transform(samples.begin(), samples.end(), std::back_inserter(samples2), [](double d) { return Duration(d); }); - return { - std::move(samples2), - wrap_estimate(analysis.mean), - wrap_estimate(analysis.standard_deviation), - outliers, - analysis.outlier_variance, - }; - } - } // namespace detail -} // namespace nonius - -#include <algorithm> -#include <set> -#include <exception> -#include <utility> -#include <regex> - -namespace nonius { - namespace detail { - template <typename Clock> - environment<FloatDuration<Clock>> measure_environment(reporter& rep) { - rep.warmup_start(); - auto iters = detail::warmup<Clock>(); - rep.warmup_end(iters); - - rep.estimate_clock_resolution_start(); - auto resolution = detail::estimate_clock_resolution<Clock>(iters); - rep.estimate_clock_resolution_complete(resolution); - - rep.estimate_clock_cost_start(); - auto cost = detail::estimate_clock_cost<Clock>(resolution.mean); - rep.estimate_clock_cost_complete(cost); - - return { resolution, cost }; - } - } // namespace detail - - struct benchmark_user_error : virtual std::exception { - char const* what() const NONIUS_NOEXCEPT override { - return "a benchmark failed to run successfully"; - } - }; - - struct skip_error : virtual std::exception { - const char* what() const NONIUS_NOEXCEPT override { - return "benchmark was skipped"; - } - }; - - inline void skip() { - throw skip_error{}; - } - - inline std::vector<parameters> generate_params(param_configuration cfg) { - auto params = global_param_registry().defaults().merged(cfg.map); - if (!cfg.run) { - return {params}; - } else { - using operation_t = std::function<param(param, param)>; - - auto&& run = *cfg.run; - auto step = run.step; - auto oper = std::unordered_map<std::string, operation_t> { - {"+", std::plus<param>{}}, - {"*", std::multiplies<param>{}}, - }.at(run.op); - - auto r = std::vector<parameters>{}; - auto next = run.init; - std::generate_n(std::back_inserter(r), std::max(run.count, std::size_t{1}), [&] { - auto last = next; - next = oper(next, step); - return params.merged(parameters{{run.name, last}}); - }); - - return r; - } - } - - template <typename Iterator> - std::vector<benchmark> filter_benchmarks(Iterator first, Iterator last, std::string pattern) { - auto r = std::vector<benchmark>{}; - auto matcher = std::regex{pattern}; - std::copy_if(first, last, std::back_inserter(r), [&] (benchmark const& b) { - return std::regex_match(b.name, matcher); - }); - return r; - } - - template <typename Clock = default_clock, typename Iterator> - void go(configuration cfg, Iterator first, Iterator last, reporter& rep) { - rep.configure(cfg); - - auto env = detail::measure_environment<Clock>(rep); - rep.suite_start(); - - auto benchmarks = filter_benchmarks(first, last, cfg.filter_pattern); - auto all_params = generate_params(cfg.params); - - for (auto&& params : all_params) { - rep.params_start(params); - for (auto&& bench : benchmarks) { - rep.benchmark_start(bench.name); - try { - auto plan = bench.template prepare<Clock>(cfg, params, env); - - rep.measurement_start(plan); - auto samples = plan.template run<Clock>(cfg, env); - rep.measurement_complete(std::vector<fp_seconds>(samples.begin(), samples.end())); - - if(!cfg.no_analysis) { - rep.analysis_start(); - auto analysis = detail::analyse(cfg, env, samples.begin(), samples.end()); - rep.analysis_complete(analysis); - } - rep.benchmark_complete(); - } catch (...) { - rep.benchmark_failure(std::current_exception()); - } - } - rep.params_complete(); - } - - rep.suite_complete(); - } - struct duplicate_benchmarks : virtual std::exception { - char const* what() const NONIUS_NOEXCEPT override { - return "two or more benchmarks with the same name were registered"; - } - }; - template <typename Clock = default_clock, typename Iterator> - void validate_benchmarks(Iterator first, Iterator last) { - struct strings_lt_through_pointer { - bool operator()(std::string* a, std::string* b) const { return *a < *b; }; - }; - std::set<std::string*, strings_lt_through_pointer> names; - for(; first != last; ++first) { - if(!names.insert(&first->name).second) - throw duplicate_benchmarks(); - } - } - template <typename Clock = default_clock, typename Iterator> - void go(configuration cfg, Iterator first, Iterator last, reporter&& rep) { - go<Clock>(cfg, first, last, rep); - } - struct no_such_reporter : virtual std::exception { - char const* what() const NONIUS_NOEXCEPT override { - return "reporter could not be found"; - } - }; - template <typename Clock = default_clock> - void go(configuration cfg, benchmark_registry& benchmarks = global_benchmark_registry(), reporter_registry& reporters = global_reporter_registry()) { - auto it = reporters.find(cfg.reporter); - if(it == reporters.end()) throw no_such_reporter(); - validate_benchmarks<Clock>(benchmarks.begin(), benchmarks.end()); - go<Clock>(cfg, benchmarks.begin(), benchmarks.end(), *it->second); - } -} // namespace nonius - -#ifndef NONIUS_DISABLE_EXTRA_REPORTERS -#ifndef NONIUS_DISABLE_CSV_REPORTER -// #included from: reporters/csv_reporter.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// CSV raw data reporter - -#define NONIUS_REPORTERS_CSV_REPORTER_HPP - -#include <ios> -#include <iomanip> -#include <algorithm> -#include <string> -#include <iterator> -#include <limits> -#include <unordered_map> -#include <vector> - -namespace nonius { - struct csv_reporter : reporter { - private: - std::string description() override { - return "outputs samples to a CSV file"; - } - - void do_configure(configuration& cfg) override { - cfg.no_analysis = true; - n_samples = cfg.samples; - verbose = cfg.verbose; - } - - void do_warmup_start() override { - if(verbose) progress_stream() << "warming up\n"; - } - void do_estimate_clock_resolution_start() override { - if(verbose) progress_stream() << "estimating clock resolution\n"; - } - void do_estimate_clock_cost_start() override { - if(verbose) progress_stream() << "estimating cost of a clock call\n"; - } - - void do_benchmark_start(std::string const& name) override { - if(verbose) progress_stream() << "\nbenchmarking " << name << "\n"; - current = name; - } - - void do_measurement_start(execution_plan<fp_seconds> plan) override { - report_stream() << std::setprecision(7); - report_stream().unsetf(std::ios::floatfield); - if(verbose) progress_stream() << "collecting " << n_samples << " samples, " << plan.iterations_per_sample << " iterations each, in estimated " << detail::pretty_duration(plan.estimated_duration) << "\n"; - } - void do_measurement_complete(std::vector<fp_seconds> const& samples) override { - data[current] = samples; - } - - void do_benchmark_failure(std::exception_ptr) override { - error_stream() << current << " failed to run successfully\n"; - } - - void do_suite_complete() override { - if(verbose) progress_stream() << "\ngenerating CSV report\n"; - report_stream() << std::fixed; - report_stream().precision(std::numeric_limits<double>::digits10); - bool first = true; - for(auto&& kv : data) { - if(!first) report_stream() << ","; - report_stream() << "\"" << escape(kv.first) << "\""; // TODO escape - first = false; - } - report_stream() << "\n"; - for(int i = 0; i < n_samples; ++i) { - first = true; - for(auto&& kv : data) { - if(!first) report_stream() << ","; - report_stream() << kv.second[i].count(); - first = false; - } - report_stream() << "\n"; - } - if(verbose) progress_stream() << "done\n"; - } - - private: - static std::string escape(std::string const& source) { - auto first = source.begin(); - auto last = source.end(); - - auto quotes = std::count(first, last, '"'); - if(quotes == 0) return source; - - std::string escaped; - escaped.reserve(source.size() + quotes); - - while(first != last) { - auto next_quote = std::find(first, last, '"'); - std::copy(first, next_quote, std::back_inserter(escaped)); - first = next_quote; - if(first != last) { - ++first; - escaped.push_back('"'); - escaped.push_back('"'); - } - } - - return escaped; - } - - int n_samples; - bool verbose; - std::string current; - std::unordered_map<std::string, std::vector<fp_seconds>> data; - }; - - NONIUS_REPORTER("csv", csv_reporter); -} // namespace nonius - -#endif // NONIUS_DISABLE_CSV_REPORTER -#ifndef NONIUS_DISABLE_JUNIT_REPORTER -// #included from: reporters/junit_reporter.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// JUnit reporter - -#define NONIUS_REPORTERS_JUNIT_REPORTER_HPP - -// #included from: detail/escape.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// General escaping routines - -#define NONIUS_DETAIL_ESCAPE_HPP - -#include <string> -#include <algorithm> -#include <iterator> -#include <utility> - -namespace nonius { - namespace detail { - inline std::string escape(std::string const& source, std::unordered_map<char, std::string> const& escapes) { - std::string magic; - magic.reserve(escapes.size()); - std::transform(escapes.begin(), escapes.end(), std::back_inserter(magic), [](std::pair<char const, std::string> const& p) { return p.first; }); - - auto first = source.begin(); - auto last = source.end(); - - auto n_magic = std::count_if(first, last, [&magic](char c) { return magic.find(c) != std::string::npos; }); - - std::string escaped; - escaped.reserve(source.size() + n_magic*6); - - while(first != last) { - auto next_magic = std::find_first_of(first, last, magic.begin(), magic.end()); - std::copy(first, next_magic, std::back_inserter(escaped)); - first = next_magic; - if(first != last) { - auto it = escapes.find(*first); - if(it != escapes.end()) { - escaped += it->second; - } - ++first; - } - } - return escaped; - } - } // namespace detail -} // namespace nonius - -#include <ios> -#include <iomanip> -#include <algorithm> -#include <string> -#include <iterator> -#include <limits> -#include <unordered_map> -#include <vector> -#include <exception> - -namespace nonius { - struct junit_reporter : reporter { - private: - std::string description() override { - return "outputs results to a JUnit-compatible XML file"; - } - - void do_configure(configuration& cfg) override { - n_samples = cfg.samples; - confidence_interval = cfg.confidence_interval; - resamples = cfg.resamples; - verbose = cfg.verbose; - title = cfg.title; - } - - struct result { - sample_analysis<fp_seconds> analysis; - std::exception_ptr failure; - }; - - void do_warmup_start() override { - if(verbose) progress_stream() << "warming up\n"; - } - void do_estimate_clock_resolution_start() override { - if(verbose) progress_stream() << "estimating clock resolution\n"; - } - void do_estimate_clock_cost_start() override { - if(verbose) progress_stream() << "estimating cost of a clock call\n"; - } - - void do_benchmark_start(std::string const& name) override { - if(verbose) progress_stream() << "\nbenchmarking " << name << "\n"; - current = name; - } - - void do_measurement_start(execution_plan<fp_seconds> plan) override { - report_stream() << std::setprecision(7); - report_stream().unsetf(std::ios::floatfield); - if(verbose) progress_stream() << "collecting " << n_samples << " samples, " << plan.iterations_per_sample << " iterations each, in estimated " << detail::pretty_duration(plan.estimated_duration) << "\n"; - } - - void do_analysis_start() override { - if(verbose) report_stream() << "analysing samples\n"; - } - void do_analysis_complete(sample_analysis<fp_seconds> const& analysis) override { - data[current] = { analysis, nullptr }; - } - - void do_benchmark_failure(std::exception_ptr e) override { - data[current] = { sample_analysis<fp_seconds>(), e }; - error_stream() << current << " failed to run successfully\n"; - } - - void do_suite_complete() override { - if(verbose) progress_stream() << "\ngenerating JUnit report\n"; - - report_stream() << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; - report_stream() << "<testsuite name=\"" << escape(title) << "\" tests=\"" << data.size() << "\""; - auto failures = std::count_if(data.begin(), data.end(), - [](std::pair<std::string const&, result> const& p) { - return static_cast<bool>(p.second.failure); - }); - if(failures > 0) report_stream() << " errors=\"" << failures << "\""; - report_stream() << ">\n"; - - report_stream() << " <properties>\n"; - report_stream() << " <property name=\"samples\" value=\"" << n_samples << "\">\n"; - report_stream() << " <property name=\"confidence_interval\" value=\"" << std::setprecision(3) << confidence_interval << "\">\n"; - report_stream() << " <property name=\"resamples\" value=\"" << resamples << "\">\n"; - report_stream() << " </properties>\n"; - - for(auto tc : data) { - report_stream() << " <testcase name=\"" << escape(tc.first) << "\""; - if(tc.second.failure) { - report_stream() << ">\n"; - try { - std::rethrow_exception(tc.second.failure); - } catch(std::exception const& e) { - report_stream() << " <error message=\"" << escape(e.what()) << "\" />\n"; - } catch(...) { - report_stream() << " <error message=\"unknown error\" />\n"; - } - report_stream() << " </testcase>\n"; - } else { - report_stream() << std::fixed; - report_stream().precision(std::numeric_limits<double>::digits10); - report_stream() << " time=\"" << tc.second.analysis.mean.point.count() << "\" />\n"; - } - } - - report_stream() << "</testsuite>\n"; - - report_stream() << std::flush; - - if(verbose) progress_stream() << "done\n"; - } - - static std::string escape(std::string const& source) { - static const std::unordered_map<char, std::string> escapes { - { '\'', "'" }, - { '"', """ }, - { '<', "<" }, - { '>', ">" }, - { '&', "&" }, - }; - return detail::escape(source, escapes); - } - - int n_samples; - double confidence_interval; - int resamples; - bool verbose; - std::string title; - - std::string current; - std::unordered_map<std::string, result> data; - }; - - NONIUS_REPORTER("junit", junit_reporter); -} // namespace nonius - -#endif // NONIUS_DISABLE_JUNIT_REPORTER -#ifndef NONIUS_DISABLE_HTML_REPORTER -// #included from: reporters/html_reporter.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// HTML single-chart reporter - -#define NONIUS_REPORTERS_HTML_ALL_REPORTER_HPP - -// #included from: detail/cpptempl.h -// cpptempl -// ================= -// This is a template engine for C++. -// -// Syntax -// ================= -// Variables: {$variable_name} -// Loops: {% for person in people %}Name: {$person.name}{% endfor %} -// If: {% for person.name == "Bob" %}Full name: Robert{% endif %} -// -// Copyright -// ================== -// Copyright (c) Ryan Ginstrom -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -// -// Modified by: Martinho Fernandes -// -// Usage -// ======================= -// std::string text = "{% if item %}{$item}{% endif %}\n" -// "{% if thing %}{$thing}{% endif %}" ; -// cpptempl::data_map data ; -// data["item"] = cpptempl::make_data("aaa") ; -// data["thing"] = cpptempl::make_data("bbb") ; -// -// std::string result = cpptempl::parse(text, data) ; -// -// Handy Functions -// ======================== -// make_data() : Feed it a string, data_map, or data_list to create a data entry. -// Example: -// data_map person ; -// person["name"] = make_data("Bob") ; -// person["occupation"] = make_data("Plumber") ; -// data_map data ; -// data["person"] = make_data(person) ; -// std::string result = parse(templ_text, data) ; - -#ifndef CPPTEMPL_H -#define CPPTEMPL_H - -#ifdef _MSC_VER -#pragma warning( disable : 4996 ) // 'std::copy': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' -#pragma warning( disable : 4512 ) // 'std::copy': Function call with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators' -#endif - -#include <string> -#include <vector> -#include <map> -#include <memory> -#include <unordered_map> -#include <boost/lexical_cast.hpp> - -#include <ostream> - -#include <sstream> -#include <boost/algorithm/string.hpp> - -namespace cpptempl -{ - // various typedefs - - // data classes - class Data ; - class DataValue ; - class DataList ; - class DataMap ; - - class data_ptr { - public: - data_ptr() {} - template<typename T> data_ptr(const T& data) { - this->operator =(data); - } - data_ptr(DataValue* data); - data_ptr(DataList* data); - data_ptr(DataMap* data); - data_ptr(const data_ptr& data) { - ptr = data.ptr; - } - template<typename T> void operator = (const T& data); - void push_back(const data_ptr& data); - virtual ~data_ptr() {} - Data* operator ->() { - return ptr.get(); - } - private: - std::shared_ptr<Data> ptr; - }; - typedef std::vector<data_ptr> data_list ; - - class data_map { - public: - data_ptr& operator [](const std::string& key); - bool empty(); - bool has(const std::string& key); - private: - std::unordered_map<std::string, data_ptr> data; - }; - - template<> inline void data_ptr::operator = (const data_ptr& data); - template<> void data_ptr::operator = (const std::string& data); - template<> void data_ptr::operator = (const std::string& data); - template<> void data_ptr::operator = (const data_map& data); - template<typename T> - void data_ptr::operator = (const T& data) { - std::string data_str = boost::lexical_cast<std::string>(data); - this->operator =(data_str); - } - - // token classes - class Token ; - typedef std::shared_ptr<Token> token_ptr ; - typedef std::vector<token_ptr> token_vector ; - - // Custom exception class for library errors - class TemplateException : public std::exception - { - public: - TemplateException(std::string reason) : m_reason(std::move(reason)){} - char const* what() const NONIUS_NOEXCEPT override { - return m_reason.c_str(); - } - private: - std::string m_reason; - }; - - // Data types used in templates - class Data - { - public: - virtual bool empty() = 0 ; - virtual std::string getvalue(); - virtual data_list& getlist(); - virtual data_map& getmap() ; - }; - - class DataValue : public Data - { - std::string m_value ; - public: - DataValue(std::string value) : m_value(value){} - std::string getvalue(); - bool empty(); - }; - - class DataList : public Data - { - data_list m_items ; - public: - DataList(const data_list &items) : m_items(items){} - data_list& getlist() ; - bool empty(); - }; - - class DataMap : public Data - { - data_map m_items ; - public: - DataMap(const data_map &items) : m_items(items){} - data_map& getmap(); - bool empty(); - }; - - inline data_ptr::data_ptr(DataValue* data) : ptr(data) {} - inline data_ptr::data_ptr(DataList* data) : ptr(data) {} - inline data_ptr::data_ptr(DataMap* data) : ptr(data) {} - - // convenience functions for making data objects - inline data_ptr make_data(std::string val) - { - return data_ptr(new DataValue(val)) ; - } - inline data_ptr make_data(data_list &val) - { - return data_ptr(new DataList(val)) ; - } - inline data_ptr make_data(data_map &val) - { - return data_ptr(new DataMap(val)) ; - } - // get a data value from a data map - // e.g. foo.bar => data["foo"]["bar"] - data_ptr parse_val(std::string key, data_map &data) ; - - typedef enum - { - TOKEN_TYPE_NONE, - TOKEN_TYPE_TEXT, - TOKEN_TYPE_VAR, - TOKEN_TYPE_IF, - TOKEN_TYPE_FOR, - TOKEN_TYPE_ENDIF, - TOKEN_TYPE_ENDFOR, - } TokenType; - - // Template tokens - // base class for all token types - class Token - { - public: - virtual TokenType gettype() = 0 ; - virtual void gettext(std::ostream &stream, data_map &data) = 0 ; - virtual void set_children(token_vector &children); - virtual token_vector & get_children(); - }; - - // normal text - class TokenText : public Token - { - std::string m_text ; - public: - TokenText(std::string text) : m_text(text){} - TokenType gettype(); - void gettext(std::ostream &stream, data_map &data); - }; - - // variable - class TokenVar : public Token - { - std::string m_key ; - public: - TokenVar(std::string key) : m_key(key){} - TokenType gettype(); - void gettext(std::ostream &stream, data_map &data); - }; - - // for block - class TokenFor : public Token - { - public: - std::string m_key ; - std::string m_val ; - token_vector m_children ; - TokenFor(std::string expr); - TokenType gettype(); - void gettext(std::ostream &stream, data_map &data); - void set_children(token_vector &children); - token_vector &get_children(); - }; - - // if block - class TokenIf : public Token - { - public: - std::string m_expr ; - token_vector m_children ; - TokenIf(std::string expr) : m_expr(expr){} - TokenType gettype(); - void gettext(std::ostream &stream, data_map &data); - bool is_true(std::string expr, data_map &data); - void set_children(token_vector &children); - token_vector &get_children(); - }; - - // end of block - class TokenEnd : public Token // end of control block - { - std::string m_type ; - public: - TokenEnd(std::string text) : m_type(text){} - TokenType gettype(); - void gettext(std::ostream &stream, data_map &data); - }; - - std::string gettext(token_ptr token, data_map &data) ; - - void parse_tree(token_vector &tokens, token_vector &tree, TokenType until=TOKEN_TYPE_NONE) ; - token_vector & tokenize(std::string text, token_vector &tokens) ; - - // The big daddy. Pass in the template and data, - // and get out a completed doc. - void parse(std::ostream &stream, std::string templ_text, data_map &data) ; - std::string parse(std::string templ_text, data_map &data); - std::string parse(std::string templ_text, data_map &data); - -// *********** Implementation ************ - - ////////////////////////////////////////////////////////////////////////// - // Data classes - ////////////////////////////////////////////////////////////////////////// - - // data_map - inline data_ptr& data_map::operator [](const std::string& key) { - return data[key]; - } - inline bool data_map::empty() { - return data.empty(); - } - inline bool data_map::has(const std::string& key) { - return data.find(key) != data.end(); - } - - // data_ptr - template<> - inline void data_ptr::operator = (const data_ptr& data) { - ptr = data.ptr; - } - - template<> - inline void data_ptr::operator = (const std::string& data) { - ptr.reset(new DataValue(data)); - } - - template<> - inline void data_ptr::operator = (const data_map& data) { - ptr.reset(new DataMap(data)); - } - - inline void data_ptr::push_back(const data_ptr& data) { - if (!ptr) { - ptr.reset(new DataList(data_list())); - } - data_list& list = ptr->getlist(); - list.push_back(data); - } - - // base data - inline std::string Data::getvalue() - { - throw TemplateException("Data item is not a value") ; - } - - inline data_list& Data::getlist() - { - throw TemplateException("Data item is not a list") ; - } - inline data_map& Data::getmap() - { - throw TemplateException("Data item is not a dictionary") ; - } - // data value - inline std::string DataValue::getvalue() - { - return m_value ; - } - inline bool DataValue::empty() - { - return m_value.empty(); - } - // data list - inline data_list& DataList::getlist() - { - return m_items ; - } - - inline bool DataList::empty() - { - return m_items.empty(); - } - // data map - inline data_map& DataMap:: getmap() - { - return m_items ; - } - inline bool DataMap::empty() - { - return m_items.empty(); - } - ////////////////////////////////////////////////////////////////////////// - // parse_val - ////////////////////////////////////////////////////////////////////////// - inline data_ptr parse_val(std::string key, data_map &data) - { - // quoted string - if (key[0] == '\"') - { - return make_data(boost::trim_copy_if(key, [](char c){ return c == '"'; })); - } - // check for dotted notation, i.e [foo.bar] - size_t index = key.find(".") ; - if (index == std::string::npos) - { - if (!data.has(key)) - { - return make_data("{$" + key + "}") ; - } - return data[key] ; - } - - std::string sub_key = key.substr(0, index) ; - if (!data.has(sub_key)) - { - return make_data("{$" + key + "}") ; - } - data_ptr item = data[sub_key] ; - return parse_val(key.substr(index+1), item->getmap()) ; - } - - ////////////////////////////////////////////////////////////////////////// - // Token classes - ////////////////////////////////////////////////////////////////////////// - - // defaults, overridden by subclasses with children - inline void Token::set_children( token_vector & ) - { - throw TemplateException("This token type cannot have children") ; - } - - inline token_vector & Token::get_children() - { - throw TemplateException("This token type cannot have children") ; - } - - // TokenText - inline TokenType TokenText::gettype() - { - return TOKEN_TYPE_TEXT ; - } - - inline void TokenText::gettext( std::ostream &stream, data_map & ) - { - stream << m_text ; - } - - // TokenVar - inline TokenType TokenVar::gettype() - { - return TOKEN_TYPE_VAR ; - } - - inline void TokenVar::gettext( std::ostream &stream, data_map &data ) - { - stream << parse_val(m_key, data)->getvalue() ; - } - - // TokenFor - inline TokenFor::TokenFor(std::string expr) - { - std::vector<std::string> elements ; - boost::split(elements, expr, boost::is_space()) ; - if (elements.size() != 4u) - { - throw TemplateException("Invalid syntax in for statement") ; - } - m_val = elements[1] ; - m_key = elements[3] ; - } - - inline TokenType TokenFor::gettype() - { - return TOKEN_TYPE_FOR ; - } - - inline void TokenFor::gettext( std::ostream &stream, data_map &data ) - { - data_ptr value = parse_val(m_key, data) ; - data_list &items = value->getlist() ; - for (size_t i = 0 ; i < items.size() ; ++i) - { - data_map loop ; - loop["index"] = make_data(boost::lexical_cast<std::string>(i+1)) ; - loop["index0"] = make_data(boost::lexical_cast<std::string>(i)) ; - data["loop"] = make_data(loop); - data[m_val] = items[i] ; - for(size_t j = 0 ; j < m_children.size() ; ++j) - { - m_children[j]->gettext(stream, data) ; - } - } - } - - inline void TokenFor::set_children( token_vector &children ) - { - m_children.assign(children.begin(), children.end()) ; - } - - inline token_vector & TokenFor::get_children() - { - return m_children; - } - - // TokenIf - inline TokenType TokenIf::gettype() - { - return TOKEN_TYPE_IF ; - } - - inline void TokenIf::gettext( std::ostream &stream, data_map &data ) - { - if (is_true(m_expr, data)) - { - for(size_t j = 0 ; j < m_children.size() ; ++j) - { - m_children[j]->gettext(stream, data) ; - } - } - } - - inline bool TokenIf::is_true( std::string expr, data_map &data ) - { - std::vector<std::string> elements ; - boost::split(elements, expr, boost::is_space()) ; - - if (elements[1] == "not") - { - return parse_val(elements[2], data)->empty() ; - } - if (elements.size() == 2) - { - return ! parse_val(elements[1], data)->empty() ; - } - data_ptr lhs = parse_val(elements[1], data) ; - data_ptr rhs = parse_val(elements[3], data) ; - if (elements[2] == "==") - { - return lhs->getvalue() == rhs->getvalue() ; - } - return lhs->getvalue() != rhs->getvalue() ; - } - - inline void TokenIf::set_children( token_vector &children ) - { - m_children.assign(children.begin(), children.end()) ; - } - - inline token_vector & TokenIf::get_children() - { - return m_children; - } - - // TokenEnd - inline TokenType TokenEnd::gettype() - { - return m_type == "endfor" ? TOKEN_TYPE_ENDFOR : TOKEN_TYPE_ENDIF ; - } - - inline void TokenEnd::gettext( std::ostream &, data_map &) - { - throw TemplateException("End-of-control statements have no associated text") ; - } - - // gettext - // generic helper for getting text from tokens. - - inline std::string gettext(token_ptr token, data_map &data) - { - std::ostringstream stream ; - token->gettext(stream, data) ; - return stream.str() ; - } - ////////////////////////////////////////////////////////////////////////// - // parse_tree - // recursively parses list of tokens into a tree - ////////////////////////////////////////////////////////////////////////// - inline void parse_tree(token_vector &tokens, token_vector &tree, TokenType until) - { - while(! tokens.empty()) - { - // 'pops' first item off list - token_ptr token = tokens[0] ; - tokens.erase(tokens.begin()) ; - - if (token->gettype() == TOKEN_TYPE_FOR) - { - token_vector children ; - parse_tree(tokens, children, TOKEN_TYPE_ENDFOR) ; - token->set_children(children) ; - } - else if (token->gettype() == TOKEN_TYPE_IF) - { - token_vector children ; - parse_tree(tokens, children, TOKEN_TYPE_ENDIF) ; - token->set_children(children) ; - } - else if (token->gettype() == until) - { - return ; - } - tree.push_back(token) ; - } - } - ////////////////////////////////////////////////////////////////////////// - // tokenize - // parses a template into tokens (text, for, if, variable) - ////////////////////////////////////////////////////////////////////////// - inline token_vector & tokenize(std::string text, token_vector &tokens) - { - while(! text.empty()) - { - size_t pos = text.find("{") ; - if (pos == std::string::npos) - { - if (! text.empty()) - { - tokens.push_back(token_ptr(new TokenText(text))) ; - } - return tokens ; - } - std::string pre_text = text.substr(0, pos) ; - if (! pre_text.empty()) - { - tokens.push_back(token_ptr(new TokenText(pre_text))) ; - } - text = text.substr(pos+1) ; - if (text.empty()) - { - tokens.push_back(token_ptr(new TokenText("{"))) ; - return tokens ; - } - - // variable - if (text[0] == '$') - { - pos = text.find("}") ; - if (pos != std::string::npos) - { - tokens.push_back(token_ptr (new TokenVar(text.substr(1, pos-1)))) ; - text = text.substr(pos+1) ; - } - } - // control statement - else if (text[0] == '%') - { - pos = text.find("}") ; - if (pos != std::string::npos) - { - std::string expression = boost::trim_copy(text.substr(1, pos-2)) ; - text = text.substr(pos+1) ; - if (boost::starts_with(expression, "for")) - { - tokens.push_back(token_ptr (new TokenFor(expression))) ; - } - else if (boost::starts_with(expression, "if")) - { - tokens.push_back(token_ptr (new TokenIf(expression))) ; - } - else - { - tokens.push_back(token_ptr (new TokenEnd(boost::trim_copy(expression)))) ; - } - } - } - else - { - tokens.push_back(token_ptr(new TokenText("{"))) ; - } - } - return tokens ; - } - - inline std::string parse(std::string templ_text, data_map &data) - { - std::ostringstream stream ; - parse(stream, templ_text, data) ; - return stream.str() ; - } - inline void parse(std::ostream &stream, std::string templ_text, data_map &data) - { - token_vector tokens ; - tokenize(templ_text, tokens) ; - token_vector tree ; - parse_tree(tokens, tree) ; - - for (size_t i = 0 ; i < tree.size() ; ++i) - { - // Recursively calls gettext on each node in the tree. - // gettext returns the appropriate text for that node. - // for text, itself; - // for variable, substitution; - // for control statement, recursively gets kids - tree[i]->gettext(stream, data) ; - } - } -} - -#endif // CPPTEMPL_H -#include <ios> -#include <iomanip> -#include <algorithm> -#include <string> -#include <iterator> -#include <limits> -#include <unordered_map> -#include <vector> - -#include <fstream> - -namespace nonius { - struct html_reporter : reporter { - private: - static std::string const& template_string() { - static char const* template_parts[] = { -// generated content broken into pieces because MSVC is in the 1990s. -// #included from: detail/html_report_template.g.h++ -"<!DOCTYPE html>\n" -"<html>\n" -" <head>\n" -" <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n" -" <title>{$title} - nonius report</title>\n" -" <style type=\"text/css\"> body {\n" -" left: 0;\n" -" right: 0;\n" -" top: 0;\n" -" bottom: 0;\n" -" margin: 0;\n" -"}\n" -"\n" -".plotly .modebar {\n" -" margin-top: 2em !important;\n" -"}\n" -"\n" -"#header {\n" -" background-color: black;\n" -" z-index: 2;\n" -" position: absolute;\n" -" left: 0;\n" -" right: 0;\n" -" color: white;\n" -" font-family: monospace;\n" -" padding-left: 0;\n" -" text-align: center;\n" -" font-size: 1.2em;\n" -" font-weight: bold;\n" -" line-height: 2em;\n" -"}\n" -"\n" -".select {\n" -" position: relative;\n" -" display: inline-block;\n" -" font-size: 1em;\n" -" font-weight: bold;\n" -" font-size: 1em;\n" -"}\n" -"\n" -".select .arr {\n" -" background: #000;\n" -" bottom: 5px;\n" -" position: absolute;\n" -" right: 5px;\n" -" top: 5px;\n" -" width: 0px;\n" -" pointer-events: none;\n" -"}\n" -"\n" -".select .arr:before {\n" -" content: '';\n" -" position: absolute;\n" -" top: 50%;\n" -" right: 14px;\n" -" margin-top: -5px;\n" -" pointer-events: none;\n" -" border-top: 10px solid white;\n" -" border-left: 10px solid transparent;\n" -" border-right: 10px solid transparent;\n" -"}\n" -"\n" -".select .arr:after {\n" -" content: '';\n" -" position: absolute;\n" -" top: 50%;\n" -" right: 18px;\n" -" margin-top: -5px;\n" -" pointer-events: none;\n" -" border-top: 6px solid black;\n" -" border-left: 6px solid transparent;\n" -" border-right: 6px solid transparent;\n" -"}\n" -"\n" -".select select {\n" -" outline: none;\n" -" -webkit-appearance: none;\n" -" -moz-appearance: none;\n" -" display: block;\n" -" padding: 0 3em 0 1.5em;\n" -" margin: 0.3em;\n" -" height: 2em;\n" -"\n" -" transition: border-color 0.2s;\n" -" border: 2px solid #aaa;\n" -" border-radius: 0px;\n" -"\n" -" background: black;\n" -" color: white;\n" -" font-family: inherit;\n" -" font-size: inherit;\n" -" line-height: inherit;\n" -" font-weight: inherit;\n" -"}\n" -"\n" -".select select:focus {\n" -" border: 2px solid white;\n" -" color: white;\n" -"}\n" -"\n" -"div.is-sorted {\n" -" position: absolute;\n" -" top: 0em;\n" -" right: 1em;\n" -" line-height: 2.8em;\n" -"}\n" -"\n" -"div.is-sorted input {\n" -" position: relative;\n" -" top: 2px;\n" -"}\n" -"\n" -"#plot {\n" -" position: absolute;\n" -" min-width: 300px;\n" -" min-height: 200px;\n" -" left: 0;\n" -" right: 0;\n" -" top: 2em;\n" -" bottom: 1em;\n" -"}\n" -"\n" -"#footer {\n" -" position: absolute;\n" -" bottom: 0;\n" -" left: 0;\n" -" right: 0;\n" -" font-family: monospace;\n" -" font-size: 0.9em;\n" -" text-align: center;\n" -" text-transform: lowercase;\n" -" background-color: #bbb;\n" -" line-height: 2em;\n" -"}\n" -" </style>\n" -" <script type=\"text/javascript\"> /**\n" -"* plotly.js (basic - minified) v1.15.0\n" -"* Copyright 2012-2016, Plotly, Inc.\n" -"* All rights reserved.\n" -"* Licensed under the MIT license\n" -"*/\n" -, -"!function(t){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=t();else if(\"function\"==typeof define&&define.amd)define([],t);else{var e;e=\"undefined\"!=typeof window?window:\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:this,e.Plotly=t()}}(function(){var t;return function e(t,n,r){function a(i,l){if(!n[i]){if(!t[i]){var s=\"function\"==typeof require&&require;if(!l&&s)return s(i,!0);if(o)return o(i,!0);var c=new Error(\"Cannot find module '\"+i+\"'\");throw c.code=\"MODULE_NOT_FOUND\",c}var u=n[i]={exports:{}};t[i][0].call(u.exports,function(e){var n=t[i][1][e];return a(n?n:e)},u,u.exports,e,t,n,r)}return n[i].exports}for(var o=\"function\"==typeof require&&require,i=0;i<r.length;i++)a(r[i]);return a}({1:[function(t,e,n){\"use strict\";var r=t(\"../src/plotly\"),a={\"X,X div\":\"font-family:'Open Sans', verdana, arial, sans-serif;margin:0;padding:0;\",\"X input,X button\":\"font-family:'Open Sans', verdana, arial, sans-serif;\",\"X input:focus,X button:focus\":\"outline:none;\",\"X a\":\"text-decoration:none;\",\"X a:hover\":\"text-decoration:none;\",\"X .crisp\":\"shape-rendering:crispEdges;\",\"X .user-select-none\":\"-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;\",\"X svg\":\"overflow:hidden;\",\"X svg a\":\"fill:#447adb;\",\"X svg a:hover\":\"fill:#3c6dc5;\",\"X .main-svg\":\"position:absolute;top:0;left:0;pointer-events:none;\",\"X .main-svg .draglayer\":\"pointer-events:all;\",\"X .cursor-pointer\":\"cursor:pointer;\",\"X .cursor-crosshair\":\"cursor:crosshair;\",\"X .cursor-move\":\"cursor:move;\",\"X .cursor-col-resize\":\"cursor:col-resize;\",\"X .cursor-row-resize\":\"cursor:row-resize;\",\"X .cursor-ns-resize\":\"cursor:ns-resize;\",\"X .cursor-ew-resize\":\"cursor:ew-resize;\",\"X .cursor-sw-resize\":\"cursor:sw-resize;\",\"X .cursor-s-resize\":\"cursor:s-resize;\",\"X .cursor-se-resize\":\"cursor:se-resize;\",\"X .cursor-w-resize\":\"cursor:w-resize;\",\"X .cursor-e-resize\":\"cursor:e-resize;\",\"X .cursor-nw-resize\":\"cursor:nw-resize;\",\"X .cursor-n-resize\":\"cursor:n-resize;\",\"X .cursor-ne-resize\":\"cursor:ne-resize;\",\"X .modebar\":\"position:absolute;top:2px;right:2px;z-index:1001;background:rgba(255,255,255,0.7);\",\"X .modebar--hover\":\"opacity:0;-webkit-transition:opacity 0.3s ease 0s;-moz-transition:opacity 0.3s ease 0s;-ms-transition:opacity 0.3s ease 0s;-o-transition:opacity 0.3s ease 0s;transition:opacity 0.3s ease 0s;\",\"X:hover .modebar--hover\":\"opacity:1;\",\"X .modebar-group\":\"float:left;display:inline-block;box-sizing:border-box;margin-left:8px;position:relative;vertical-align:middle;white-space:nowrap;\",\"X .modebar-group:first-child\":\"margin-left:0px;\",\"X .modebar-btn\":\"position:relative;font-size:16px;padding:3px 4px;cursor:pointer;line-height:normal;box-sizing:border-box;\",\"X .modebar-btn svg\":\"position:relative;top:2px;\",\"X .modebar-btn path\":\"fill:rgba(0,31,95,0.3);\",\"X .modebar-btn.active path,X .modebar-btn:hover path\":\"fill:rgba(0,22,72,0.5);\",\"X .modebar-btn.modebar-btn--logo\":\"padding:3px 1px;\",\"X .modebar-btn.modebar-btn--logo path\":\"fill:#447adb !important;\",\"X [data-title]:before,X [data-title]:after\":\"position:absolute;-webkit-transform:translate3d(0, 0, 0);-moz-transform:translate3d(0, 0, 0);-ms-transform:translate3d(0, 0, 0);-o-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);display:none;opacity:0;z-index:1001;pointer-events:none;top:110%;right:50%;\",\"X [data-title]:hover:before,X [data-title]:hover:after\":\"display:block;opacity:1;\",\"X [data-title]:before\":\"content:'';position:absolute;background:transparent;border:6px solid transparent;z-index:1002;margin-top:-12px;border-bottom-color:#69738a;margin-right:-6px;\",\"X [data-title]:after\":\"content:attr(data-title);background:#69738a;color:white;padding:8px 10px;font-size:12px;line-height:12px;white-space:nowrap;margin-right:-18px;border-radius:2px;\",\"X .select-outline\":\"fill:none;stroke-width:1;shape-rendering:crispEdges;\",\"X .select-outline-1\":\"stroke:white;\",\"X .select-outline-2\":\"stroke:black;stroke-dasharray:2px 2px;\",Y:\"font-family:'Open Sans';position:fixed;top:50px;right:20px;z-index:10000;font-size:10pt;max-width:180px;\",\"Y p\":\"margin:0;\",\"Y .notifier-note\":\"min-width:180px;max-width:250px;border:1px solid #fff;z-index:3000;margin:0;background-color:#8c97af;background-color:rgba(140,151,175,0.9);color:#fff;padding:10px;\",\"Y .notifier-close\":\"color:#fff;opacity:0.8;float:right;padding:0 5px;background:none;border:none;font-size:20px;font-weight:bold;line-height:20px;\",\"Y .notifier-close:hover\":\"color:#444;text-decoration:none;cursor:pointer;\"};for(var o in a){var i=o.replace(/^,/,\" ,\").replace(/X/g,\".js-plotly-plot .plotly\").replace(/Y/g,\".plotly-notifier\");r.Lib.addStyleRule(i,a[o])}},{\"../src/plotly\":107}],2:[function(t,e,n){\"use strict\";e.exports={undo:{width:857.1,path:\"m857 350q0-87-34-166t-91-137-137-92-166-34q-96 0-183 41t-147 114q-4 6-4 13t5 11l76 77q6 5 14 5 9-1 13-7 41-53 100-82t126-29q58 0 110 23t92 61 61 91 22 111-22 111-61 91-92 61-110 23q-55 0-105-20t-90-57l77-77q17-16 8-38-10-23-33-23h-250q-15 0-25 11t-11 25v250q0 24 22 33 22 10 39-8l72-72q60 57 137 88t159 31q87 0 166-34t137-92 91-137 34-166z\",ascent:850,descent:-150},home:{width:928.6,path:\"m786 296v-267q0-15-11-26t-25-10h-214v214h-143v-214h-214q-15 0-25 10t-11 26v267q0 1 0 2t0 2l321 264 321-264q1-1 1-4z m124 39l-34-41q-5-5-12-6h-2q-7 0-12 3l-386 322-386-322q-7-4-13-4-7 2-12 7l-35 41q-4 5-3 13t6 12l401 334q18 15 42 15t43-15l136-114v109q0 8 5 13t13 5h107q8 0 13-5t5-13v-227l122-102q5-5 6-12t-4-13z\",ascent:850,descent:-150},\"camera-retro\":{width:1e3,path:\"m518 386q0 8-5 13t-13 5q-37 0-63-27t-26-63q0-8 5-13t13-5 12 5 5 13q0 23 16 38t38 16q8 0 13 5t5 13z m125-73q0-59-42-101t-101-42-101 42-42 101 42 101 101 42 101-42 42-101z m-572-320h858v71h-858v-71z m643 320q0 89-62 152t-152 62-151-62-63-152 63-151 151-63 152 63 62 151z m-571 358h214v72h-214v-72z m-72-107h858v143h-462l-36-71h-360v-72z m929 143v-714q0-30-21-51t-50-21h-858q-29 0-50 21t-21 51v714q0 30 21 51t50 21h858q29 0 50-21t21-51z\",ascent:850,descent:-150},zoombox:{width:1e3,path:\"m1000-25l-250 251c40 63 63 138 63 218 0 224-182 406-407 406-224 0-406-182-406-406s183-406 407-406c80 0 155 22 218 62l250-250 125 125z m-812 250l0 438 437 0 0-438-437 0z m62 375l313 0 0-312-313 0 0 312z\",ascent:850,descent:-150},pan:{width:1e3,path:\"m1000 350l-187 188 0-125-250 0 0 250 125 0-188 187-187-187 125 0 0-250-250 0 0 125-188-188 186-187 0 125 252 0 0-250-125 0 187-188 188 188-125 0 0 250 250 0 0-126 187 188z\",ascent:850,descent:-150},zoom_plus:{width:1e3,path:\"m1 787l0-875 875 0 0 875-875 0z m687-500l-187 0 0-187-125 0 0 187-188 0 0 125 188 0 0 187 125 0 0-187 187 0 0-125z\",ascent:850,descent:-150},zoom_minus:{width:1e3,path:\"m0 788l0-876 875 0 0 876-875 0z m688-500l-500 0 0 125 500 0 0-125z\",ascent:850,descent:-150},autoscale:{width:1e3,path:\"m250 850l-187 0-63 0 0-62 0-188 63 0 0 188 187 0 0 62z m688 0l-188 0 0-62 188 0 0-188 62 0 0 188 0 62-62 0z m-875-938l0 188-63 0 0-188 0-62 63 0 187 0 0 62-187 0z m875 188l0-188-188 0 0-62 188 0 62 0 0 62 0 188-62 0z m-125 188l-1 0-93-94-156 156 156 156 92-93 2 0 0 250-250 0 0-2 93-92-156-156-156 156 94 92 0 2-250 0 0-250 0 0 93 93 157-156-157-156-93 94 0 0 0-250 250 0 0 0-94 93 156 157 156-157-93-93 0 0 250 0 0 250z\",ascent:850,descent:-150},tooltip_basic:{width:1500,path:\"m375 725l0 0-375-375 375-374 0-1 1125 0 0 750-1125 0z\",ascent:850,descent:-150},tooltip_compare:{width:1125,path:\"m187 786l0 2-187-188 188-187 0 0 937 0 0 373-938 0z m0-499l0 1-187-188 188-188 0 0 937 0 0 376-938-1z\",ascent:850,descent:-150},plotlylogo:{width:1542,path:\"m0-10h182v-140h-182v140z m228 146h183v-286h-183v286z m225 714h182v-1000h-182v1000z m225-285h182v-715h-182v715z m225 142h183v-857h-183v857z m231-428h182v-429h-182v429z m225-291h183v-138h-183v138z\",ascent:850,descent:-150},\"z-axis\":{width:1e3,path:\"m833 5l-17 108v41l-130-65 130-66c0 0 0 38 0 39 0-1 36-14 39-25 4-15-6-22-16-30-15-12-39-16-56-20-90-22-187-23-279-23-261 0-341 34-353 59 3 60 228 110 228 110-140-8-351-35-351-116 0-120 293-142 474-142 155 0 477 22 477 142 0 50-74 79-163 96z m-374 94c-58-5-99-21-99-40 0-24 65-43 144-43 79 0 143 19 143 43 0 19-42 34-98 40v216h87l-132 135-133-135h88v-216z m167 515h-136v1c16 16 31 34 46 52l84 109v54h-230v-71h124v-1c-16-17-28-32-44-51l-89-114v-51h245v72z\",ascent:850,descent:-150},\"3d_rotate\":{width:1e3,path:\"m922 660c-5 4-9 7-14 11-359 263-580-31-580-31l-102 28 58-400c0 1 1 1 2 2 118 108 351 249 351 249s-62 27-100 42c88 83 222 183 347 122 16-8 30-17 44-27-2 1-4 2-6 4z m36-329c0 0 64 229-88 296-62 27-124 14-175-11 157-78 225-208 249-266 8-19 11-31 11-31 2 5 6 15 11 32-5-13-8-20-8-20z m-775-239c70-31 117-50 198-32-121 80-199 346-199 346l-96-15-58-12c0 0 55-226 155-287z m603 133l-317-139c0 0 4-4 19-14 7-5 24-15 24-15s-177-147-389 4c235-287 536-112 536-112l31-22 100 299-4-1z m-298-153c6-4 14-9 24-15 0 0-17 10-24 15z\",ascent:850,descent:-150},camera:{width:1e3,path:\"m500 450c-83 0-150-67-150-150 0-83 67-150 150-150 83 0 150 67 150 150 0 83-67 150-150 150z m400 150h-120c-16 0-34 13-39 29l-31 93c-6 15-23 28-40 28h-340c-16 0-34-13-39-28l-31-94c-6-15-23-28-40-28h-120c-55 0-100-45-100-100v-450c0-55 45-100 100-100h800c55 0 100 45 100 100v450c0 55-45 100-100 100z m-400-550c-138 0-250 112-250 250 0 138 112 250 250 250 138 0 250-112 250-250 0-138-112-250-250-250z m365 380c-19 0-35 16-35 35 0 19 16 35 35 35 19 0 35-16 35-35 0-19-16-35-35-35z\",ascent:850,descent:-150},movie:{width:1e3,path:\"m938 413l-188-125c0 37-17 71-44 94 64 38 107 107 107 187 0 121-98 219-219 219-121 0-219-98-219-219 0-61 25-117 66-156h-115c30 33 49 76 49 125 0 103-84 187-187 187s-188-84-188-187c0-57 26-107 65-141-38-22-65-62-65-109v-250c0-70 56-126 125-126h500c69 0 125 56 125 126l188-126c34 0 62 28 62 63v375c0 35-28 63-62 63z m-750 0c-69 0-125 56-125 125s56 125 125 125 125-56 125-125-56-125-125-125z m406-1c-87 0-157 70-157 157 0 86 70 156 157 156s156-70 156-156-70-157-156-157z\",ascent:850,descent:-150},question:{width:857.1,path:\"m500 82v107q0 8-5 13t-13 5h-107q-8 0-13-5t-5-13v-107q0-8 5-13t13-5h107q8 0 13 5t5 13z m143 375q0 49-31 91t-77 65-95 23q-136 0-2" -, -"07-119-9-14 4-24l74-55q4-4 10-4 9 0 14 7 30 38 48 51 19 14 48 14 27 0 48-15t21-33q0-21-11-34t-38-25q-35-16-65-48t-29-70v-20q0-8 5-13t13-5h107q8 0 13 5t5 13q0 10 12 27t30 28q18 10 28 16t25 19 25 27 16 34 7 45z m214-107q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z\",ascent:850,descent:-150},disk:{width:857.1,path:\"m214-7h429v214h-429v-214z m500 0h72v500q0 8-6 21t-11 20l-157 156q-5 6-19 12t-22 5v-232q0-22-15-38t-38-16h-322q-22 0-37 16t-16 38v232h-72v-714h72v232q0 22 16 38t37 16h465q22 0 38-16t15-38v-232z m-214 518v178q0 8-5 13t-13 5h-107q-7 0-13-5t-5-13v-178q0-8 5-13t13-5h107q7 0 13 5t5 13z m357-18v-518q0-22-15-38t-38-16h-750q-23 0-38 16t-16 38v750q0 22 16 38t38 16h517q23 0 50-12t42-26l156-157q16-15 27-42t11-49z\",ascent:850,descent:-150},lasso:{width:1031,path:\"m1018 538c-36 207-290 336-568 286-277-48-473-256-436-463 10-57 36-108 76-151-13-66 11-137 68-183 34-28 75-41 114-42l-55-70 0 0c-2-1-3-2-4-3-10-14-8-34 5-45 14-11 34-8 45 4 1 1 2 3 2 5l0 0 113 140c16 11 31 24 45 40 4 3 6 7 8 11 48-3 100 0 151 9 278 48 473 255 436 462z m-624-379c-80 14-149 48-197 96 42 42 109 47 156 9 33-26 47-66 41-105z m-187-74c-19 16-33 37-39 60 50-32 109-55 174-68-42-25-95-24-135 8z m360 75c-34-7-69-9-102-8 8 62-16 128-68 170-73 59-175 54-244-5-9 20-16 40-20 61-28 159 121 317 333 354s407-60 434-217c28-159-121-318-333-355z\",ascent:850,descent:-150},selectbox:{width:1e3,path:\"m0 850l0-143 143 0 0 143-143 0z m286 0l0-143 143 0 0 143-143 0z m285 0l0-143 143 0 0 143-143 0z m286 0l0-143 143 0 0 143-143 0z m-857-286l0-143 143 0 0 143-143 0z m857 0l0-143 143 0 0 143-143 0z m-857-285l0-143 143 0 0 143-143 0z m857 0l0-143 143 0 0 143-143 0z m-857-286l0-143 143 0 0 143-143 0z m286 0l0-143 143 0 0 143-143 0z m285 0l0-143 143 0 0 143-143 0z m286 0l0-143 143 0 0 143-143 0z\",ascent:850,descent:-150}}},{}],3:[function(t,e,n){e.exports=t(\"../src/traces/bar\")},{\"../src/traces/bar\":148}],4:[function(t,e,n){e.exports=t(\"../src/core\")},{\"../src/core\":83}],5:[function(t,e,n){\"use strict\";var r=t(\"./core\");r.register([t(\"./bar\"),t(\"./pie\")]),e.exports=r},{\"./bar\":3,\"./core\":4,\"./pie\":6}],6:[function(t,e,n){e.exports=t(\"../src/traces/pie\")},{\"../src/traces/pie\":160}],7:[function(t,e,n){function r(){this._events=this._events||{},this._maxListeners=this._maxListeners||void 0}function a(t){return\"function\"==typeof t}function o(t){return\"number\"==typeof t}function i(t){return\"object\"==typeof t&&null!==t}function l(t){return void 0===t}e.exports=r,r.EventEmitter=r,r.prototype._events=void 0,r.prototype._maxListeners=void 0,r.defaultMaxListeners=10,r.prototype.setMaxListeners=function(t){if(!o(t)||0>t||isNaN(t))throw TypeError(\"n must be a positive number\");return this._maxListeners=t,this},r.prototype.emit=function(t){var e,n,r,o,s,c;if(this._events||(this._events={}),\"error\"===t&&(!this._events.error||i(this._events.error)&&!this._events.error.length)){if(e=arguments[1],e instanceof Error)throw e;throw TypeError('Uncaught, unspecified \"error\" event.')}if(n=this._events[t],l(n))return!1;if(a(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:o=Array.prototype.slice.call(arguments,1),n.apply(this,o)}else if(i(n))for(o=Array.prototype.slice.call(arguments,1),c=n.slice(),r=c.length,s=0;r>s;s++)c[s].apply(this,o);return!0},r.prototype.addListener=function(t,e){var n;if(!a(e))throw TypeError(\"listener must be a function\");return this._events||(this._events={}),this._events.newListener&&this.emit(\"newListener\",t,a(e.listener)?e.listener:e),this._events[t]?i(this._events[t])?this._events[t].push(e):this._events[t]=[this._events[t],e]:this._events[t]=e,i(this._events[t])&&!this._events[t].warned&&(n=l(this._maxListeners)?r.defaultMaxListeners:this._maxListeners,n&&n>0&&this._events[t].length>n&&(this._events[t].warned=!0,console.error(\"(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.\",this._events[t].length),\"function\"==typeof console.trace&&console.trace())),this},r.prototype.on=r.prototype.addListener,r.prototype.once=function(t,e){function n(){this.removeListener(t,n),r||(r=!0,e.apply(this,arguments))}if(!a(e))throw TypeError(\"listener must be a function\");var r=!1;return n.listener=e,this.on(t,n),this},r.prototype.removeListener=function(t,e){var n,r,o,l;if(!a(e))throw TypeError(\"listener must be a function\");if(!this._events||!this._events[t])return this;if(n=this._events[t],o=n.length,r=-1,n===e||a(n.listener)&&n.listener===e)delete this._events[t],this._events.removeListener&&this.emit(\"removeListener\",t,e);else if(i(n)){for(l=o;l-- >0;)if(n[l]===e||n[l].listener&&n[l].listener===e){r=l;break}if(0>r)return this;1===n.length?(n.length=0,delete this._events[t]):n.splice(r,1),this._events.removeListener&&this.emit(\"removeListener\",t,e)}return this},r.prototype.removeAllListeners=function(t){var e,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[t]&&delete this._events[t],this;if(0===arguments.length){for(e in this._events)\"removeListener\"!==e&&this.removeAllListeners(e);return this.removeAllListeners(\"removeListener\"),this._events={},this}if(n=this._events[t],a(n))this.removeListener(t,n);else if(n)for(;n.length;)this.removeListener(t,n[n.length-1]);return delete this._events[t],this},r.prototype.listeners=function(t){var e;return e=this._events&&this._events[t]?a(this._events[t])?[this._events[t]]:this._events[t].slice():[]},r.prototype.listenerCount=function(t){if(this._events){var e=this._events[t];if(a(e))return 1;if(e)return e.length}return 0},r.listenerCount=function(t,e){return t.listenerCount(e)}},{}],8:[function(t,e,n){function r(){u=!1,l.length?c=l.concat(c):f=-1,c.length&&a()}function a(){if(!u){var t=setTimeout(r);u=!0;for(var e=c.length;e;){for(l=c,c=[];++f<e;)l&&l[f].run();f=-1,e=c.length}l=null,u=!1,clearTimeout(t)}}function o(t,e){this.fun=t,this.array=e}function i(){}var l,s=e.exports={},c=[],u=!1,f=-1;s.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];c.push(new o(t,e)),1!==c.length||u||setTimeout(a,0)},o.prototype.run=function(){this.fun.apply(null,this.array)},s.title=\"browser\",s.browser=!0,s.env={},s.argv=[],s.version=\"\",s.versions={},s.on=i,s.addListener=i,s.once=i,s.off=i,s.removeListener=i,s.removeAllListeners=i,s.emit=i,s.binding=function(t){throw new Error(\"process.binding is not supported\")},s.cwd=function(){return\"/\"},s.chdir=function(t){throw new Error(\"process.chdir is not supported\")},s.umask=function(){return 0}},{}],9:[function(e,n,r){!function(){function e(t){return t&&(t.ownerDocument||t.document||t).documentElement}function r(t){return t&&(t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView)}function a(t,e){return e>t?-1:t>e?1:t>=e?0:NaN}function o(t){return null===t?NaN:+t}function i(t){return!isNaN(t)}function l(t){return{left:function(e,n,r,a){for(arguments.length<3&&(r=0),arguments.length<4&&(a=e.length);a>r;){var o=r+a>>>1;t(e[o],n)<0?r=o+1:a=o}return r},right:function(e,n,r,a){for(arguments.length<3&&(r=0),arguments.length<4&&(a=e.length);a>r;){var o=r+a>>>1;t(e[o],n)>0?a=o:r=o+1}return r}}}function s(t){return t.length}function c(t){for(var e=1;t*e%1;)e*=10;return e}function u(t,e){for(var n in e)Object.defineProperty(t.prototype,n,{value:e[n],enumerable:!1})}function f(){this._=Object.create(null)}function d(t){return(t+=\"\")===ki||t[0]===Mi?Mi+t:t}function h(t){return(t+=\"\")[0]===Mi?t.slice(1):t}function p(t){return d(t)in this._}function g(t){return(t=d(t))in this._&&delete this._[t]}function v(){var t=[];for(var e in this._)t.push(h(e));return t}function m(){var t=0;for(var e in this._)++t;return t}function y(){for(var t in this._)return!1;return!0}function x(){this._=Object.create(null)}function b(t){return t}function _(t,e,n){return function(){var r=n.apply(e,arguments);return r===e?t:r}}function w(t,e){if(e in t)return e;e=e.charAt(0).toUpperCase()+e.slice(1);for(var n=0,r=Ai.length;r>n;++n){var a=Ai[n]+e;if(a in t)return a}}function k(){}function M(){}function A(t){function e(){for(var e,r=n,a=-1,o=r.length;++a<o;)(e=r[a].on)&&e.apply(this,arguments);return t}var n=[],r=new f;return e.on=function(e,a){var o,i=r.get(e);return arguments.length<2?i&&i.on:(i&&(i.on=null,n=n.slice(0,o=n.indexOf(i)).concat(n.slice(o+1)),r.remove(e)),a&&n.push(r.set(e,{on:a})),t)},e}function L(){ui.event.preventDefault()}function T(){for(var t,e=ui.event;t=e.sourceEvent;)e=t;return e}function z(t){for(var e=new M,n=0,r=arguments.length;++n<r;)e[arguments[n]]=A(e);return e.of=function(n,r){return function(a){try{var o=a.sourceEvent=ui.event;a.target=t,ui.event=a,e[a.type].apply(n,r)}finally{ui.event=o}}},e}function S(t){return Ti(t,Ci),t}function E(t){return\"function\"==typeof t?t:function(){return zi(t,this)}}function C(t){return\"function\"==typeof t?t:function(){return Si(t,this)}}function O(t,e){function n(){this.removeAttribute(t)}function r(){this.removeAttributeNS(t.space,t.local)}function a(){this.setAttribute(t,e)}function o(){this.setAttributeNS(t.space,t.local,e)}function i(){var n=e.apply(this,arguments);null==n?this.removeAttribute(t):this.setAttribute(t,n)}function l(){var n=e.apply(this,arguments);null==n?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,n)}return t=ui.ns.qualify(t),null==e?t.local?r:n:\"function\"==typeof e?t.local?l:i:t.local?o:a}function P(t){return t.trim().replace(/\\s+/g,\" \")}function N(t){return new RegExp(\"(?:^|\\\\s+)\"+ui.requote(t)+\"(?:\\\\s+|$)\",\"g\")}function D(t){return(t+\"\").trim().split(/^|\\s+/)}function I(t,e){function n(){for(var n=-1;++n<a;)t[n](this,e)}function r(){for(var n=-1,r=e.apply(this,arguments);++n<a;)t[n](this,r)}t=D(t).map(R);var a=t.length;return\"function\"==typeof e?r:n}function R(t){var e=N(t);return function(n,r){if(a=n.classList)return r?a.add(t):a.remove(t);var" -, -" a=n.getAttribute(\"class\")||\"\";r?(e.lastIndex=0,e.test(a)||n.setAttribute(\"class\",P(a+\" \"+t))):n.setAttribute(\"class\",P(a.replace(e,\" \")))}}function j(t,e,n){function r(){this.style.removeProperty(t)}function a(){this.style.setProperty(t,e,n)}function o(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,n)}return null==e?r:\"function\"==typeof e?o:a}function q(t,e){function n(){delete this[t]}function r(){this[t]=e}function a(){var n=e.apply(this,arguments);null==n?delete this[t]:this[t]=n}return null==e?n:\"function\"==typeof e?a:r}function F(t){function e(){var e=this.ownerDocument,n=this.namespaceURI;return n===Oi&&e.documentElement.namespaceURI===Oi?e.createElement(t):e.createElementNS(n,t)}function n(){return this.ownerDocument.createElementNS(t.space,t.local)}return\"function\"==typeof t?t:(t=ui.ns.qualify(t)).local?n:e}function B(){var t=this.parentNode;t&&t.removeChild(this)}function H(t){return{__data__:t}}function V(t){return function(){return Ei(this,t)}}function Z(t){return arguments.length||(t=a),function(e,n){return e&&n?t(e.__data__,n.__data__):!e-!n}}function Y(t,e){for(var n=0,r=t.length;r>n;n++)for(var a,o=t[n],i=0,l=o.length;l>i;i++)(a=o[i])&&e(a,i,n);return t}function U(t){return Ti(t,Ni),t}function X(t){var e,n;return function(r,a,o){var i,l=t[o].update,s=l.length;for(o!=n&&(n=o,e=0),a>=e&&(e=a+1);!(i=l[e])&&++e<s;);return i}}function G(t,e,n){function r(){var e=this[i];e&&(this.removeEventListener(t,e,e.$),delete this[i])}function a(){var a=s(e,di(arguments));r.call(this),this.addEventListener(t,this[i]=a,a.$=n),a._=e}function o(){var e,n=new RegExp(\"^__on([^.]+)\"+ui.requote(t)+\"$\");for(var r in this)if(e=r.match(n)){var a=this[r];this.removeEventListener(e[1],a,a.$),delete this[r]}}var i=\"__on\"+t,l=t.indexOf(\".\"),s=$;l>0&&(t=t.slice(0,l));var c=Di.get(t);return c&&(t=c,s=Q),l?e?a:r:e?k:o}function $(t,e){return function(n){var r=ui.event;ui.event=n,e[0]=this.__data__;try{t.apply(this,e)}finally{ui.event=r}}}function Q(t,e){var n=$(t,e);return function(t){var e=this,r=t.relatedTarget;r&&(r===e||8&r.compareDocumentPosition(e))||n.call(e,t)}}function W(t){var n=\".dragsuppress-\"+ ++Ri,a=\"click\"+n,o=ui.select(r(t)).on(\"touchmove\"+n,L).on(\"dragstart\"+n,L).on(\"selectstart\"+n,L);if(null==Ii&&(Ii=\"onselectstart\"in t?!1:w(t.style,\"userSelect\")),Ii){var i=e(t).style,l=i[Ii];i[Ii]=\"none\"}return function(t){if(o.on(n,null),Ii&&(i[Ii]=l),t){var e=function(){o.on(a,null)};o.on(a,function(){L(),e()},!0),setTimeout(e,0)}}}function J(t,e){e.changedTouches&&(e=e.changedTouches[0]);var n=t.ownerSVGElement||t;if(n.createSVGPoint){var a=n.createSVGPoint();if(0>ji){var o=r(t);if(o.scrollX||o.scrollY){n=ui.select(\"body\").append(\"svg\").style({position:\"absolute\",top:0,left:0,margin:0,padding:0,border:\"none\"},\"important\");var i=n[0][0].getScreenCTM();ji=!(i.f||i.e),n.remove()}}return ji?(a.x=e.pageX,a.y=e.pageY):(a.x=e.clientX,a.y=e.clientY),a=a.matrixTransform(t.getScreenCTM().inverse()),[a.x,a.y]}var l=t.getBoundingClientRect();return[e.clientX-l.left-t.clientLeft,e.clientY-l.top-t.clientTop]}function K(){return ui.event.changedTouches[0].identifier}function tt(t){return t>0?1:0>t?-1:0}function et(t,e,n){return(e[0]-t[0])*(n[1]-t[1])-(e[1]-t[1])*(n[0]-t[0])}function nt(t){return t>1?0:-1>t?Bi:Math.acos(t)}function rt(t){return t>1?Zi:-1>t?-Zi:Math.asin(t)}function at(t){return((t=Math.exp(t))-1/t)/2}function ot(t){return((t=Math.exp(t))+1/t)/2}function it(t){return((t=Math.exp(2*t))-1)/(t+1)}function lt(t){return(t=Math.sin(t/2))*t}function st(){}function ct(t,e,n){return this instanceof ct?(this.h=+t,this.s=+e,void(this.l=+n)):arguments.length<2?t instanceof ct?new ct(t.h,t.s,t.l):kt(\"\"+t,Mt,ct):new ct(t,e,n)}function ut(t,e,n){function r(t){return t>360?t-=360:0>t&&(t+=360),60>t?o+(i-o)*t/60:180>t?i:240>t?o+(i-o)*(240-t)/60:o}function a(t){return Math.round(255*r(t))}var o,i;return t=isNaN(t)?0:(t%=360)<0?t+360:t,e=isNaN(e)?0:0>e?0:e>1?1:e,n=0>n?0:n>1?1:n,i=.5>=n?n*(1+e):n+e-n*e,o=2*n-i,new xt(a(t+120),a(t),a(t-120))}function ft(t,e,n){return this instanceof ft?(this.h=+t,this.c=+e,void(this.l=+n)):arguments.length<2?t instanceof ft?new ft(t.h,t.c,t.l):t instanceof ht?gt(t.l,t.a,t.b):gt((t=At((t=ui.rgb(t)).r,t.g,t.b)).l,t.a,t.b):new ft(t,e,n)}function dt(t,e,n){return isNaN(t)&&(t=0),isNaN(e)&&(e=0),new ht(n,Math.cos(t*=Yi)*e,Math.sin(t)*e)}function ht(t,e,n){return this instanceof ht?(this.l=+t,this.a=+e,void(this.b=+n)):arguments.length<2?t instanceof ht?new ht(t.l,t.a,t.b):t instanceof ft?dt(t.h,t.c,t.l):At((t=xt(t)).r,t.g,t.b):new ht(t,e,n)}function pt(t,e,n){var r=(t+16)/116,a=r+e/500,o=r-n/200;return a=vt(a)*nl,r=vt(r)*rl,o=vt(o)*al,new xt(yt(3.2404542*a-1.5371385*r-.4985314*o),yt(-.969266*a+1.8760108*r+.041556*o),yt(.0556434*a-.2040259*r+1.0572252*o))}function gt(t,e,n){return t>0?new ft(Math.atan2(n,e)*Ui,Math.sqrt(e*e+n*n),t):new ft(NaN,NaN,t)}function vt(t){return t>.206893034?t*t*t:(t-4/29)/7.787037}function mt(t){return t>.008856?Math.pow(t,1/3):7.787037*t+4/29}function yt(t){return Math.round(255*(.00304>=t?12.92*t:1.055*Math.pow(t,1/2.4)-.055))}function xt(t,e,n){return this instanceof xt?(this.r=~~t,this.g=~~e,void(this.b=~~n)):arguments.length<2?t instanceof xt?new xt(t.r,t.g,t.b):kt(\"\"+t,xt,ut):new xt(t,e,n)}function bt(t){return new xt(t>>16,t>>8&255,255&t)}function _t(t){return bt(t)+\"\"}function wt(t){return 16>t?\"0\"+Math.max(0,t).toString(16):Math.min(255,t).toString(16)}function kt(t,e,n){var r,a,o,i=0,l=0,s=0;if(r=/([a-z]+)\\((.*)\\)/.exec(t=t.toLowerCase()))switch(a=r[2].split(\",\"),r[1]){case\"hsl\":return n(parseFloat(a[0]),parseFloat(a[1])/100,parseFloat(a[2])/100);case\"rgb\":return e(Tt(a[0]),Tt(a[1]),Tt(a[2]))}return(o=ll.get(t))?e(o.r,o.g,o.b):(null==t||\"#\"!==t.charAt(0)||isNaN(o=parseInt(t.slice(1),16))||(4===t.length?(i=(3840&o)>>4,i=i>>4|i,l=240&o,l=l>>4|l,s=15&o,s=s<<4|s):7===t.length&&(i=(16711680&o)>>16,l=(65280&o)>>8,s=255&o)),e(i,l,s))}function Mt(t,e,n){var r,a,o=Math.min(t/=255,e/=255,n/=255),i=Math.max(t,e,n),l=i-o,s=(i+o)/2;return l?(a=.5>s?l/(i+o):l/(2-i-o),r=t==i?(e-n)/l+(n>e?6:0):e==i?(n-t)/l+2:(t-e)/l+4,r*=60):(r=NaN,a=s>0&&1>s?0:r),new ct(r,a,s)}function At(t,e,n){t=Lt(t),e=Lt(e),n=Lt(n);var r=mt((.4124564*t+.3575761*e+.1804375*n)/nl),a=mt((.2126729*t+.7151522*e+.072175*n)/rl),o=mt((.0193339*t+.119192*e+.9503041*n)/al);return ht(116*a-16,500*(r-a),200*(a-o))}function Lt(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function Tt(t){var e=parseFloat(t);return\"%\"===t.charAt(t.length-1)?Math.round(2.55*e):e}function zt(t){return\"function\"==typeof t?t:function(){return t}}function St(t){return function(e,n,r){return 2===arguments.length&&\"function\"==typeof n&&(r=n,n=null),Et(e,n,t,r)}}function Et(t,e,n,r){function a(){var t,e=s.status;if(!e&&Ot(s)||e>=200&&300>e||304===e){try{t=n.call(o,s)}catch(r){return void i.error.call(o,r)}i.load.call(o,t)}else i.error.call(o,s)}var o={},i=ui.dispatch(\"beforesend\",\"progress\",\"load\",\"error\"),l={},s=new XMLHttpRequest,c=null;return!this.XDomainRequest||\"withCredentials\"in s||!/^(http(s)?:)?\\/\\//.test(t)||(s=new XDomainRequest),\"onload\"in s?s.onload=s.onerror=a:s.onreadystatechange=function(){s.readyState>3&&a()},s.onprogress=function(t){var e=ui.event;ui.event=t;try{i.progress.call(o,s)}finally{ui.event=e}},o.header=function(t,e){return t=(t+\"\").toLowerCase(),arguments.length<2?l[t]:(null==e?delete l[t]:l[t]=e+\"\",o)},o.mimeType=function(t){return arguments.length?(e=null==t?null:t+\"\",o):e},o.responseType=function(t){return arguments.length?(c=t,o):c},o.response=function(t){return n=t,o},[\"get\",\"post\"].forEach(function(t){o[t]=function(){return o.send.apply(o,[t].concat(di(arguments)))}}),o.send=function(n,r,a){if(2===arguments.length&&\"function\"==typeof r&&(a=r,r=null),s.open(n,t,!0),null==e||\"accept\"in l||(l.accept=e+\",*/*\"),s.setRequestHeader)for(var u in l)s.setRequestHeader(u,l[u]);return null!=e&&s.overrideMimeType&&s.overrideMimeType(e),null!=c&&(s.responseType=c),null!=a&&o.on(\"error\",a).on(\"load\",function(t){a(null,t)}),i.beforesend.call(o,s),s.send(null==r?null:r),o},o.abort=function(){return s.abort(),o},ui.rebind(o,i,\"on\"),null==r?o:o.get(Ct(r))}function Ct(t){return 1===t.length?function(e,n){t(null==e?n:null)}:t}function Ot(t){var e=t.responseType;return e&&\"text\"!==e?t.response:t.responseText}function Pt(t,e,n){var r=arguments.length;2>r&&(e=0),3>r&&(n=Date.now());var a=n+e,o={c:t,t:a,n:null};return cl?cl.n=o:sl=o,cl=o,ul||(fl=clearTimeout(fl),ul=1,dl(Nt)),o}function Nt(){var t=Dt(),e=It()-t;e>24?(isFinite(e)&&(clearTimeout(fl),fl=setTimeout(Nt,e)),ul=0):(ul=1,dl(Nt))}function Dt(){for(var t=Date.now(),e=sl;e;)t>=e.t&&e.c(t-e.t)&&(e.c=null),e=e.n;return t}function It(){for(var t,e=sl,n=1/0;e;)e.c?(e.t<n&&(n=e.t),e=(t=e).n):e=t?t.n=e.n:sl=e.n;return cl=t,n}function Rt(t,e){return e-(t?Math.ceil(Math.log(t)/Math.LN10):1)}function jt(t,e){var n=Math.pow(10,3*wi(8-e));return{scale:e>8?function(t){return t/n}:function(t){return t*n},symbol:t}}function qt(t){var e=t.decimal,n=t.thousands,r=t.grouping,a=t.currency,o=r&&n?function(t,e){for(var a=t.length,o=[],i=0,l=r[0],s=0;a>0&&l>0&&(s+l+1>e&&(l=Math.max(1,e-s)),o.push(t.substring(a-=l,a+l)),!((s+=l+1)>e));)l=r[i=(i+1)%r.length];return o.reverse().join(n)}:b;return function(t){var n=pl.exec(t),r=n[1]||\" \",i=n[2]||\">\",l=n[3]||\"-\",s=n[4]||\"\",c=n[5],u=+n[6],f=n[7],d=n[8],h=n[9],p=1,g=\"\",v=\"\",m=!1,y=!0;switch(d&&(d=+d.substring(1)),(c||\"0\"===r&&\"=\"===i)&&(c=r=\"0\",i=\"=\"),h){case\"n\":f=!0,h=\"g\";break;case\"%\":p=100,v=\"%\",h=\"f\";break;case\"p\":p=100,v=\"%\",h=\"r\";break;case\"b\":case\"o\":case\"x\":case\"X\":\"#\"===s&&(g=\"0\"+h.toLowerCase());case\"c\":y=!1;case\"d\":m=!0,d=0;break;case\"s\":p=-1,h=\"r\"}\"$\"===s&&(g=a[0],v=a[1]),\"r\"!=h||d||(h=\"g\"),null!=d&&(\"g\"==h?d=Math.max(1,Math.min(21,d)):\"e\"!=h&&\"f\"!=h||(d=Math.max(0,Math.min(20,d)))),h=gl.get(h)||Ft;var x=c&&f;return function(t){var n=v;if(m&&t%1)return\"\";var a=0>t||0===t&&0>1/t?(t=-t,\"-\"):\"-\"===l?\"\":l;if(0>p){var s=ui.formatPrefix(t,d);t=s.scale(t),n=s.symbol+v}else t*=p;t=h(t,d);var b,_,w=t.lastIndex" -, -"Of(\".\");if(0>w){var k=y?t.lastIndexOf(\"e\"):-1;0>k?(b=t,_=\"\"):(b=t.substring(0,k),_=t.substring(k))}else b=t.substring(0,w),_=e+t.substring(w+1);!c&&f&&(b=o(b,1/0));var M=g.length+b.length+_.length+(x?0:a.length),A=u>M?new Array(M=u-M+1).join(r):\"\";return x&&(b=o(A+b,A.length?u-_.length:1/0)),a+=g,t=b+_,(\"<\"===i?a+t+A:\">\"===i?A+a+t:\"^\"===i?A.substring(0,M>>=1)+a+t+A.substring(M):a+(x?t:A+t))+n}}}function Ft(t){return t+\"\"}function Bt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ht(t,e,n){function r(e){var n=t(e),r=o(n,1);return r-e>e-n?n:r}function a(n){return e(n=t(new ml(n-1)),1),n}function o(t,n){return e(t=new ml(+t),n),t}function i(t,r,o){var i=a(t),l=[];if(o>1)for(;r>i;)n(i)%o||l.push(new Date(+i)),e(i,1);else for(;r>i;)l.push(new Date(+i)),e(i,1);return l}function l(t,e,n){try{ml=Bt;var r=new Bt;return r._=t,i(r,e,n)}finally{ml=Date}}t.floor=t,t.round=r,t.ceil=a,t.offset=o,t.range=i;var s=t.utc=Vt(t);return s.floor=s,s.round=Vt(r),s.ceil=Vt(a),s.offset=Vt(o),s.range=l,t}function Vt(t){return function(e,n){try{ml=Bt;var r=new Bt;return r._=e,t(r,n)._}finally{ml=Date}}}function Zt(t){function e(t){function e(e){for(var n,a,o,i=[],l=-1,s=0;++l<r;)37===t.charCodeAt(l)&&(i.push(t.slice(s,l)),null!=(a=xl[n=t.charAt(++l)])&&(n=t.charAt(++l)),(o=z[n])&&(n=o(e,null==a?\"e\"===n?\" \":\"0\":a)),i.push(n),s=l+1);return i.push(t.slice(s,l)),i.join(\"\")}var r=t.length;return e.parse=function(e){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},a=n(r,t,e,0);if(a!=e.length)return null;\"p\"in r&&(r.H=r.H%12+12*r.p);var o=null!=r.Z&&ml!==Bt,i=new(o?Bt:ml);return\"j\"in r?i.setFullYear(r.y,0,r.j):\"W\"in r||\"U\"in r?(\"w\"in r||(r.w=\"W\"in r?1:0),i.setFullYear(r.y,0,1),i.setFullYear(r.y,0,\"W\"in r?(r.w+6)%7+7*r.W-(i.getDay()+5)%7:r.w+7*r.U-(i.getDay()+6)%7)):i.setFullYear(r.y,r.m,r.d),i.setHours(r.H+(r.Z/100|0),r.M+r.Z%100,r.S,r.L),o?i._:i},e.toString=function(){return t},e}function n(t,e,n,r){for(var a,o,i,l=0,s=e.length,c=n.length;s>l;){if(r>=c)return-1;\n" -, -"if(a=e.charCodeAt(l++),37===a){if(i=e.charAt(l++),o=S[i in xl?e.charAt(l++):i],!o||(r=o(t,n,r))<0)return-1}else if(a!=n.charCodeAt(r++))return-1}return r}function r(t,e,n){w.lastIndex=0;var r=w.exec(e.slice(n));return r?(t.w=k.get(r[0].toLowerCase()),n+r[0].length):-1}function a(t,e,n){b.lastIndex=0;var r=b.exec(e.slice(n));return r?(t.w=_.get(r[0].toLowerCase()),n+r[0].length):-1}function o(t,e,n){L.lastIndex=0;var r=L.exec(e.slice(n));return r?(t.m=T.get(r[0].toLowerCase()),n+r[0].length):-1}function i(t,e,n){M.lastIndex=0;var r=M.exec(e.slice(n));return r?(t.m=A.get(r[0].toLowerCase()),n+r[0].length):-1}function l(t,e,r){return n(t,z.c.toString(),e,r)}function s(t,e,r){return n(t,z.x.toString(),e,r)}function c(t,e,r){return n(t,z.X.toString(),e,r)}function u(t,e,n){var r=x.get(e.slice(n,n+=2).toLowerCase());return null==r?-1:(t.p=r,n)}var f=t.dateTime,d=t.date,h=t.time,p=t.periods,g=t.days,v=t.shortDays,m=t.months,y=t.shortMonths;e.utc=function(t){function n(t){try{ml=Bt;var e=new ml;return e._=t,r(e)}finally{ml=Date}}var r=e(t);return n.parse=function(t){try{ml=Bt;var e=r.parse(t);return e&&e._}finally{ml=Date}},n.toString=r.toString,n},e.multi=e.utc.multi=ue;var x=ui.map(),b=Ut(g),_=Xt(g),w=Ut(v),k=Xt(v),M=Ut(m),A=Xt(m),L=Ut(y),T=Xt(y);p.forEach(function(t,e){x.set(t.toLowerCase(),e)});var z={a:function(t){return v[t.getDay()]},A:function(t){return g[t.getDay()]},b:function(t){return y[t.getMonth()]},B:function(t){return m[t.getMonth()]},c:e(f),d:function(t,e){return Yt(t.getDate(),e,2)},e:function(t,e){return Yt(t.getDate(),e,2)},H:function(t,e){return Yt(t.getHours(),e,2)},I:function(t,e){return Yt(t.getHours()%12||12,e,2)},j:function(t,e){return Yt(1+vl.dayOfYear(t),e,3)},L:function(t,e){return Yt(t.getMilliseconds(),e,3)},m:function(t,e){return Yt(t.getMonth()+1,e,2)},M:function(t,e){return Yt(t.getMinutes(),e,2)},p:function(t){return p[+(t.getHours()>=12)]},S:function(t,e){return Yt(t.getSeconds(),e,2)},U:function(t,e){return Yt(vl.sundayOfYear(t),e,2)},w:function(t){return t.getDay()},W:function(t,e){return Yt(vl.mondayOfYear(t),e,2)},x:e(d),X:e(h),y:function(t,e){return Yt(t.getFullYear()%100,e,2)},Y:function(t,e){return Yt(t.getFullYear()%1e4,e,4)},Z:se,\"%\":function(){return\"%\"}},S={a:r,A:a,b:o,B:i,c:l,d:ne,e:ne,H:ae,I:ae,j:re,L:le,m:ee,M:oe,p:u,S:ie,U:$t,w:Gt,W:Qt,x:s,X:c,y:Jt,Y:Wt,Z:Kt,\"%\":ce};return e}function Yt(t,e,n){var r=0>t?\"-\":\"\",a=(r?-t:t)+\"\",o=a.length;return r+(n>o?new Array(n-o+1).join(e)+a:a)}function Ut(t){return new RegExp(\"^(?:\"+t.map(ui.requote).join(\"|\")+\")\",\"i\")}function Xt(t){for(var e=new f,n=-1,r=t.length;++n<r;)e.set(t[n].toLowerCase(),n);return e}function Gt(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+1));return r?(t.w=+r[0],n+r[0].length):-1}function $t(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n));return r?(t.U=+r[0],n+r[0].length):-1}function Qt(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n));return r?(t.W=+r[0],n+r[0].length):-1}function Wt(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+4));return r?(t.y=+r[0],n+r[0].length):-1}function Jt(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+2));return r?(t.y=te(+r[0]),n+r[0].length):-1}function Kt(t,e,n){return/^[+-]\\d{4}$/.test(e=e.slice(n,n+5))?(t.Z=-e,n+5):-1}function te(t){return t+(t>68?1900:2e3)}function ee(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function ne(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function re(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+3));return r?(t.j=+r[0],n+r[0].length):-1}function ae(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function oe(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function ie(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function le(t,e,n){bl.lastIndex=0;var r=bl.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function se(t){var e=t.getTimezoneOffset(),n=e>0?\"-\":\"+\",r=wi(e)/60|0,a=wi(e)%60;return n+Yt(r,\"0\",2)+Yt(a,\"0\",2)}function ce(t,e,n){_l.lastIndex=0;var r=_l.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function ue(t){for(var e=t.length,n=-1;++n<e;)t[n][0]=this(t[n][0]);return function(e){for(var n=0,r=t[n];!r[1](e);)r=t[++n];return r[0](e)}}function fe(){}function de(t,e,n){var r=n.s=t+e,a=r-t,o=r-a;n.t=t-o+(e-a)}function he(t,e){t&&Al.hasOwnProperty(t.type)&&Al[t.type](t,e)}function pe(t,e,n){var r,a=-1,o=t.length-n;for(e.lineStart();++a<o;)r=t[a],e.point(r[0],r[1],r[2]);e.lineEnd()}function ge(t,e){var n=-1,r=t.length;for(e.polygonStart();++n<r;)pe(t[n],e,1);e.polygonEnd()}function ve(){function t(t,e){t*=Yi,e=e*Yi/2+Bi/4;var n=t-r,i=n>=0?1:-1,l=i*n,s=Math.cos(e),c=Math.sin(e),u=o*c,f=a*s+u*Math.cos(l),d=u*i*Math.sin(l);Tl.add(Math.atan2(d,f)),r=t,a=s,o=c}var e,n,r,a,o;zl.point=function(i,l){zl.point=t,r=(e=i)*Yi,a=Math.cos(l=(n=l)*Yi/2+Bi/4),o=Math.sin(l)},zl.lineEnd=function(){t(e,n)}}function me(t){var e=t[0],n=t[1],r=Math.cos(n);return[r*Math.cos(e),r*Math.sin(e),Math.sin(n)]}function ye(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function xe(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function be(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function _e(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function we(t){var e=Math.sqrt(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}function ke(t){return[Math.atan2(t[1],t[0]),rt(t[2])]}function Me(t,e){return wi(t[0]-e[0])<qi&&wi(t[1]-e[1])<qi}function Ae(t,e){t*=Yi;var n=Math.cos(e*=Yi);Le(n*Math.cos(t),n*Math.sin(t),Math.sin(e))}function Le(t,e,n){++Sl,Cl+=(t-Cl)/Sl,Ol+=(e-Ol)/Sl,Pl+=(n-Pl)/Sl}function Te(){function t(t,a){t*=Yi;var o=Math.cos(a*=Yi),i=o*Math.cos(t),l=o*Math.sin(t),s=Math.sin(a),c=Math.atan2(Math.sqrt((c=n*s-r*l)*c+(c=r*i-e*s)*c+(c=e*l-n*i)*c),e*i+n*l+r*s);El+=c,Nl+=c*(e+(e=i)),Dl+=c*(n+(n=l)),Il+=c*(r+(r=s)),Le(e,n,r)}var e,n,r;Fl.point=function(a,o){a*=Yi;var i=Math.cos(o*=Yi);e=i*Math.cos(a),n=i*Math.sin(a),r=Math.sin(o),Fl.point=t,Le(e,n,r)}}function ze(){Fl.point=Ae}function Se(){function t(t,e){t*=Yi;var n=Math.cos(e*=Yi),i=n*Math.cos(t),l=n*Math.sin(t),s=Math.sin(e),c=a*s-o*l,u=o*i-r*s,f=r*l-a*i,d=Math.sqrt(c*c+u*u+f*f),h=r*i+a*l+o*s,p=d&&-nt(h)/d,g=Math.atan2(d,h);Rl+=p*c,jl+=p*u,ql+=p*f,El+=g,Nl+=g*(r+(r=i)),Dl+=g*(a+(a=l)),Il+=g*(o+(o=s)),Le(r,a,o)}var e,n,r,a,o;Fl.point=function(i,l){e=i,n=l,Fl.point=t,i*=Yi;var s=Math.cos(l*=Yi);r=s*Math.cos(i),a=s*Math.sin(i),o=Math.sin(l),Le(r,a,o)},Fl.lineEnd=function(){t(e,n),Fl.lineEnd=ze,Fl.point=Ae}}function Ee(t,e){function n(n,r){return n=t(n,r),e(n[0],n[1])}return t.invert&&e.invert&&(n.invert=function(n,r){return n=e.invert(n,r),n&&t.invert(n[0],n[1])}),n}function Ce(){return!0}function Oe(t,e,n,r,a){var o=[],i=[];if(t.forEach(function(t){if(!((e=t.length-1)<=0)){var e,n=t[0],r=t[e];if(Me(n,r)){a.lineStart();for(var l=0;e>l;++l)a.point((n=t[l])[0],n[1]);return void a.lineEnd()}var s=new Ne(n,t,null,!0),c=new Ne(n,null,s,!1);s.o=c,o.push(s),i.push(c),s=new Ne(r,t,null,!1),c=new Ne(r,null,s,!0),s.o=c,o.push(s),i.push(c)}}),i.sort(e),Pe(o),Pe(i),o.length){for(var l=0,s=n,c=i.length;c>l;++l)i[l].e=s=!s;for(var u,f,d=o[0];;){for(var h=d,p=!0;h.v;)if((h=h.n)===d)return;u=h.z,a.lineStart();do{if(h.v=h.o.v=!0,h.e){if(p)for(var l=0,c=u.length;c>l;++l)a.point((f=u[l])[0],f[1]);else r(h.x,h.n.x,1,a);h=h.n}else{if(p){u=h.p.z;for(var l=u.length-1;l>=0;--l)a.point((f=u[l])[0],f[1])}else r(h.x,h.p.x,-1,a);h=h.p}h=h.o,u=h.z,p=!p}while(!h.v);a.lineEnd()}}}function Pe(t){if(e=t.length){for(var e,n,r=0,a=t[0];++r<e;)a.n=n=t[r],n.p=a,a=n;a.n=n=t[0],n.p=a}}function Ne(t,e,n,r){this.x=t,this.z=e,this.o=n,this.e=r,this.v=!1,this.n=this.p=null}function De(t,e,n,r){return function(a,o){function i(e,n){var r=a(e,n);t(e=r[0],n=r[1])&&o.point(e,n)}function l(t,e){var n=a(t,e);v.point(n[0],n[1])}function s(){y.point=l,v.lineStart()}function c(){y.point=i,v.lineEnd()}function u(t,e){g.push([t,e]);var n=a(t,e);b.point(n[0],n[1])}function f(){b.lineStart(),g=[]}function d(){u(g[0][0],g[0][1]),b.lineEnd();var t,e=b.clean(),n=x.buffer(),r=n.length;if(g.pop(),p.push(g),g=null,r)if(1&e){t=n[0];var a,r=t.length-1,i=-1;if(r>0){for(_||(o.polygonStart(),_=!0),o.lineStart();++i<r;)o.point((a=t[i])[0],a[1]);o.lineEnd()}}else r>1&&2&e&&n.push(n.pop().concat(n.shift())),h.push(n.filter(Ie))}var h,p,g,v=e(o),m=a.invert(r[0],r[1]),y={point:i,lineStart:s,lineEnd:c,polygonStart:function(){y.point=u,y.lineStart=f,y.lineEnd=d,h=[],p=[]},polygonEnd:function(){y.point=i,y.lineStart=s,y.lineEnd=c,h=ui.merge(h);var t=He(m,p);h.length?(_||(o.polygonStart(),_=!0),Oe(h,je,t,n,o)):t&&(_||(o.polygonStart(),_=!0),o.lineStart(),n(null,null,1,o),o.lineEnd()),_&&(o.polygonEnd(),_=!1),h=p=null},sphere:function(){o.polygonStart(),o.lineStart(),n(null,null,1,o),o.lineEnd(),o.polygonEnd()}},x=Re(),b=e(x),_=!1;return y}}function Ie(t){return t.length>1}function Re(){var t,e=[];return{lineStart:function(){e.push(t=[])},point:function(e,n){t.push([e,n])},lineEnd:k,buffer:function(){var n=e;return e=[],t=null,n},rejoin:function(){e.length>1&&e.push(e.pop().concat(e.shift()))}}}function je(t,e){return((t=t.x)[0]<0?t[1]-Zi-qi:Zi-t[1])-((e=e.x)[0]<0?e[1]-Zi-qi:Zi-e[1])}function qe(t){var e,n=NaN,r=NaN,a=NaN;return{lineStart:function(){t.lineStart(),e=1},point:function(o,i){var l=o>0?Bi:-Bi,s=wi(o-n);wi(s-Bi)<qi?(t.point(n,r=(r+i)/2>0?Zi:-Zi),t.point(a,r),t.lineEnd(),t.lineStart(),t.point(l,r),t.point(o,r),e=0):a!==l&&s>=Bi&&(wi(n-a)<qi&&(n-=a*qi),wi(o-l)<qi&&(o-=l*qi),r=Fe(n,r,o,i),t.point(a,r),t.lineEnd(),t.lineStart(),t.point(l,r),e=0),t.point(n=o,r=i),a=l},lineEnd:function(){t.lineEnd(),n=r=NaN},clean:function(){return 2-e}}}function Fe(t,e,n,r){var a,o,i=Math.sin(t-n);return wi(i)>qi?Math.atan((Math.sin(e)*(o=Math.cos(r))*Math.sin(n)-Math.sin(r)*(a=Math.cos(e))*Math.sin(t))/(a*o*i)):(e+r)/2}function Be(t,e,n,r){var a;if(null==t)a=n*Zi,r.point(-Bi,a),r.point(0,a),r.point(Bi,a),r.point(Bi,0),r.point(Bi,-a),r.point(0,-a),r.point(-Bi,-a),r.point(-B" -, -"i,0),r.point(-Bi,a);else if(wi(t[0]-e[0])>qi){var o=t[0]<e[0]?Bi:-Bi;a=n*o/2,r.point(-o,a),r.point(0,a),r.point(o,a)}else r.point(e[0],e[1])}function He(t,e){var n=t[0],r=t[1],a=[Math.sin(n),-Math.cos(n),0],o=0,i=0;Tl.reset();for(var l=0,s=e.length;s>l;++l){var c=e[l],u=c.length;if(u)for(var f=c[0],d=f[0],h=f[1]/2+Bi/4,p=Math.sin(h),g=Math.cos(h),v=1;;){v===u&&(v=0),t=c[v];var m=t[0],y=t[1]/2+Bi/4,x=Math.sin(y),b=Math.cos(y),_=m-d,w=_>=0?1:-1,k=w*_,M=k>Bi,A=p*x;if(Tl.add(Math.atan2(A*w*Math.sin(k),g*b+A*Math.cos(k))),o+=M?_+w*Hi:_,M^d>=n^m>=n){var L=xe(me(f),me(t));we(L);var T=xe(a,L);we(T);var z=(M^_>=0?-1:1)*rt(T[2]);(r>z||r===z&&(L[0]||L[1]))&&(i+=M^_>=0?1:-1)}if(!v++)break;d=m,p=x,g=b,f=t}}return(-qi>o||qi>o&&0>Tl)^1&i}function Ve(t){function e(t,e){return Math.cos(t)*Math.cos(e)>o}function n(t){var n,o,s,c,u;return{lineStart:function(){c=s=!1,u=1},point:function(f,d){var h,p=[f,d],g=e(f,d),v=i?g?0:a(f,d):g?a(f+(0>f?Bi:-Bi),d):0;if(!n&&(c=s=g)&&t.lineStart(),g!==s&&(h=r(n,p),(Me(n,h)||Me(p,h))&&(p[0]+=qi,p[1]+=qi,g=e(p[0],p[1]))),g!==s)u=0,g?(t.lineStart(),h=r(p,n),t.point(h[0],h[1])):(h=r(n,p),t.point(h[0],h[1]),t.lineEnd()),n=h;else if(l&&n&&i^g){var m;v&o||!(m=r(p,n,!0))||(u=0,i?(t.lineStart(),t.point(m[0][0],m[0][1]),t.point(m[1][0],m[1][1]),t.lineEnd()):(t.point(m[1][0],m[1][1]),t.lineEnd(),t.lineStart(),t.point(m[0][0],m[0][1])))}!g||n&&Me(n,p)||t.point(p[0],p[1]),n=p,s=g,o=v},lineEnd:function(){s&&t.lineEnd(),n=null},clean:function(){return u|(c&&s)<<1}}}function r(t,e,n){var r=me(t),a=me(e),i=[1,0,0],l=xe(r,a),s=ye(l,l),c=l[0],u=s-c*c;if(!u)return!n&&t;var f=o*s/u,d=-o*c/u,h=xe(i,l),p=_e(i,f),g=_e(l,d);be(p,g);var v=h,m=ye(p,v),y=ye(v,v),x=m*m-y*(ye(p,p)-1);if(!(0>x)){var b=Math.sqrt(x),_=_e(v,(-m-b)/y);if(be(_,p),_=ke(_),!n)return _;var w,k=t[0],M=e[0],A=t[1],L=e[1];k>M&&(w=k,k=M,M=w);var T=M-k,z=wi(T-Bi)<qi,S=z||qi>T;if(!z&&A>L&&(w=A,A=L,L=w),S?z?A+L>0^_[1]<(wi(_[0]-k)<qi?A:L):A<=_[1]&&_[1]<=L:T>Bi^(k<=_[0]&&_[0]<=M)){var E=_e(v,(-m+b)/y);return be(E,p),[_,ke(E)]}}}function a(e,n){var r=i?t:Bi-t,a=0;return-r>e?a|=1:e>r&&(a|=2),-r>n?a|=4:n>r&&(a|=8),a}var o=Math.cos(t),i=o>0,l=wi(o)>qi,s=mn(t,6*Yi);return De(e,n,s,i?[0,-t]:[-Bi,t-Bi])}function Ze(t,e,n,r){return function(a){var o,i=a.a,l=a.b,s=i.x,c=i.y,u=l.x,f=l.y,d=0,h=1,p=u-s,g=f-c;if(o=t-s,p||!(o>0)){if(o/=p,0>p){if(d>o)return;h>o&&(h=o)}else if(p>0){if(o>h)return;o>d&&(d=o)}if(o=n-s,p||!(0>o)){if(o/=p,0>p){if(o>h)return;o>d&&(d=o)}else if(p>0){if(d>o)return;h>o&&(h=o)}if(o=e-c,g||!(o>0)){if(o/=g,0>g){if(d>o)return;h>o&&(h=o)}else if(g>0){if(o>h)return;o>d&&(d=o)}if(o=r-c,g||!(0>o)){if(o/=g,0>g){if(o>h)return;o>d&&(d=o)}else if(g>0){if(d>o)return;h>o&&(h=o)}return d>0&&(a.a={x:s+d*p,y:c+d*g}),1>h&&(a.b={x:s+h*p,y:c+h*g}),a}}}}}}function Ye(t,e,n,r){function a(r,a){return wi(r[0]-t)<qi?a>0?0:3:wi(r[0]-n)<qi?a>0?2:1:wi(r[1]-e)<qi?a>0?1:0:a>0?3:2}function o(t,e){return i(t.x,e.x)}function i(t,e){var n=a(t,1),r=a(e,1);return n!==r?n-r:0===n?e[1]-t[1]:1===n?t[0]-e[0]:2===n?t[1]-e[1]:e[0]-t[0]}return function(l){function s(t){for(var e=0,n=v.length,r=t[1],a=0;n>a;++a)for(var o,i=1,l=v[a],s=l.length,c=l[0];s>i;++i)o=l[i],c[1]<=r?o[1]>r&&et(c,o,t)>0&&++e:o[1]<=r&&et(c,o,t)<0&&--e,c=o;return 0!==e}function c(o,l,s,c){var u=0,f=0;if(null==o||(u=a(o,s))!==(f=a(l,s))||i(o,l)<0^s>0){do c.point(0===u||3===u?t:n,u>1?r:e);while((u=(u+s+4)%4)!==f)}else c.point(l[0],l[1])}function u(a,o){return a>=t&&n>=a&&o>=e&&r>=o}function f(t,e){u(t,e)&&l.point(t,e)}function d(){S.point=p,v&&v.push(m=[]),M=!0,k=!1,_=w=NaN}function h(){g&&(p(y,x),b&&k&&T.rejoin(),g.push(T.buffer())),S.point=f,k&&l.lineEnd()}function p(t,e){t=Math.max(-Hl,Math.min(Hl,t)),e=Math.max(-Hl,Math.min(Hl,e));var n=u(t,e);if(v&&m.push([t,e]),M)y=t,x=e,b=n,M=!1,n&&(l.lineStart(),l.point(t,e));else if(n&&k)l.point(t,e);else{var r={a:{x:_,y:w},b:{x:t,y:e}};z(r)?(k||(l.lineStart(),l.point(r.a.x,r.a.y)),l.point(r.b.x,r.b.y),n||l.lineEnd(),A=!1):n&&(l.lineStart(),l.point(t,e),A=!1)}_=t,w=e,k=n}var g,v,m,y,x,b,_,w,k,M,A,L=l,T=Re(),z=Ze(t,e,n,r),S={point:f,lineStart:d,lineEnd:h,polygonStart:function(){l=T,g=[],v=[],A=!0},polygonEnd:function(){l=L,g=ui.merge(g);var e=s([t,r]),n=A&&e,a=g.length;(n||a)&&(l.polygonStart(),n&&(l.lineStart(),c(null,null,1,l),l.lineEnd()),a&&Oe(g,o,e,c,l),l.polygonEnd()),g=v=m=null}};return S}}function Ue(t){var e=0,n=Bi/3,r=cn(t),a=r(e,n);return a.parallels=function(t){return arguments.length?r(e=t[0]*Bi/180,n=t[1]*Bi/180):[e/Bi*180,n/Bi*180]},a}function Xe(t,e){function n(t,e){var n=Math.sqrt(o-2*a*Math.sin(e))/a;return[n*Math.sin(t*=a),i-n*Math.cos(t)]}var r=Math.sin(t),a=(r+Math.sin(e))/2,o=1+r*(2*a-r),i=Math.sqrt(o)/a;return n.invert=function(t,e){var n=i-e;return[Math.atan2(t,n)/a,rt((o-(t*t+n*n)*a*a)/(2*a))]},n}function Ge(){function t(t,e){Zl+=a*t-r*e,r=t,a=e}var e,n,r,a;$l.point=function(o,i){$l.point=t,e=r=o,n=a=i},$l.lineEnd=function(){t(e,n)}}function $e(t,e){Yl>t&&(Yl=t),t>Xl&&(Xl=t),Ul>e&&(Ul=e),e>Gl&&(Gl=e)}function Qe(){function t(t,e){i.push(\"M\",t,\",\",e,o)}function e(t,e){i.push(\"M\",t,\",\",e),l.point=n}function n(t,e){i.push(\"L\",t,\",\",e)}function r(){l.point=t}function a(){i.push(\"Z\")}var o=We(4.5),i=[],l={point:t,lineStart:function(){l.point=e},lineEnd:r,polygonStart:function(){l.lineEnd=a},polygonEnd:function(){l.lineEnd=r,l.point=t},pointRadius:function(t){return o=We(t),l},result:function(){if(i.length){var t=i.join(\"\");return i=[],t}}};return l}function We(t){return\"m0,\"+t+\"a\"+t+\",\"+t+\" 0 1,1 0,\"+-2*t+\"a\"+t+\",\"+t+\" 0 1,1 0,\"+2*t+\"z\"}function Je(t,e){Cl+=t,Ol+=e,++Pl}function Ke(){function t(t,r){var a=t-e,o=r-n,i=Math.sqrt(a*a+o*o);Nl+=i*(e+t)/2,Dl+=i*(n+r)/2,Il+=i,Je(e=t,n=r)}var e,n;Wl.point=function(r,a){Wl.point=t,Je(e=r,n=a)}}function tn(){Wl.point=Je}function en(){function t(t,e){var n=t-r,o=e-a,i=Math.sqrt(n*n+o*o);Nl+=i*(r+t)/2,Dl+=i*(a+e)/2,Il+=i,i=a*t-r*e,Rl+=i*(r+t),jl+=i*(a+e),ql+=3*i,Je(r=t,a=e)}var e,n,r,a;Wl.point=function(o,i){Wl.point=t,Je(e=r=o,n=a=i)},Wl.lineEnd=function(){t(e,n)}}function nn(t){function e(e,n){t.moveTo(e+i,n),t.arc(e,n,i,0,Hi)}function n(e,n){t.moveTo(e,n),l.point=r}function r(e,n){t.lineTo(e,n)}function a(){l.point=e}function o(){t.closePath()}var i=4.5,l={point:e,lineStart:function(){l.point=n},lineEnd:a,polygonStart:function(){l.lineEnd=o},polygonEnd:function(){l.lineEnd=a,l.point=e},pointRadius:function(t){return i=t,l},result:k};return l}function rn(t){function e(t){return(l?r:n)(t)}function n(e){return ln(e,function(n,r){n=t(n,r),e.point(n[0],n[1])})}function r(e){function n(n,r){n=t(n,r),e.point(n[0],n[1])}function r(){x=NaN,M.point=o,e.lineStart()}function o(n,r){var o=me([n,r]),i=t(n,r);a(x,b,y,_,w,k,x=i[0],b=i[1],y=n,_=o[0],w=o[1],k=o[2],l,e),e.point(x,b)}function i(){M.point=n,e.lineEnd()}function s(){r(),M.point=c,M.lineEnd=u}function c(t,e){o(f=t,d=e),h=x,p=b,g=_,v=w,m=k,M.point=o}function u(){a(x,b,y,_,w,k,h,p,f,g,v,m,l,e),M.lineEnd=i,i()}var f,d,h,p,g,v,m,y,x,b,_,w,k,M={point:n,lineStart:r,lineEnd:i,polygonStart:function(){e.polygonStart(),M.lineStart=s},polygonEnd:function(){e.polygonEnd(),M.lineStart=r}};return M}function a(e,n,r,l,s,c,u,f,d,h,p,g,v,m){var y=u-e,x=f-n,b=y*y+x*x;if(b>4*o&&v--){var _=l+h,w=s+p,k=c+g,M=Math.sqrt(_*_+w*w+k*k),A=Math.asin(k/=M),L=wi(wi(k)-1)<qi||wi(r-d)<qi?(r+d)/2:Math.atan2(w,_),T=t(L,A),z=T[0],S=T[1],E=z-e,C=S-n,O=x*E-y*C;(O*O/b>o||wi((y*E+x*C)/b-.5)>.3||i>l*h+s*p+c*g)&&(a(e,n,r,l,s,c,z,S,L,_/=M,w/=M,k,v,m),m.point(z,S),a(z,S,L,_,w,k,u,f,d,h,p,g,v,m))}}var o=.5,i=Math.cos(30*Yi),l=16;return e.precision=function(t){return arguments.length?(l=(o=t*t)>0&&16,e):Math.sqrt(o)},e}function an(t){var e=rn(function(e,n){return t([e*Ui,n*Ui])});return function(t){return un(e(t))}}function on(t){this.stream=t}function ln(t,e){return{point:e,sphere:function(){t.sphere()},lineStart:function(){t.lineStart()},lineEnd:function(){t.lineEnd()},polygonStart:function(){t.polygonStart()},polygonEnd:function(){t.polygonEnd()}}}function sn(t){return cn(function(){return t})()}function cn(t){function e(t){return t=l(t[0]*Yi,t[1]*Yi),[t[0]*d+s,c-t[1]*d]}function n(t){return t=l.invert((t[0]-s)/d,(c-t[1])/d),t&&[t[0]*Ui,t[1]*Ui]}function r(){l=Ee(i=hn(m,y,x),o);var t=o(g,v);return s=h-t[0]*d,c=p+t[1]*d,a()}function a(){return u&&(u.valid=!1,u=null),e}var o,i,l,s,c,u,f=rn(function(t,e){return t=o(t,e),[t[0]*d+s,c-t[1]*d]}),d=150,h=480,p=250,g=0,v=0,m=0,y=0,x=0,_=Bl,w=b,k=null,M=null;return e.stream=function(t){return u&&(u.valid=!1),u=un(_(i,f(w(t)))),u.valid=!0,u},e.clipAngle=function(t){return arguments.length?(_=null==t?(k=t,Bl):Ve((k=+t)*Yi),a()):k},e.clipExtent=function(t){return arguments.length?(M=t,w=t?Ye(t[0][0],t[0][1],t[1][0],t[1][1]):b,a()):M},e.scale=function(t){return arguments.length?(d=+t,r()):d},e.translate=function(t){return arguments.length?(h=+t[0],p=+t[1],r()):[h,p]},e.center=function(t){return arguments.length?(g=t[0]%360*Yi,v=t[1]%360*Yi,r()):[g*Ui,v*Ui]},e.rotate=function(t){return arguments.length?(m=t[0]%360*Yi,y=t[1]%360*Yi,x=t.length>2?t[2]%360*Yi:0,r()):[m*Ui,y*Ui,x*Ui]},ui.rebind(e,f,\"precision\"),function(){return o=t.apply(this,arguments),e.invert=o.invert&&n,r()}}function un(t){return ln(t,function(e,n){t.point(e*Yi,n*Yi)})}function fn(t,e){return[t,e]}function dn(t,e){return[t>Bi?t-Hi:-Bi>t?t+Hi:t,e]}function hn(t,e,n){return t?e||n?Ee(gn(t),vn(e,n)):gn(t):e||n?vn(e,n):dn}function pn(t){return function(e,n){return e+=t,[e>Bi?e-Hi:-Bi>e?e+Hi:e,n]}}function gn(t){var e=pn(t);return e.invert=pn(-t),e}function vn(t,e){function n(t,e){var n=Math.cos(e),l=Math.cos(t)*n,s=Math.sin(t)*n,c=Math.sin(e),u=c*r+l*a;return[Math.atan2(s*o-u*i,l*r-c*a),rt(u*o+s*i)]}var r=Math.cos(t),a=Math.sin(t),o=Math.cos(e),i=Math.sin(e);return n.invert=function(t,e){var n=Math.cos(e),l=Math.cos(t)*n,s=Math.sin(t)*n,c=Math.sin(e),u=c*o-s*i;return[Math.atan2(s*o+c*i,l*r+u*a),rt(u*r-l*a)]},n}function mn(t,e){var n=Math.cos(t),r=Math.sin(t);return function(a,o,i,l){var s=i*e;null!=a?(a=yn(n,a),o=yn(n,o),(i>0?o>a:a>o)&&(a+=i*Hi)):(a=t+i*Hi,o=t-.5*s);for(var c,u=a;i>0?u>o:o>u;u-=s)l.point((c=ke([n,-r*Math." -, -"cos(u),-r*Math.sin(u)]))[0],c[1])}}function yn(t,e){var n=me(e);n[0]-=t,we(n);var r=nt(-n[1]);return((-n[2]<0?-r:r)+2*Math.PI-qi)%(2*Math.PI)}function xn(t,e,n){var r=ui.range(t,e-qi,n).concat(e);return function(t){return r.map(function(e){return[t,e]})}}function bn(t,e,n){var r=ui.range(t,e-qi,n).concat(e);return function(t){return r.map(function(e){return[e,t]})}}function _n(t){return t.source}function wn(t){return t.target}function kn(t,e,n,r){var a=Math.cos(e),o=Math.sin(e),i=Math.cos(r),l=Math.sin(r),s=a*Math.cos(t),c=a*Math.sin(t),u=i*Math.cos(n),f=i*Math.sin(n),d=2*Math.asin(Math.sqrt(lt(r-e)+a*i*lt(n-t))),h=1/Math.sin(d),p=d?function(t){var e=Math.sin(t*=d)*h,n=Math.sin(d-t)*h,r=n*s+e*u,a=n*c+e*f,i=n*o+e*l;return[Math.atan2(a,r)*Ui,Math.atan2(i,Math.sqrt(r*r+a*a))*Ui]}:function(){return[t*Ui,e*Ui]};return p.distance=d,p}function Mn(){function t(t,a){var o=Math.sin(a*=Yi),i=Math.cos(a),l=wi((t*=Yi)-e),s=Math.cos(l);Jl+=Math.atan2(Math.sqrt((l=i*Math.sin(l))*l+(l=r*o-n*i*s)*l),n*o+r*i*s),e=t,n=o,r=i}var e,n,r;Kl.point=function(a,o){e=a*Yi,n=Math.sin(o*=Yi),r=Math.cos(o),Kl.point=t},Kl.lineEnd=function(){Kl.point=Kl.lineEnd=k}}function An(t,e){function n(e,n){var r=Math.cos(e),a=Math.cos(n),o=t(r*a);return[o*a*Math.sin(e),o*Math.sin(n)]}return n.invert=function(t,n){var r=Math.sqrt(t*t+n*n),a=e(r),o=Math.sin(a),i=Math.cos(a);return[Math.atan2(t*o,r*i),Math.asin(r&&n*o/r)]},n}function Ln(t,e){function n(t,e){i>0?-Zi+qi>e&&(e=-Zi+qi):e>Zi-qi&&(e=Zi-qi);var n=i/Math.pow(a(e),o);return[n*Math.sin(o*t),i-n*Math.cos(o*t)]}var r=Math.cos(t),a=function(t){return Math.tan(Bi/4+t/2)},o=t===e?Math.sin(t):Math.log(r/Math.cos(e))/Math.log(a(e)/a(t)),i=r*Math.pow(a(t),o)/o;return o?(n.invert=function(t,e){var n=i-e,r=tt(o)*Math.sqrt(t*t+n*n);return[Math.atan2(t,n)/o,2*Math.atan(Math.pow(i/r,1/o))-Zi]},n):zn}function Tn(t,e){function n(t,e){var n=o-e;return[n*Math.sin(a*t),o-n*Math.cos(a*t)]}var r=Math.cos(t),a=t===e?Math.sin(t):(r-Math.cos(e))/(e-t),o=r/a+t;return wi(a)<qi?fn:(n.invert=function(t,e){var n=o-e;return[Math.atan2(t,n)/a,o-tt(a)*Math.sqrt(t*t+n*n)]},n)}function zn(t,e){return[t,Math.log(Math.tan(Bi/4+e/2))]}function Sn(t){var e,n=sn(t),r=n.scale,a=n.translate,o=n.clipExtent;return n.scale=function(){var t=r.apply(n,arguments);return t===n?e?n.clipExtent(null):n:t},n.translate=function(){var t=a.apply(n,arguments);return t===n?e?n.clipExtent(null):n:t},n.clipExtent=function(t){var i=o.apply(n,arguments);if(i===n){if(e=null==t){var l=Bi*r(),s=a();o([[s[0]-l,s[1]-l],[s[0]+l,s[1]+l]])}}else e&&(i=null);return i},n.clipExtent(null)}function En(t,e){return[Math.log(Math.tan(Bi/4+e/2)),-t]}function Cn(t){return t[0]}function On(t){return t[1]}function Pn(t){for(var e=t.length,n=[0,1],r=2,a=2;e>a;a++){for(;r>1&&et(t[n[r-2]],t[n[r-1]],t[a])<=0;)--r;n[r++]=a}return n.slice(0,r)}function Nn(t,e){return t[0]-e[0]||t[1]-e[1]}function Dn(t,e,n){return(n[0]-e[0])*(t[1]-e[1])<(n[1]-e[1])*(t[0]-e[0])}function In(t,e,n,r){var a=t[0],o=n[0],i=e[0]-a,l=r[0]-o,s=t[1],c=n[1],u=e[1]-s,f=r[1]-c,d=(l*(s-c)-f*(a-o))/(f*i-l*u);return[a+d*i,s+d*u]}function Rn(t){var e=t[0],n=t[t.length-1];return!(e[0]-n[0]||e[1]-n[1])}function jn(){or(this),this.edge=this.site=this.circle=null}function qn(t){var e=fs.pop()||new jn;return e.site=t,e}function Fn(t){Qn(t),ss.remove(t),fs.push(t),or(t)}function Bn(t){var e=t.circle,n=e.x,r=e.cy,a={x:n,y:r},o=t.P,i=t.N,l=[t];Fn(t);for(var s=o;s.circle&&wi(n-s.circle.x)<qi&&wi(r-s.circle.cy)<qi;)o=s.P,l.unshift(s),Fn(s),s=o;l.unshift(s),Qn(s);for(var c=i;c.circle&&wi(n-c.circle.x)<qi&&wi(r-c.circle.cy)<qi;)i=c.N,l.push(c),Fn(c),c=i;l.push(c),Qn(c);var u,f=l.length;for(u=1;f>u;++u)c=l[u],s=l[u-1],nr(c.edge,s.site,c.site,a);s=l[0],c=l[f-1],c.edge=tr(s.site,c.site,null,a),$n(s),$n(c)}function Hn(t){for(var e,n,r,a,o=t.x,i=t.y,l=ss._;l;)if(r=Vn(l,i)-o,r>qi)l=l.L;else{if(a=o-Zn(l,i),!(a>qi)){r>-qi?(e=l.P,n=l):a>-qi?(e=l,n=l.N):e=n=l;break}if(!l.R){e=l;break}l=l.R}var s=qn(t);if(ss.insert(e,s),e||n){if(e===n)return Qn(e),n=qn(e.site),ss.insert(s,n),s.edge=n.edge=tr(e.site,s.site),$n(e),void $n(n);if(!n)return void(s.edge=tr(e.site,s.site));Qn(e),Qn(n);var c=e.site,u=c.x,f=c.y,d=t.x-u,h=t.y-f,p=n.site,g=p.x-u,v=p.y-f,m=2*(d*v-h*g),y=d*d+h*h,x=g*g+v*v,b={x:(v*y-h*x)/m+u,y:(d*x-g*y)/m+f};nr(n.edge,c,p,b),s.edge=tr(c,t,null,b),n.edge=tr(t,p,null,b),$n(e),$n(n)}}function Vn(t,e){var n=t.site,r=n.x,a=n.y,o=a-e;if(!o)return r;var i=t.P;if(!i)return-(1/0);n=i.site;var l=n.x,s=n.y,c=s-e;if(!c)return l;var u=l-r,f=1/o-1/c,d=u/c;return f?(-d+Math.sqrt(d*d-2*f*(u*u/(-2*c)-s+c/2+a-o/2)))/f+r:(r+l)/2}function Zn(t,e){var n=t.N;if(n)return Vn(n,e);var r=t.site;return r.y===e?r.x:1/0}function Yn(t){this.site=t,this.edges=[]}function Un(t){for(var e,n,r,a,o,i,l,s,c,u,f=t[0][0],d=t[1][0],h=t[0][1],p=t[1][1],g=ls,v=g.length;v--;)if(o=g[v],o&&o.prepare())for(l=o.edges,s=l.length,i=0;s>i;)u=l[i].end(),r=u.x,a=u.y,c=l[++i%s].start(),e=c.x,n=c.y,(wi(r-e)>qi||wi(a-n)>qi)&&(l.splice(i,0,new rr(er(o.site,u,wi(r-f)<qi&&p-a>qi?{x:f,y:wi(e-f)<qi?n:p}:wi(a-p)<qi&&d-r>qi?{x:wi(n-p)<qi?e:d,y:p}:wi(r-d)<qi&&a-h>qi?{x:d,y:wi(e-d)<qi?n:h}:wi(a-h)<qi&&r-f>qi?{x:wi(n-h)<qi?e:f,y:h}:null),o.site,null)),++s)}function Xn(t,e){return e.angle-t.angle}function Gn(){or(this),this.x=this.y=this.arc=this.site=this.cy=null}function $n(t){var e=t.P,n=t.N;if(e&&n){var r=e.site,a=t.site,o=n.site;if(r!==o){var i=a.x,l=a.y,s=r.x-i,c=r.y-l,u=o.x-i,f=o.y-l,d=2*(s*f-c*u);if(!(d>=-Fi)){var h=s*s+c*c,p=u*u+f*f,g=(f*h-c*p)/d,v=(s*p-u*h)/d,f=v+l,m=ds.pop()||new Gn;m.arc=t,m.site=a,m.x=g+i,m.y=f+Math.sqrt(g*g+v*v),m.cy=f,t.circle=m;for(var y=null,x=us._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}us.insert(y,m),y||(cs=m)}}}}function Qn(t){var e=t.circle;e&&(e.P||(cs=e.N),us.remove(e),ds.push(e),or(e),t.circle=null)}function Wn(t){for(var e,n=is,r=Ze(t[0][0],t[0][1],t[1][0],t[1][1]),a=n.length;a--;)e=n[a],(!Jn(e,t)||!r(e)||wi(e.a.x-e.b.x)<qi&&wi(e.a.y-e.b.y)<qi)&&(e.a=e.b=null,n.splice(a,1))}function Jn(t,e){var n=t.b;if(n)return!0;var r,a,o=t.a,i=e[0][0],l=e[1][0],s=e[0][1],c=e[1][1],u=t.l,f=t.r,d=u.x,h=u.y,p=f.x,g=f.y,v=(d+p)/2,m=(h+g)/2;if(g===h){if(i>v||v>=l)return;if(d>p){if(o){if(o.y>=c)return}else o={x:v,y:s};n={x:v,y:c}}else{if(o){if(o.y<s)return}else o={x:v,y:c};n={x:v,y:s}}}else if(r=(d-p)/(g-h),a=m-r*v,-1>r||r>1)if(d>p){if(o){if(o.y>=c)return}else o={x:(s-a)/r,y:s};n={x:(c-a)/r,y:c}}else{if(o){if(o.y<s)return}else o={x:(c-a)/r,y:c};n={x:(s-a)/r,y:s}}else if(g>h){if(o){if(o.x>=l)return}else o={x:i,y:r*i+a};n={x:l,y:r*l+a}}else{if(o){if(o.x<i)return}else o={x:l,y:r*l+a};n={x:i,y:r*i+a}}return t.a=o,t.b=n,!0}function Kn(t,e){this.l=t,this.r=e,this.a=this.b=null}function tr(t,e,n,r){var a=new Kn(t,e);return is.push(a),n&&nr(a,t,e,n),r&&nr(a,e,t,r),ls[t.i].edges.push(new rr(a,t,e)),ls[e.i].edges.push(new rr(a,e,t)),a}function er(t,e,n){var r=new Kn(t,null);return r.a=e,r.b=n,is.push(r),r}function nr(t,e,n,r){t.a||t.b?t.l===n?t.b=r:t.a=r:(t.a=r,t.l=e,t.r=n)}function rr(t,e,n){var r=t.a,a=t.b;this.edge=t,this.site=e,this.angle=n?Math.atan2(n.y-e.y,n.x-e.x):t.l===e?Math.atan2(a.x-r.x,r.y-a.y):Math.atan2(r.x-a.x,a.y-r.y)}function ar(){this._=null}function or(t){t.U=t.C=t.L=t.R=t.P=t.N=null}function ir(t,e){var n=e,r=e.R,a=n.U;a?a.L===n?a.L=r:a.R=r:t._=r,r.U=a,n.U=r,n.R=r.L,n.R&&(n.R.U=n),r.L=n}function lr(t,e){var n=e,r=e.L,a=n.U;a?a.L===n?a.L=r:a.R=r:t._=r,r.U=a,n.U=r,n.L=r.R,n.L&&(n.L.U=n),r.R=n}function sr(t){for(;t.L;)t=t.L;return t}function cr(t,e){var n,r,a,o=t.sort(ur).pop();for(is=[],ls=new Array(t.length),ss=new ar,us=new ar;;)if(a=cs,o&&(!a||o.y<a.y||o.y===a.y&&o.x<a.x))o.x===n&&o.y===r||(ls[o.i]=new Yn(o),Hn(o),n=o.x,r=o.y),o=t.pop();else{if(!a)break;Bn(a.arc)}e&&(Wn(e),Un(e));var i={cells:ls,edges:is};return ss=us=is=ls=null,i}function ur(t,e){return e.y-t.y||e.x-t.x}function fr(t,e,n){return(t.x-n.x)*(e.y-t.y)-(t.x-e.x)*(n.y-t.y)}function dr(t){return t.x}function hr(t){return t.y}function pr(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function gr(t,e,n,r,a,o){if(!t(e,n,r,a,o)){var i=.5*(n+a),l=.5*(r+o),s=e.nodes;s[0]&&gr(t,s[0],n,r,i,l),s[1]&&gr(t,s[1],i,r,a,l),s[2]&&gr(t,s[2],n,l,i,o),s[3]&&gr(t,s[3],i,l,a,o)}}function vr(t,e,n,r,a,o,i){var l,s=1/0;return function c(t,u,f,d,h){if(!(u>o||f>i||r>d||a>h)){if(p=t.point){var p,g=e-t.x,v=n-t.y,m=g*g+v*v;if(s>m){var y=Math.sqrt(s=m);r=e-y,a=n-y,o=e+y,i=n+y,l=p}}for(var x=t.nodes,b=.5*(u+d),_=.5*(f+h),w=e>=b,k=n>=_,M=k<<1|w,A=M+4;A>M;++M)if(t=x[3&M])switch(3&M){case 0:c(t,u,f,b,_);break;case 1:c(t,b,f,d,_);break;case 2:c(t,u,_,b,h);break;case 3:c(t,b,_,d,h)}}}(t,r,a,o,i),l}function mr(t,e){t=ui.rgb(t),e=ui.rgb(e);var n=t.r,r=t.g,a=t.b,o=e.r-n,i=e.g-r,l=e.b-a;return function(t){return\"#\"+wt(Math.round(n+o*t))+wt(Math.round(r+i*t))+wt(Math.round(a+l*t))}}function yr(t,e){var n,r={},a={};for(n in t)n in e?r[n]=_r(t[n],e[n]):a[n]=t[n];for(n in e)n in t||(a[n]=e[n]);return function(t){for(n in r)a[n]=r[n](t);return a}}function xr(t,e){return t=+t,e=+e,function(n){return t*(1-n)+e*n}}function br(t,e){var n,r,a,o=ps.lastIndex=gs.lastIndex=0,i=-1,l=[],s=[];for(t+=\"\",e+=\"\";(n=ps.exec(t))&&(r=gs.exec(e));)(a=r.index)>o&&(a=e.slice(o,a),l[i]?l[i]+=a:l[++i]=a),(n=n[0])===(r=r[0])?l[i]?l[i]+=r:l[++i]=r:(l[++i]=null,s.push({i:i,x:xr(n,r)})),o=gs.lastIndex;return o<e.length&&(a=e.slice(o),l[i]?l[i]+=a:l[++i]=a),l.length<2?s[0]?(e=s[0].x,function(t){return e(t)+\"\"}):function(){return e}:(e=s.length,function(t){for(var n,r=0;e>r;++r)l[(n=s[r]).i]=n.x(t);return l.join(\"\")})}function _r(t,e){for(var n,r=ui.interpolators.length;--r>=0&&!(n=ui.interpolators[r](t,e)););return n}function wr(t,e){var n,r=[],a=[],o=t.length,i=e.length,l=Math.min(t.length,e.length);for(n=0;l>n;++n)r.push(_r(t[n],e[n]));for(;o>n;++n)a[n]=t[n];for(;i>n;++n)a[n]=e[n];return function(t){for(n=0;l>n;++n)a[n]=r[n](t);return a}}function kr(t){return function(e){return 0>=e?0:e>=1?1:t(e)}}function Mr(t){return function(e){return 1-t(1-e)}}function Ar(t){return function(e){return.5*(.5>e?t(2*e):2-t(2-2*e))}" -, -"}function Lr(t){return t*t}function Tr(t){return t*t*t}function zr(t){if(0>=t)return 0;if(t>=1)return 1;var e=t*t,n=e*t;return 4*(.5>t?n:3*(t-e)+n-.75)}function Sr(t){return function(e){return Math.pow(e,t)}}function Er(t){return 1-Math.cos(t*Zi)}function Cr(t){return Math.pow(2,10*(t-1))}function Or(t){return 1-Math.sqrt(1-t*t)}function Pr(t,e){var n;return arguments.length<2&&(e=.45),arguments.length?n=e/Hi*Math.asin(1/t):(t=1,n=e/4),function(r){return 1+t*Math.pow(2,-10*r)*Math.sin((r-n)*Hi/e)}}function Nr(t){return t||(t=1.70158),function(e){return e*e*((t+1)*e-t)}}function Dr(t){return 1/2.75>t?7.5625*t*t:2/2.75>t?7.5625*(t-=1.5/2.75)*t+.75:2.5/2.75>t?7.5625*(t-=2.25/2.75)*t+.9375:7.5625*(t-=2.625/2.75)*t+.984375}function Ir(t,e){t=ui.hcl(t),e=ui.hcl(e);var n=t.h,r=t.c,a=t.l,o=e.h-n,i=e.c-r,l=e.l-a;return isNaN(i)&&(i=0,r=isNaN(r)?e.c:r),isNaN(o)?(o=0,n=isNaN(n)?e.h:n):o>180?o-=360:-180>o&&(o+=360),function(t){return dt(n+o*t,r+i*t,a+l*t)+\"\"}}function Rr(t,e){t=ui.hsl(t),e=ui.hsl(e);var n=t.h,r=t.s,a=t.l,o=e.h-n,i=e.s-r,l=e.l-a;return isNaN(i)&&(i=0,r=isNaN(r)?e.s:r),isNaN(o)?(o=0,n=isNaN(n)?e.h:n):o>180?o-=360:-180>o&&(o+=360),function(t){return ut(n+o*t,r+i*t,a+l*t)+\"\"}}function jr(t,e){t=ui.lab(t),e=ui.lab(e);var n=t.l,r=t.a,a=t.b,o=e.l-n,i=e.a-r,l=e.b-a;return function(t){return pt(n+o*t,r+i*t,a+l*t)+\"\"}}function qr(t,e){return e-=t,function(n){return Math.round(t+e*n)}}function Fr(t){var e=[t.a,t.b],n=[t.c,t.d],r=Hr(e),a=Br(e,n),o=Hr(Vr(n,e,-a))||0;e[0]*n[1]<n[0]*e[1]&&(e[0]*=-1,e[1]*=-1,r*=-1,a*=-1),this.rotate=(r?Math.atan2(e[1],e[0]):Math.atan2(-n[0],n[1]))*Ui,this.translate=[t.e,t.f],this.scale=[r,o],this.skew=o?Math.atan2(a,o)*Ui:0}function Br(t,e){return t[0]*e[0]+t[1]*e[1]}function Hr(t){var e=Math.sqrt(Br(t,t));return e&&(t[0]/=e,t[1]/=e),e}function Vr(t,e,n){return t[0]+=n*e[0],t[1]+=n*e[1],t}function Zr(t){return t.length?t.pop()+\",\":\"\"}function Yr(t,e,n,r){if(t[0]!==e[0]||t[1]!==e[1]){var a=n.push(\"translate(\",null,\",\",null,\")\");r.push({i:a-4,x:xr(t[0],e[0])\n" -, -"},{i:a-2,x:xr(t[1],e[1])})}else(e[0]||e[1])&&n.push(\"translate(\"+e+\")\")}function Ur(t,e,n,r){t!==e?(t-e>180?e+=360:e-t>180&&(t+=360),r.push({i:n.push(Zr(n)+\"rotate(\",null,\")\")-2,x:xr(t,e)})):e&&n.push(Zr(n)+\"rotate(\"+e+\")\")}function Xr(t,e,n,r){t!==e?r.push({i:n.push(Zr(n)+\"skewX(\",null,\")\")-2,x:xr(t,e)}):e&&n.push(Zr(n)+\"skewX(\"+e+\")\")}function Gr(t,e,n,r){if(t[0]!==e[0]||t[1]!==e[1]){var a=n.push(Zr(n)+\"scale(\",null,\",\",null,\")\");r.push({i:a-4,x:xr(t[0],e[0])},{i:a-2,x:xr(t[1],e[1])})}else 1===e[0]&&1===e[1]||n.push(Zr(n)+\"scale(\"+e+\")\")}function $r(t,e){var n=[],r=[];return t=ui.transform(t),e=ui.transform(e),Yr(t.translate,e.translate,n,r),Ur(t.rotate,e.rotate,n,r),Xr(t.skew,e.skew,n,r),Gr(t.scale,e.scale,n,r),t=e=null,function(t){for(var e,a=-1,o=r.length;++a<o;)n[(e=r[a]).i]=e.x(t);return n.join(\"\")}}function Qr(t,e){return e=(e-=t=+t)||1/e,function(n){return(n-t)/e}}function Wr(t,e){return e=(e-=t=+t)||1/e,function(n){return Math.max(0,Math.min(1,(n-t)/e))}}function Jr(t){for(var e=t.source,n=t.target,r=ta(e,n),a=[e];e!==r;)e=e.parent,a.push(e);for(var o=a.length;n!==r;)a.splice(o,0,n),n=n.parent;return a}function Kr(t){for(var e=[],n=t.parent;null!=n;)e.push(t),t=n,n=n.parent;return e.push(t),e}function ta(t,e){if(t===e)return t;for(var n=Kr(t),r=Kr(e),a=n.pop(),o=r.pop(),i=null;a===o;)i=a,a=n.pop(),o=r.pop();return i}function ea(t){t.fixed|=2}function na(t){t.fixed&=-7}function ra(t){t.fixed|=4,t.px=t.x,t.py=t.y}function aa(t){t.fixed&=-5}function oa(t,e,n){var r=0,a=0;if(t.charge=0,!t.leaf)for(var o,i=t.nodes,l=i.length,s=-1;++s<l;)o=i[s],null!=o&&(oa(o,e,n),t.charge+=o.charge,r+=o.charge*o.cx,a+=o.charge*o.cy);if(t.point){t.leaf||(t.point.x+=Math.random()-.5,t.point.y+=Math.random()-.5);var c=e*n[t.point.index];t.charge+=t.pointCharge=c,r+=c*t.point.x,a+=c*t.point.y}t.cx=r/t.charge,t.cy=a/t.charge}function ia(t,e){return ui.rebind(t,e,\"sort\",\"children\",\"value\"),t.nodes=t,t.links=da,t}function la(t,e){for(var n=[t];null!=(t=n.pop());)if(e(t),(a=t.children)&&(r=a.length))for(var r,a;--r>=0;)n.push(a[r])}function sa(t,e){for(var n=[t],r=[];null!=(t=n.pop());)if(r.push(t),(o=t.children)&&(a=o.length))for(var a,o,i=-1;++i<a;)n.push(o[i]);for(;null!=(t=r.pop());)e(t)}function ca(t){return t.children}function ua(t){return t.value}function fa(t,e){return e.value-t.value}function da(t){return ui.merge(t.map(function(t){return(t.children||[]).map(function(e){return{source:t,target:e}})}))}function ha(t){return t.x}function pa(t){return t.y}function ga(t,e,n){t.y0=e,t.y=n}function va(t){return ui.range(t.length)}function ma(t){for(var e=-1,n=t[0].length,r=[];++e<n;)r[e]=0;return r}function ya(t){for(var e,n=1,r=0,a=t[0][1],o=t.length;o>n;++n)(e=t[n][1])>a&&(r=n,a=e);return r}function xa(t){return t.reduce(ba,0)}function ba(t,e){return t+e[1]}function _a(t,e){return wa(t,Math.ceil(Math.log(e.length)/Math.LN2+1))}function wa(t,e){for(var n=-1,r=+t[0],a=(t[1]-r)/e,o=[];++n<=e;)o[n]=a*n+r;return o}function ka(t){return[ui.min(t),ui.max(t)]}function Ma(t,e){return t.value-e.value}function Aa(t,e){var n=t._pack_next;t._pack_next=e,e._pack_prev=t,e._pack_next=n,n._pack_prev=e}function La(t,e){t._pack_next=e,e._pack_prev=t}function Ta(t,e){var n=e.x-t.x,r=e.y-t.y,a=t.r+e.r;return.999*a*a>n*n+r*r}function za(t){function e(t){u=Math.min(t.x-t.r,u),f=Math.max(t.x+t.r,f),d=Math.min(t.y-t.r,d),h=Math.max(t.y+t.r,h)}if((n=t.children)&&(c=n.length)){var n,r,a,o,i,l,s,c,u=1/0,f=-(1/0),d=1/0,h=-(1/0);if(n.forEach(Sa),r=n[0],r.x=-r.r,r.y=0,e(r),c>1&&(a=n[1],a.x=a.r,a.y=0,e(a),c>2))for(o=n[2],Oa(r,a,o),e(o),Aa(r,o),r._pack_prev=o,Aa(o,a),a=r._pack_next,i=3;c>i;i++){Oa(r,a,o=n[i]);var p=0,g=1,v=1;for(l=a._pack_next;l!==a;l=l._pack_next,g++)if(Ta(l,o)){p=1;break}if(1==p)for(s=r._pack_prev;s!==l._pack_prev&&!Ta(s,o);s=s._pack_prev,v++);p?(v>g||g==v&&a.r<r.r?La(r,a=l):La(r=s,a),i--):(Aa(r,o),a=o,e(o))}var m=(u+f)/2,y=(d+h)/2,x=0;for(i=0;c>i;i++)o=n[i],o.x-=m,o.y-=y,x=Math.max(x,o.r+Math.sqrt(o.x*o.x+o.y*o.y));t.r=x,n.forEach(Ea)}}function Sa(t){t._pack_next=t._pack_prev=t}function Ea(t){delete t._pack_next,delete t._pack_prev}function Ca(t,e,n,r){var a=t.children;if(t.x=e+=r*t.x,t.y=n+=r*t.y,t.r*=r,a)for(var o=-1,i=a.length;++o<i;)Ca(a[o],e,n,r)}function Oa(t,e,n){var r=t.r+n.r,a=e.x-t.x,o=e.y-t.y;if(r&&(a||o)){var i=e.r+n.r,l=a*a+o*o;i*=i,r*=r;var s=.5+(r-i)/(2*l),c=Math.sqrt(Math.max(0,2*i*(r+l)-(r-=l)*r-i*i))/(2*l);n.x=t.x+s*a+c*o,n.y=t.y+s*o-c*a}else n.x=t.x+r,n.y=t.y}function Pa(t,e){return t.parent==e.parent?1:2}function Na(t){var e=t.children;return e.length?e[0]:t.t}function Da(t){var e,n=t.children;return(e=n.length)?n[e-1]:t.t}function Ia(t,e,n){var r=n/(e.i-t.i);e.c-=r,e.s+=n,t.c+=r,e.z+=n,e.m+=n}function Ra(t){for(var e,n=0,r=0,a=t.children,o=a.length;--o>=0;)e=a[o],e.z+=n,e.m+=n,n+=e.s+(r+=e.c)}function ja(t,e,n){return t.a.parent===e.parent?t.a:n}function qa(t){return 1+ui.max(t,function(t){return t.y})}function Fa(t){return t.reduce(function(t,e){return t+e.x},0)/t.length}function Ba(t){var e=t.children;return e&&e.length?Ba(e[0]):t}function Ha(t){var e,n=t.children;return n&&(e=n.length)?Ha(n[e-1]):t}function Va(t){return{x:t.x,y:t.y,dx:t.dx,dy:t.dy}}function Za(t,e){var n=t.x+e[3],r=t.y+e[0],a=t.dx-e[1]-e[3],o=t.dy-e[0]-e[2];return 0>a&&(n+=a/2,a=0),0>o&&(r+=o/2,o=0),{x:n,y:r,dx:a,dy:o}}function Ya(t){var e=t[0],n=t[t.length-1];return n>e?[e,n]:[n,e]}function Ua(t){return t.rangeExtent?t.rangeExtent():Ya(t.range())}function Xa(t,e,n,r){var a=n(t[0],t[1]),o=r(e[0],e[1]);return function(t){return o(a(t))}}function Ga(t,e){var n,r=0,a=t.length-1,o=t[r],i=t[a];return o>i&&(n=r,r=a,a=n,n=o,o=i,i=n),t[r]=e.floor(o),t[a]=e.ceil(i),t}function $a(t){return t?{floor:function(e){return Math.floor(e/t)*t},ceil:function(e){return Math.ceil(e/t)*t}}:Ls}function Qa(t,e,n,r){var a=[],o=[],i=0,l=Math.min(t.length,e.length)-1;for(t[l]<t[0]&&(t=t.slice().reverse(),e=e.slice().reverse());++i<=l;)a.push(n(t[i-1],t[i])),o.push(r(e[i-1],e[i]));return function(e){var n=ui.bisect(t,e,1,l)-1;return o[n](a[n](e))}}function Wa(t,e,n,r){function a(){var a=Math.min(t.length,e.length)>2?Qa:Xa,s=r?Wr:Qr;return i=a(t,e,s,n),l=a(e,t,s,_r),o}function o(t){return i(t)}var i,l;return o.invert=function(t){return l(t)},o.domain=function(e){return arguments.length?(t=e.map(Number),a()):t},o.range=function(t){return arguments.length?(e=t,a()):e},o.rangeRound=function(t){return o.range(t).interpolate(qr)},o.clamp=function(t){return arguments.length?(r=t,a()):r},o.interpolate=function(t){return arguments.length?(n=t,a()):n},o.ticks=function(e){return eo(t,e)},o.tickFormat=function(e,n){return no(t,e,n)},o.nice=function(e){return Ka(t,e),a()},o.copy=function(){return Wa(t,e,n,r)},a()}function Ja(t,e){return ui.rebind(t,e,\"range\",\"rangeRound\",\"interpolate\",\"clamp\")}function Ka(t,e){return Ga(t,$a(to(t,e)[2])),Ga(t,$a(to(t,e)[2])),t}function to(t,e){null==e&&(e=10);var n=Ya(t),r=n[1]-n[0],a=Math.pow(10,Math.floor(Math.log(r/e)/Math.LN10)),o=e/r*a;return.15>=o?a*=10:.35>=o?a*=5:.75>=o&&(a*=2),n[0]=Math.ceil(n[0]/a)*a,n[1]=Math.floor(n[1]/a)*a+.5*a,n[2]=a,n}function eo(t,e){return ui.range.apply(ui,to(t,e))}function no(t,e,n){var r=to(t,e);if(n){var a=pl.exec(n);if(a.shift(),\"s\"===a[8]){var o=ui.formatPrefix(Math.max(wi(r[0]),wi(r[1])));return a[7]||(a[7]=\".\"+ro(o.scale(r[2]))),a[8]=\"f\",n=ui.format(a.join(\"\")),function(t){return n(o.scale(t))+o.symbol}}a[7]||(a[7]=\".\"+ao(a[8],r)),n=a.join(\"\")}else n=\",.\"+ro(r[2])+\"f\";return ui.format(n)}function ro(t){return-Math.floor(Math.log(t)/Math.LN10+.01)}function ao(t,e){var n=ro(e[2]);return t in Ts?Math.abs(n-ro(Math.max(wi(e[0]),wi(e[1]))))+ +(\"e\"!==t):n-2*(\"%\"===t)}function oo(t,e,n,r){function a(t){return(n?Math.log(0>t?0:t):-Math.log(t>0?0:-t))/Math.log(e)}function o(t){return n?Math.pow(e,t):-Math.pow(e,-t)}function i(e){return t(a(e))}return i.invert=function(e){return o(t.invert(e))},i.domain=function(e){return arguments.length?(n=e[0]>=0,t.domain((r=e.map(Number)).map(a)),i):r},i.base=function(n){return arguments.length?(e=+n,t.domain(r.map(a)),i):e},i.nice=function(){var e=Ga(r.map(a),n?Math:Ss);return t.domain(e),r=e.map(o),i},i.ticks=function(){var t=Ya(r),i=[],l=t[0],s=t[1],c=Math.floor(a(l)),u=Math.ceil(a(s)),f=e%1?2:e;if(isFinite(u-c)){if(n){for(;u>c;c++)for(var d=1;f>d;d++)i.push(o(c)*d);i.push(o(c))}else for(i.push(o(c));c++<u;)for(var d=f-1;d>0;d--)i.push(o(c)*d);for(c=0;i[c]<l;c++);for(u=i.length;i[u-1]>s;u--);i=i.slice(c,u)}return i},i.tickFormat=function(t,n){if(!arguments.length)return zs;arguments.length<2?n=zs:\"function\"!=typeof n&&(n=ui.format(n));var r=Math.max(1,e*t/i.ticks().length);return function(t){var i=t/o(Math.round(a(t)));return e-.5>i*e&&(i*=e),r>=i?n(t):\"\"}},i.copy=function(){return oo(t.copy(),e,n,r)},Ja(i,t)}function io(t,e,n){function r(e){return t(a(e))}var a=lo(e),o=lo(1/e);return r.invert=function(e){return o(t.invert(e))},r.domain=function(e){return arguments.length?(t.domain((n=e.map(Number)).map(a)),r):n},r.ticks=function(t){return eo(n,t)},r.tickFormat=function(t,e){return no(n,t,e)},r.nice=function(t){return r.domain(Ka(n,t))},r.exponent=function(i){return arguments.length?(a=lo(e=i),o=lo(1/e),t.domain(n.map(a)),r):e},r.copy=function(){return io(t.copy(),e,n)},Ja(r,t)}function lo(t){return function(e){return 0>e?-Math.pow(-e,t):Math.pow(e,t)}}function so(t,e){function n(n){return o[((a.get(n)||(\"range\"===e.t?a.set(n,t.push(n)):NaN))-1)%o.length]}function r(e,n){return ui.range(t.length).map(function(t){return e+n*t})}var a,o,i;return n.domain=function(r){if(!arguments.length)return t;t=[],a=new f;for(var o,i=-1,l=r.length;++i<l;)a.has(o=r[i])||a.set(o,t.push(o));return n[e.t].apply(n,e.a)},n.range=function(t){return arguments.length?(o=t,i=0,e={t:\"range\",a:arguments},n):o},n.rangePoints=function(a,l){arguments.length<2&&(l=0);var s=a[0],c=a[1],u=t.length<2?(s=(s+c)/2,0):(c-s)/(t.length-1+l);return o=r(s+u*l/2,u),i=0,e={t:\"rangePoints\",a:arguments},n},n.rangeRoundPoints=function(a,l){arguments.length<2&&(l=0);var s=a[0],c=a[1],u=t.length<2?(s=c=Math.round((s+c)/2),0):(c-s)/" -, -"(t.length-1+l)|0;return o=r(s+Math.round(u*l/2+(c-s-(t.length-1+l)*u)/2),u),i=0,e={t:\"rangeRoundPoints\",a:arguments},n},n.rangeBands=function(a,l,s){arguments.length<2&&(l=0),arguments.length<3&&(s=l);var c=a[1]<a[0],u=a[c-0],f=a[1-c],d=(f-u)/(t.length-l+2*s);return o=r(u+d*s,d),c&&o.reverse(),i=d*(1-l),e={t:\"rangeBands\",a:arguments},n},n.rangeRoundBands=function(a,l,s){arguments.length<2&&(l=0),arguments.length<3&&(s=l);var c=a[1]<a[0],u=a[c-0],f=a[1-c],d=Math.floor((f-u)/(t.length-l+2*s));return o=r(u+Math.round((f-u-(t.length-l)*d)/2),d),c&&o.reverse(),i=Math.round(d*(1-l)),e={t:\"rangeRoundBands\",a:arguments},n},n.rangeBand=function(){return i},n.rangeExtent=function(){return Ya(e.a[0])},n.copy=function(){return so(t,e)},n.domain(t)}function co(t,e){function n(){var n=0,a=e.length;for(l=[];++n<a;)l[n-1]=ui.quantile(t,n/a);return r}function r(t){return isNaN(t=+t)?void 0:e[ui.bisect(l,t)]}var l;return r.domain=function(e){return arguments.length?(t=e.map(o).filter(i).sort(a),n()):t},r.range=function(t){return arguments.length?(e=t,n()):e},r.quantiles=function(){return l},r.invertExtent=function(n){return n=e.indexOf(n),0>n?[NaN,NaN]:[n>0?l[n-1]:t[0],n<l.length?l[n]:t[t.length-1]]},r.copy=function(){return co(t,e)},n()}function uo(t,e,n){function r(e){return n[Math.max(0,Math.min(i,Math.floor(o*(e-t))))]}function a(){return o=n.length/(e-t),i=n.length-1,r}var o,i;return r.domain=function(n){return arguments.length?(t=+n[0],e=+n[n.length-1],a()):[t,e]},r.range=function(t){return arguments.length?(n=t,a()):n},r.invertExtent=function(e){return e=n.indexOf(e),e=0>e?NaN:e/o+t,[e,e+1/o]},r.copy=function(){return uo(t,e,n)},a()}function fo(t,e){function n(n){return n>=n?e[ui.bisect(t,n)]:void 0}return n.domain=function(e){return arguments.length?(t=e,n):t},n.range=function(t){return arguments.length?(e=t,n):e},n.invertExtent=function(n){return n=e.indexOf(n),[t[n-1],t[n]]},n.copy=function(){return fo(t,e)},n}function ho(t){function e(t){return+t}return e.invert=e,e.domain=e.range=function(n){return arguments.length?(t=n.map(e),e):t},e.ticks=function(e){return eo(t,e)},e.tickFormat=function(e,n){return no(t,e,n)},e.copy=function(){return ho(t)},e}function po(){return 0}function go(t){return t.innerRadius}function vo(t){return t.outerRadius}function mo(t){return t.startAngle}function yo(t){return t.endAngle}function xo(t){return t&&t.padAngle}function bo(t,e,n,r){return(t-n)*e-(e-r)*t>0?0:1}function _o(t,e,n,r,a){var o=t[0]-e[0],i=t[1]-e[1],l=(a?r:-r)/Math.sqrt(o*o+i*i),s=l*i,c=-l*o,u=t[0]+s,f=t[1]+c,d=e[0]+s,h=e[1]+c,p=(u+d)/2,g=(f+h)/2,v=d-u,m=h-f,y=v*v+m*m,x=n-r,b=u*h-d*f,_=(0>m?-1:1)*Math.sqrt(Math.max(0,x*x*y-b*b)),w=(b*m-v*_)/y,k=(-b*v-m*_)/y,M=(b*m+v*_)/y,A=(-b*v+m*_)/y,L=w-p,T=k-g,z=M-p,S=A-g;return L*L+T*T>z*z+S*S&&(w=M,k=A),[[w-s,k-c],[w*n/x,k*n/x]]}function wo(t){function e(e){function i(){c.push(\"M\",o(t(u),l))}for(var s,c=[],u=[],f=-1,d=e.length,h=zt(n),p=zt(r);++f<d;)a.call(this,s=e[f],f)?u.push([+h.call(this,s,f),+p.call(this,s,f)]):u.length&&(i(),u=[]);return u.length&&i(),c.length?c.join(\"\"):null}var n=Cn,r=On,a=Ce,o=ko,i=o.key,l=.7;return e.x=function(t){return arguments.length?(n=t,e):n},e.y=function(t){return arguments.length?(r=t,e):r},e.defined=function(t){return arguments.length?(a=t,e):a},e.interpolate=function(t){return arguments.length?(i=\"function\"==typeof t?o=t:(o=Ds.get(t)||ko).key,e):i},e.tension=function(t){return arguments.length?(l=t,e):l},e}function ko(t){return t.length>1?t.join(\"L\"):t+\"Z\"}function Mo(t){return t.join(\"L\")+\"Z\"}function Ao(t){for(var e=0,n=t.length,r=t[0],a=[r[0],\",\",r[1]];++e<n;)a.push(\"H\",(r[0]+(r=t[e])[0])/2,\"V\",r[1]);return n>1&&a.push(\"H\",r[0]),a.join(\"\")}function Lo(t){for(var e=0,n=t.length,r=t[0],a=[r[0],\",\",r[1]];++e<n;)a.push(\"V\",(r=t[e])[1],\"H\",r[0]);return a.join(\"\")}function To(t){for(var e=0,n=t.length,r=t[0],a=[r[0],\",\",r[1]];++e<n;)a.push(\"H\",(r=t[e])[0],\"V\",r[1]);return a.join(\"\")}function zo(t,e){return t.length<4?ko(t):t[1]+Co(t.slice(1,-1),Oo(t,e))}function So(t,e){return t.length<3?Mo(t):t[0]+Co((t.push(t[0]),t),Oo([t[t.length-2]].concat(t,[t[1]]),e))}function Eo(t,e){return t.length<3?ko(t):t[0]+Co(t,Oo(t,e))}function Co(t,e){if(e.length<1||t.length!=e.length&&t.length!=e.length+2)return ko(t);var n=t.length!=e.length,r=\"\",a=t[0],o=t[1],i=e[0],l=i,s=1;if(n&&(r+=\"Q\"+(o[0]-2*i[0]/3)+\",\"+(o[1]-2*i[1]/3)+\",\"+o[0]+\",\"+o[1],a=t[1],s=2),e.length>1){l=e[1],o=t[s],s++,r+=\"C\"+(a[0]+i[0])+\",\"+(a[1]+i[1])+\",\"+(o[0]-l[0])+\",\"+(o[1]-l[1])+\",\"+o[0]+\",\"+o[1];for(var c=2;c<e.length;c++,s++)o=t[s],l=e[c],r+=\"S\"+(o[0]-l[0])+\",\"+(o[1]-l[1])+\",\"+o[0]+\",\"+o[1]}if(n){var u=t[s];r+=\"Q\"+(o[0]+2*l[0]/3)+\",\"+(o[1]+2*l[1]/3)+\",\"+u[0]+\",\"+u[1]}return r}function Oo(t,e){for(var n,r=[],a=(1-e)/2,o=t[0],i=t[1],l=1,s=t.length;++l<s;)n=o,o=i,i=t[l],r.push([a*(i[0]-n[0]),a*(i[1]-n[1])]);return r}function Po(t){if(t.length<3)return ko(t);var e=1,n=t.length,r=t[0],a=r[0],o=r[1],i=[a,a,a,(r=t[1])[0]],l=[o,o,o,r[1]],s=[a,\",\",o,\"L\",Ro(js,i),\",\",Ro(js,l)];for(t.push(t[n-1]);++e<=n;)r=t[e],i.shift(),i.push(r[0]),l.shift(),l.push(r[1]),jo(s,i,l);return t.pop(),s.push(\"L\",r),s.join(\"\")}function No(t){if(t.length<4)return ko(t);for(var e,n=[],r=-1,a=t.length,o=[0],i=[0];++r<3;)e=t[r],o.push(e[0]),i.push(e[1]);for(n.push(Ro(js,o)+\",\"+Ro(js,i)),--r;++r<a;)e=t[r],o.shift(),o.push(e[0]),i.shift(),i.push(e[1]),jo(n,o,i);return n.join(\"\")}function Do(t){for(var e,n,r=-1,a=t.length,o=a+4,i=[],l=[];++r<4;)n=t[r%a],i.push(n[0]),l.push(n[1]);for(e=[Ro(js,i),\",\",Ro(js,l)],--r;++r<o;)n=t[r%a],i.shift(),i.push(n[0]),l.shift(),l.push(n[1]),jo(e,i,l);return e.join(\"\")}function Io(t,e){var n=t.length-1;if(n)for(var r,a,o=t[0][0],i=t[0][1],l=t[n][0]-o,s=t[n][1]-i,c=-1;++c<=n;)r=t[c],a=c/n,r[0]=e*r[0]+(1-e)*(o+a*l),r[1]=e*r[1]+(1-e)*(i+a*s);return Po(t)}function Ro(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]+t[3]*e[3]}function jo(t,e,n){t.push(\"C\",Ro(Is,e),\",\",Ro(Is,n),\",\",Ro(Rs,e),\",\",Ro(Rs,n),\",\",Ro(js,e),\",\",Ro(js,n))}function qo(t,e){return(e[1]-t[1])/(e[0]-t[0])}function Fo(t){for(var e=0,n=t.length-1,r=[],a=t[0],o=t[1],i=r[0]=qo(a,o);++e<n;)r[e]=(i+(i=qo(a=o,o=t[e+1])))/2;return r[e]=i,r}function Bo(t){for(var e,n,r,a,o=[],i=Fo(t),l=-1,s=t.length-1;++l<s;)e=qo(t[l],t[l+1]),wi(e)<qi?i[l]=i[l+1]=0:(n=i[l]/e,r=i[l+1]/e,a=n*n+r*r,a>9&&(a=3*e/Math.sqrt(a),i[l]=a*n,i[l+1]=a*r));for(l=-1;++l<=s;)a=(t[Math.min(s,l+1)][0]-t[Math.max(0,l-1)][0])/(6*(1+i[l]*i[l])),o.push([a||0,i[l]*a||0]);return o}function Ho(t){return t.length<3?ko(t):t[0]+Co(t,Bo(t))}function Vo(t){for(var e,n,r,a=-1,o=t.length;++a<o;)e=t[a],n=e[0],r=e[1]-Zi,e[0]=n*Math.cos(r),e[1]=n*Math.sin(r);return t}function Zo(t){function e(e){function s(){g.push(\"M\",l(t(m),f),u,c(t(v.reverse()),f),\"Z\")}for(var d,h,p,g=[],v=[],m=[],y=-1,x=e.length,b=zt(n),_=zt(a),w=n===r?function(){return h}:zt(r),k=a===o?function(){return p}:zt(o);++y<x;)i.call(this,d=e[y],y)?(v.push([h=+b.call(this,d,y),p=+_.call(this,d,y)]),m.push([+w.call(this,d,y),+k.call(this,d,y)])):v.length&&(s(),v=[],m=[]);return v.length&&s(),g.length?g.join(\"\"):null}var n=Cn,r=Cn,a=0,o=On,i=Ce,l=ko,s=l.key,c=l,u=\"L\",f=.7;return e.x=function(t){return arguments.length?(n=r=t,e):r},e.x0=function(t){return arguments.length?(n=t,e):n},e.x1=function(t){return arguments.length?(r=t,e):r},e.y=function(t){return arguments.length?(a=o=t,e):o},e.y0=function(t){return arguments.length?(a=t,e):a},e.y1=function(t){return arguments.length?(o=t,e):o},e.defined=function(t){return arguments.length?(i=t,e):i},e.interpolate=function(t){return arguments.length?(s=\"function\"==typeof t?l=t:(l=Ds.get(t)||ko).key,c=l.reverse||l,u=l.closed?\"M\":\"L\",e):s},e.tension=function(t){return arguments.length?(f=t,e):f},e}function Yo(t){return t.radius}function Uo(t){return[t.x,t.y]}function Xo(t){return function(){var e=t.apply(this,arguments),n=e[0],r=e[1]-Zi;return[n*Math.cos(r),n*Math.sin(r)]}}function Go(){return 64}function $o(){return\"circle\"}function Qo(t){var e=Math.sqrt(t/Bi);return\"M0,\"+e+\"A\"+e+\",\"+e+\" 0 1,1 0,\"+-e+\"A\"+e+\",\"+e+\" 0 1,1 0,\"+e+\"Z\"}function Wo(t){return function(){var e,n,r;(e=this[t])&&(r=e[n=e.active])&&(r.timer.c=null,r.timer.t=NaN,--e.count?delete e[n]:delete this[t],e.active+=.5,r.event&&r.event.interrupt.call(this,this.__data__,r.index))}}function Jo(t,e,n){return Ti(t,Ys),t.namespace=e,t.id=n,t}function Ko(t,e,n,r){var a=t.id,o=t.namespace;return Y(t,\"function\"==typeof n?function(t,i,l){t[o][a].tween.set(e,r(n.call(t,t.__data__,i,l)))}:(n=r(n),function(t){t[o][a].tween.set(e,n)}))}function ti(t){return null==t&&(t=\"\"),function(){this.textContent=t}}function ei(t){return null==t?\"__transition__\":\"__transition_\"+t+\"__\"}function ni(t,e,n,r,a){function o(t){var e=g.delay;return c.t=e+s,t>=e?i(t-e):void(c.c=i)}function i(n){var a=p.active,o=p[a];o&&(o.timer.c=null,o.timer.t=NaN,--p.count,delete p[a],o.event&&o.event.interrupt.call(t,t.__data__,o.index));for(var i in p)if(r>+i){var f=p[i];f.timer.c=null,f.timer.t=NaN,--p.count,delete p[i]}c.c=l,Pt(function(){return c.c&&l(n||1)&&(c.c=null,c.t=NaN),1},0,s),p.active=r,g.event&&g.event.start.call(t,t.__data__,e),h=[],g.tween.forEach(function(n,r){(r=r.call(t,t.__data__,e))&&h.push(r)}),d=g.ease,u=g.duration}function l(a){for(var o=a/u,i=d(o),l=h.length;l>0;)h[--l].call(t,i);return o>=1?(g.event&&g.event.end.call(t,t.__data__,e),--p.count?delete p[r]:delete t[n],1):void 0}var s,c,u,d,h,p=t[n]||(t[n]={active:0,count:0}),g=p[r];g||(s=a.time,c=Pt(o,0,s),g=p[r]={tween:new f,time:s,timer:c,delay:a.delay,duration:a.duration,ease:a.ease,index:e},a=null,++p.count)}function ri(t,e,n){t.attr(\"transform\",function(t){var r=e(t);return\"translate(\"+(isFinite(r)?r:n(t))+\",0)\"})}function ai(t,e,n){t.attr(\"transform\",function(t){var r=e(t);return\"translate(0,\"+(isFinite(r)?r:n(t))+\")\"})}function oi(t){return t.toISOString()}function ii(t,e,n){function r(e){return t(e)}function a(t,n){var r=t[1]-t[0],a=r/n,o=ui.bisect(tc,a);return o==tc.length?[e.year,to(t.map(function(t){return t/31536e6}),n)[2]]:o?e[a/tc[o-1]<tc[o]/a?o-1:o]:[rc,to(t,n)[2]]}return r.invert=function(e){return li" -, -"(t.invert(e))},r.domain=function(e){return arguments.length?(t.domain(e),r):t.domain().map(li)},r.nice=function(t,e){function n(n){return!isNaN(n)&&!t.range(n,li(+n+1),e).length}var o=r.domain(),i=Ya(o),l=null==t?a(i,10):\"number\"==typeof t&&a(i,t);return l&&(t=l[0],e=l[1]),r.domain(Ga(o,e>1?{floor:function(e){for(;n(e=t.floor(e));)e=li(e-1);return e},ceil:function(e){for(;n(e=t.ceil(e));)e=li(+e+1);return e}}:t))},r.ticks=function(t,e){var n=Ya(r.domain()),o=null==t?a(n,10):\"number\"==typeof t?a(n,t):!t.range&&[{range:t},e];return o&&(t=o[0],e=o[1]),t.range(n[0],li(+n[1]+1),1>e?1:e)},r.tickFormat=function(){return n},r.copy=function(){return ii(t.copy(),e,n)},Ja(r,t)}function li(t){return new Date(t)}function si(t){return JSON.parse(t.responseText)}function ci(t){var e=hi.createRange();return e.selectNode(hi.body),e.createContextualFragment(t.responseText)}var ui={version:\"3.5.16\"},fi=[].slice,di=function(t){return fi.call(t)},hi=this.document;if(hi)try{di(hi.documentElement.childNodes)[0].nodeType}catch(pi){di=function(t){for(var e=t.length,n=new Array(e);e--;)n[e]=t[e];return n}}if(Date.now||(Date.now=function(){return+new Date}),hi)try{hi.createElement(\"DIV\").style.setProperty(\"opacity\",0,\"\")}catch(gi){var vi=this.Element.prototype,mi=vi.setAttribute,yi=vi.setAttributeNS,xi=this.CSSStyleDeclaration.prototype,bi=xi.setProperty;vi.setAttribute=function(t,e){mi.call(this,t,e+\"\")},vi.setAttributeNS=function(t,e,n){yi.call(this,t,e,n+\"\")},xi.setProperty=function(t,e,n){bi.call(this,t,e+\"\",n)}}ui.ascending=a,ui.descending=function(t,e){return t>e?-1:e>t?1:e>=t?0:NaN},ui.min=function(t,e){var n,r,a=-1,o=t.length;if(1===arguments.length){for(;++a<o;)if(null!=(r=t[a])&&r>=r){n=r;break}for(;++a<o;)null!=(r=t[a])&&n>r&&(n=r)}else{for(;++a<o;)if(null!=(r=e.call(t,t[a],a))&&r>=r){n=r;break}for(;++a<o;)null!=(r=e.call(t,t[a],a))&&n>r&&(n=r)}return n},ui.max=function(t,e){var n,r,a=-1,o=t.length;if(1===arguments.length){for(;++a<o;)if(null!=(r=t[a])&&r>=r){n=r;break}for(;++a<o;)null!=(r=t[a])&&r>n&&(n=r)}else{for(;++a<o;)if(null!=(r=e.call(t,t[a],a))&&r>=r){n=r;break}for(;++a<o;)null!=(r=e.call(t,t[a],a))&&r>n&&(n=r)}return n},ui.extent=function(t,e){var n,r,a,o=-1,i=t.length;if(1===arguments.length){for(;++o<i;)if(null!=(r=t[o])&&r>=r){n=a=r;break}for(;++o<i;)null!=(r=t[o])&&(n>r&&(n=r),r>a&&(a=r))}else{for(;++o<i;)if(null!=(r=e.call(t,t[o],o))&&r>=r){n=a=r;break}for(;++o<i;)null!=(r=e.call(t,t[o],o))&&(n>r&&(n=r),r>a&&(a=r))}return[n,a]},ui.sum=function(t,e){var n,r=0,a=t.length,o=-1;if(1===arguments.length)for(;++o<a;)i(n=+t[o])&&(r+=n);else for(;++o<a;)i(n=+e.call(t,t[o],o))&&(r+=n);return r},ui.mean=function(t,e){var n,r=0,a=t.length,l=-1,s=a;if(1===arguments.length)for(;++l<a;)i(n=o(t[l]))?r+=n:--s;else for(;++l<a;)i(n=o(e.call(t,t[l],l)))?r+=n:--s;return s?r/s:void 0},ui.quantile=function(t,e){var n=(t.length-1)*e+1,r=Math.floor(n),a=+t[r-1],o=n-r;return o?a+o*(t[r]-a):a},ui.median=function(t,e){var n,r=[],l=t.length,s=-1;if(1===arguments.length)for(;++s<l;)i(n=o(t[s]))&&r.push(n);else for(;++s<l;)i(n=o(e.call(t,t[s],s)))&&r.push(n);return r.length?ui.quantile(r.sort(a),.5):void 0},ui.variance=function(t,e){var n,r,a=t.length,l=0,s=0,c=-1,u=0;if(1===arguments.length)for(;++c<a;)i(n=o(t[c]))&&(r=n-l,l+=r/++u,s+=r*(n-l));else for(;++c<a;)i(n=o(e.call(t,t[c],c)))&&(r=n-l,l+=r/++u,s+=r*(n-l));return u>1?s/(u-1):void 0},ui.deviation=function(){var t=ui.variance.apply(this,arguments);return t?Math.sqrt(t):t};var _i=l(a);ui.bisectLeft=_i.left,ui.bisect=ui.bisectRight=_i.right,ui.bisector=function(t){return l(1===t.length?function(e,n){return a(t(e),n)}:t)},ui.shuffle=function(t,e,n){(o=arguments.length)<3&&(n=t.length,2>o&&(e=0));for(var r,a,o=n-e;o;)a=Math.random()*o--|0,r=t[o+e],t[o+e]=t[a+e],t[a+e]=r;return t},ui.permute=function(t,e){for(var n=e.length,r=new Array(n);n--;)r[n]=t[e[n]];return r},ui.pairs=function(t){for(var e,n=0,r=t.length-1,a=t[0],o=new Array(0>r?0:r);r>n;)o[n]=[e=a,a=t[++n]];return o},ui.transpose=function(t){if(!(a=t.length))return[];for(var e=-1,n=ui.min(t,s),r=new Array(n);++e<n;)for(var a,o=-1,i=r[e]=new Array(a);++o<a;)i[o]=t[o][e];return r},ui.zip=function(){return ui.transpose(arguments)},ui.keys=function(t){var e=[];for(var n in t)e.push(n);return e},ui.values=function(t){var e=[];for(var n in t)e.push(t[n]);return e},ui.entries=function(t){var e=[];for(var n in t)e.push({key:n,value:t[n]});return e},ui.merge=function(t){for(var e,n,r,a=t.length,o=-1,i=0;++o<a;)i+=t[o].length;for(n=new Array(i);--a>=0;)for(r=t[a],e=r.length;--e>=0;)n[--i]=r[e];return n};var wi=Math.abs;ui.range=function(t,e,n){if(arguments.length<3&&(n=1,arguments.length<2&&(e=t,t=0)),(e-t)/n===1/0)throw new Error(\"infinite range\");var r,a=[],o=c(wi(n)),i=-1;if(t*=o,e*=o,n*=o,0>n)for(;(r=t+n*++i)>e;)a.push(r/o);else for(;(r=t+n*++i)<e;)a.push(r/o);return a},ui.map=function(t,e){var n=new f;if(t instanceof f)t.forEach(function(t,e){n.set(t,e)});else if(Array.isArray(t)){var r,a=-1,o=t.length;if(1===arguments.length)for(;++a<o;)n.set(a,t[a]);else for(;++a<o;)n.set(e.call(t,r=t[a],a),r)}else for(var i in t)n.set(i,t[i]);return n};var ki=\"__proto__\",Mi=\"\\x00\";u(f,{has:p,get:function(t){return this._[d(t)]},set:function(t,e){return this._[d(t)]=e},remove:g,keys:v,values:function(){var t=[];for(var e in this._)t.push(this._[e]);return t},entries:function(){var t=[];for(var e in this._)t.push({key:h(e),value:this._[e]});return t},size:m,empty:y,forEach:function(t){for(var e in this._)t.call(this,h(e),this._[e])}}),ui.nest=function(){function t(e,i,l){if(l>=o.length)return r?r.call(a,i):n?i.sort(n):i;for(var s,c,u,d,h=-1,p=i.length,g=o[l++],v=new f;++h<p;)(d=v.get(s=g(c=i[h])))?d.push(c):v.set(s,[c]);return e?(c=e(),u=function(n,r){c.set(n,t(e,r,l))}):(c={},u=function(n,r){c[n]=t(e,r,l)}),v.forEach(u),c}function e(t,n){if(n>=o.length)return t;var r=[],a=i[n++];return t.forEach(function(t,a){r.push({key:t,values:e(a,n)})}),a?r.sort(function(t,e){return a(t.key,e.key)}):r}var n,r,a={},o=[],i=[];return a.map=function(e,n){return t(n,e,0)},a.entries=function(n){return e(t(ui.map,n,0),0)},a.key=function(t){return o.push(t),a},a.sortKeys=function(t){return i[o.length-1]=t,a},a.sortValues=function(t){return n=t,a},a.rollup=function(t){return r=t,a},a},ui.set=function(t){var e=new x;if(t)for(var n=0,r=t.length;r>n;++n)e.add(t[n]);return e},u(x,{has:p,add:function(t){return this._[d(t+=\"\")]=!0,t},remove:g,values:v,size:m,empty:y,forEach:function(t){for(var e in this._)t.call(this,h(e))}}),ui.behavior={},ui.rebind=function(t,e){for(var n,r=1,a=arguments.length;++r<a;)t[n=arguments[r]]=_(t,e,e[n]);return t};var Ai=[\"webkit\",\"ms\",\"moz\",\"Moz\",\"o\",\"O\"];ui.dispatch=function(){for(var t=new M,e=-1,n=arguments.length;++e<n;)t[arguments[e]]=A(t);return t},M.prototype.on=function(t,e){var n=t.indexOf(\".\"),r=\"\";if(n>=0&&(r=t.slice(n+1),t=t.slice(0,n)),t)return arguments.length<2?this[t].on(r):this[t].on(r,e);if(2===arguments.length){if(null==e)for(t in this)this.hasOwnProperty(t)&&this[t].on(r,null);return this}},ui.event=null,ui.requote=function(t){return t.replace(Li,\"\\\\$&\")};var Li=/[\\\\\\^\\$\\*\\+\\?\\|\\[\\]\\(\\)\\.\\{\\}]/g,Ti={}.__proto__?function(t,e){t.__proto__=e}:function(t,e){for(var n in e)t[n]=e[n]},zi=function(t,e){return e.querySelector(t)},Si=function(t,e){return e.querySelectorAll(t)},Ei=function(t,e){var n=t.matches||t[w(t,\"matchesSelector\")];return(Ei=function(t,e){return n.call(t,e)})(t,e)};\"function\"==typeof Sizzle&&(zi=function(t,e){return Sizzle(t,e)[0]||null},Si=Sizzle,Ei=Sizzle.matchesSelector),ui.selection=function(){return ui.select(hi.documentElement)};var Ci=ui.selection.prototype=[];Ci.select=function(t){var e,n,r,a,o=[];t=E(t);for(var i=-1,l=this.length;++i<l;){o.push(e=[]),e.parentNode=(r=this[i]).parentNode;for(var s=-1,c=r.length;++s<c;)(a=r[s])?(e.push(n=t.call(a,a.__data__,s,i)),n&&\"__data__\"in a&&(n.__data__=a.__data__)):e.push(null)}return S(o)},Ci.selectAll=function(t){var e,n,r=[];t=C(t);for(var a=-1,o=this.length;++a<o;)for(var i=this[a],l=-1,s=i.length;++l<s;)(n=i[l])&&(r.push(e=di(t.call(n,n.__data__,l,a))),e.parentNode=n);return S(r)};var Oi=\"http://www.w3.org/1999/xhtml\",Pi={svg:\"http://www.w3.org/2000/svg\",xhtml:Oi,xlink:\"http://www.w3.org/1999/xlink\",xml:\"http://www.w3.org/XML/1998/namespace\",xmlns:\"http://www.w3.org/2000/xmlns/\"};ui.ns={prefix:Pi,qualify:function(t){var e=t.indexOf(\":\"),n=t;return e>=0&&\"xmlns\"!==(n=t.slice(0,e))&&(t=t.slice(e+1)),Pi.hasOwnProperty(n)?{space:Pi[n],local:t}:t}},Ci.attr=function(t,e){if(arguments.length<2){if(\"string\"==typeof t){var n=this.node();return t=ui.ns.qualify(t),t.local?n.getAttributeNS(t.space,t.local):n.getAttribute(t)}for(e in t)this.each(O(e,t[e]));return this}return this.each(O(t,e))},Ci.classed=function(t,e){if(arguments.length<2){if(\"string\"==typeof t){var n=this.node(),r=(t=D(t)).length,a=-1;if(e=n.classList){for(;++a<r;)if(!e.contains(t[a]))return!1}else for(e=n.getAttribute(\"class\");++a<r;)if(!N(t[a]).test(e))return!1;return!0}for(e in t)this.each(I(e,t[e]));return this}return this.each(I(t,e))},Ci.style=function(t,e,n){var a=arguments.length;if(3>a){if(\"string\"!=typeof t){2>a&&(e=\"\");for(n in t)this.each(j(n,t[n],e));return this}if(2>a){var o=this.node();return r(o).getComputedStyle(o,null).getPropertyValue(t)}n=\"\"}return this.each(j(t,e,n))},Ci.property=function(t,e){if(arguments.length<2){if(\"string\"==typeof t)return this.node()[t];for(e in t)this.each(q(e,t[e]));return this}return this.each(q(t,e))},Ci.text=function(t){return arguments.length?this.each(\"function\"==typeof t?function(){var e=t.apply(this,arguments);this.textContent=null==e?\"\":e}:null==t?function(){this.textContent=\"\"}:function(){this.textContent=t}):this.node().textContent},Ci.html=function(t){return arguments.length?this.each(\"function\"==typeof t?function(){var e=t.apply(this,arguments);this.innerHTML=null==e?\"\":e}:null==t?function(){this.innerHTML=\"\"}:function(){this.innerHTML=t}):this.node().innerHTML},Ci.append=function(t){return t=F(t),this.select(function(){return this.appendChild(t.apply(t" -, -"his,arguments))})},Ci.insert=function(t,e){return t=F(t),e=E(e),this.select(function(){return this.insertBefore(t.apply(this,arguments),e.apply(this,arguments)||null)})},Ci.remove=function(){return this.each(B)},Ci.data=function(t,e){function n(t,n){var r,a,o,i=t.length,u=n.length,d=Math.min(i,u),h=new Array(u),p=new Array(u),g=new Array(i);if(e){var v,m=new f,y=new Array(i);for(r=-1;++r<i;)(a=t[r])&&(m.has(v=e.call(a,a.__data__,r))?g[r]=a:m.set(v,a),y[r]=v);for(r=-1;++r<u;)(a=m.get(v=e.call(n,o=n[r],r)))?a!==!0&&(h[r]=a,a.__data__=o):p[r]=H(o),m.set(v,!0);for(r=-1;++r<i;)r in y&&m.get(y[r])!==!0&&(g[r]=t[r])}else{for(r=-1;++r<d;)a=t[r],o=n[r],a?(a.__data__=o,h[r]=a):p[r]=H(o);for(;u>r;++r)p[r]=H(n[r]);for(;i>r;++r)g[r]=t[r]}p.update=h,p.parentNode=h.parentNode=g.parentNode=t.parentNode,l.push(p),s.push(h),c.push(g)}var r,a,o=-1,i=this.length;if(!arguments.length){for(t=new Array(i=(r=this[0]).length);++o<i;)(a=r[o])&&(t[o]=a.__data__);return t}var l=U([]),s=S([]),c=S([]);if(\"function\"==typeof t)for(;++o<i;)n(r=this[o],t.call(r,r.parentNode.__data__,o));else for(;++o<i;)n(r=this[o],t);return s.enter=function(){return l},s.exit=function(){return c},s},Ci.datum=function(t){return arguments.length?this.property(\"__data__\",t):this.property(\"__data__\")},Ci.filter=function(t){var e,n,r,a=[];\"function\"!=typeof t&&(t=V(t));for(var o=0,i=this.length;i>o;o++){a.push(e=[]),e.parentNode=(n=this[o]).parentNode;for(var l=0,s=n.length;s>l;l++)(r=n[l])&&t.call(r,r.__data__,l,o)&&e.push(r)}return S(a)},Ci.order=function(){for(var t=-1,e=this.length;++t<e;)for(var n,r=this[t],a=r.length-1,o=r[a];--a>=0;)(n=r[a])&&(o&&o!==n.nextSibling&&o.parentNode.insertBefore(n,o),o=n);return this},Ci.sort=function(t){t=Z.apply(this,arguments);for(var e=-1,n=this.length;++e<n;)this[e].sort(t);return this.order()},Ci.each=function(t){return Y(this,function(e,n,r){t.call(e,e.__data__,n,r)})},Ci.call=function(t){var e=di(arguments);return t.apply(e[0]=this,e),this},Ci.empty=function(){return!this.node();\n" -, -"},Ci.node=function(){for(var t=0,e=this.length;e>t;t++)for(var n=this[t],r=0,a=n.length;a>r;r++){var o=n[r];if(o)return o}return null},Ci.size=function(){var t=0;return Y(this,function(){++t}),t};var Ni=[];ui.selection.enter=U,ui.selection.enter.prototype=Ni,Ni.append=Ci.append,Ni.empty=Ci.empty,Ni.node=Ci.node,Ni.call=Ci.call,Ni.size=Ci.size,Ni.select=function(t){for(var e,n,r,a,o,i=[],l=-1,s=this.length;++l<s;){r=(a=this[l]).update,i.push(e=[]),e.parentNode=a.parentNode;for(var c=-1,u=a.length;++c<u;)(o=a[c])?(e.push(r[c]=n=t.call(a.parentNode,o.__data__,c,l)),n.__data__=o.__data__):e.push(null)}return S(i)},Ni.insert=function(t,e){return arguments.length<2&&(e=X(this)),Ci.insert.call(this,t,e)},ui.select=function(t){var n;return\"string\"==typeof t?(n=[zi(t,hi)],n.parentNode=hi.documentElement):(n=[t],n.parentNode=e(t)),S([n])},ui.selectAll=function(t){var e;return\"string\"==typeof t?(e=di(Si(t,hi)),e.parentNode=hi.documentElement):(e=di(t),e.parentNode=null),S([e])},Ci.on=function(t,e,n){var r=arguments.length;if(3>r){if(\"string\"!=typeof t){2>r&&(e=!1);for(n in t)this.each(G(n,t[n],e));return this}if(2>r)return(r=this.node()[\"__on\"+t])&&r._;n=!1}return this.each(G(t,e,n))};var Di=ui.map({mouseenter:\"mouseover\",mouseleave:\"mouseout\"});hi&&Di.forEach(function(t){\"on\"+t in hi&&Di.remove(t)});var Ii,Ri=0;ui.mouse=function(t){return J(t,T())};var ji=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ui.touch=function(t,e,n){if(arguments.length<3&&(n=e,e=T().changedTouches),e)for(var r,a=0,o=e.length;o>a;++a)if((r=e[a]).identifier===n)return J(t,r)},ui.behavior.drag=function(){function t(){this.on(\"mousedown.drag\",o).on(\"touchstart.drag\",i)}function e(t,e,r,o,i){return function(){function l(){var t,n,r=e(d,g);r&&(t=r[0]-x[0],n=r[1]-x[1],p|=t|n,x=r,h({type:\"drag\",x:r[0]+c[0],y:r[1]+c[1],dx:t,dy:n}))}function s(){e(d,g)&&(m.on(o+v,null).on(i+v,null),y(p),h({type:\"dragend\"}))}var c,u=this,f=ui.event.target.correspondingElement||ui.event.target,d=u.parentNode,h=n.of(u,arguments),p=0,g=t(),v=\".drag\"+(null==g?\"\":\"-\"+g),m=ui.select(r(f)).on(o+v,l).on(i+v,s),y=W(f),x=e(d,g);a?(c=a.apply(u,arguments),c=[c.x-x[0],c.y-x[1]]):c=[0,0],h({type:\"dragstart\"})}}var n=z(t,\"drag\",\"dragstart\",\"dragend\"),a=null,o=e(k,ui.mouse,r,\"mousemove\",\"mouseup\"),i=e(K,ui.touch,b,\"touchmove\",\"touchend\");return t.origin=function(e){return arguments.length?(a=e,t):a},ui.rebind(t,n,\"on\")},ui.touches=function(t,e){return arguments.length<2&&(e=T().touches),e?di(e).map(function(e){var n=J(t,e);return n.identifier=e.identifier,n}):[]};var qi=1e-6,Fi=qi*qi,Bi=Math.PI,Hi=2*Bi,Vi=Hi-qi,Zi=Bi/2,Yi=Bi/180,Ui=180/Bi,Xi=Math.SQRT2,Gi=2,$i=4;ui.interpolateZoom=function(t,e){var n,r,a=t[0],o=t[1],i=t[2],l=e[0],s=e[1],c=e[2],u=l-a,f=s-o,d=u*u+f*f;if(Fi>d)r=Math.log(c/i)/Xi,n=function(t){return[a+t*u,o+t*f,i*Math.exp(Xi*t*r)]};else{var h=Math.sqrt(d),p=(c*c-i*i+$i*d)/(2*i*Gi*h),g=(c*c-i*i-$i*d)/(2*c*Gi*h),v=Math.log(Math.sqrt(p*p+1)-p),m=Math.log(Math.sqrt(g*g+1)-g);r=(m-v)/Xi,n=function(t){var e=t*r,n=ot(v),l=i/(Gi*h)*(n*it(Xi*e+v)-at(v));return[a+l*u,o+l*f,i*n/ot(Xi*e+v)]}}return n.duration=1e3*r,n},ui.behavior.zoom=function(){function t(t){t.on(C,f).on(Wi+\".zoom\",h).on(\"dblclick.zoom\",p).on(N,d)}function e(t){return[(t[0]-M.x)/M.k,(t[1]-M.y)/M.k]}function n(t){return[t[0]*M.k+M.x,t[1]*M.k+M.y]}function a(t){M.k=Math.max(T[0],Math.min(T[1],t))}function o(t,e){e=n(e),M.x+=t[0]-e[0],M.y+=t[1]-e[1]}function i(e,n,r,i){e.__chart__={x:M.x,y:M.y,k:M.k},a(Math.pow(2,i)),o(v=n,r),e=ui.select(e),S>0&&(e=e.transition().duration(S)),e.call(t.event)}function l(){_&&_.domain(b.range().map(function(t){return(t-M.x)/M.k}).map(b.invert)),k&&k.domain(w.range().map(function(t){return(t-M.y)/M.k}).map(w.invert))}function s(t){E++||t({type:\"zoomstart\"})}function c(t){l(),t({type:\"zoom\",scale:M.k,translate:[M.x,M.y]})}function u(t){--E||(t({type:\"zoomend\"}),v=null)}function f(){function t(){l=1,o(ui.mouse(a),d),c(i)}function n(){f.on(O,null).on(P,null),h(l),u(i)}var a=this,i=D.of(a,arguments),l=0,f=ui.select(r(a)).on(O,t).on(P,n),d=e(ui.mouse(a)),h=W(a);Zs.call(a),s(i)}function d(){function t(){var t=ui.touches(p);return h=M.k,t.forEach(function(t){t.identifier in v&&(v[t.identifier]=e(t))}),t}function n(){var e=ui.event.target;ui.select(e).on(b,r).on(_,l),w.push(e);for(var n=ui.event.changedTouches,a=0,o=n.length;o>a;++a)v[n[a].identifier]=null;var s=t(),c=Date.now();if(1===s.length){if(500>c-x){var u=s[0];i(p,u,v[u.identifier],Math.floor(Math.log(M.k)/Math.LN2)+1),L()}x=c}else if(s.length>1){var u=s[0],f=s[1],d=u[0]-f[0],h=u[1]-f[1];m=d*d+h*h}}function r(){var t,e,n,r,i=ui.touches(p);Zs.call(p);for(var l=0,s=i.length;s>l;++l,r=null)if(n=i[l],r=v[n.identifier]){if(e)break;t=n,e=r}if(r){var u=(u=n[0]-t[0])*u+(u=n[1]-t[1])*u,f=m&&Math.sqrt(u/m);t=[(t[0]+n[0])/2,(t[1]+n[1])/2],e=[(e[0]+r[0])/2,(e[1]+r[1])/2],a(f*h)}x=null,o(t,e),c(g)}function l(){if(ui.event.touches.length){for(var e=ui.event.changedTouches,n=0,r=e.length;r>n;++n)delete v[e[n].identifier];for(var a in v)return void t()}ui.selectAll(w).on(y,null),k.on(C,f).on(N,d),A(),u(g)}var h,p=this,g=D.of(p,arguments),v={},m=0,y=\".zoom-\"+ui.event.changedTouches[0].identifier,b=\"touchmove\"+y,_=\"touchend\"+y,w=[],k=ui.select(p),A=W(p);n(),s(g),k.on(C,null).on(N,n)}function h(){var t=D.of(this,arguments);y?clearTimeout(y):(Zs.call(this),g=e(v=m||ui.mouse(this)),s(t)),y=setTimeout(function(){y=null,u(t)},50),L(),a(Math.pow(2,.002*Qi())*M.k),o(v,g),c(t)}function p(){var t=ui.mouse(this),n=Math.log(M.k)/Math.LN2;i(this,t,e(t),ui.event.shiftKey?Math.ceil(n)-1:Math.floor(n)+1)}var g,v,m,y,x,b,_,w,k,M={x:0,y:0,k:1},A=[960,500],T=Ji,S=250,E=0,C=\"mousedown.zoom\",O=\"mousemove.zoom\",P=\"mouseup.zoom\",N=\"touchstart.zoom\",D=z(t,\"zoomstart\",\"zoom\",\"zoomend\");return Wi||(Wi=\"onwheel\"in hi?(Qi=function(){return-ui.event.deltaY*(ui.event.deltaMode?120:1)},\"wheel\"):\"onmousewheel\"in hi?(Qi=function(){return ui.event.wheelDelta},\"mousewheel\"):(Qi=function(){return-ui.event.detail},\"MozMousePixelScroll\")),t.event=function(t){t.each(function(){var t=D.of(this,arguments),e=M;Hs?ui.select(this).transition().each(\"start.zoom\",function(){M=this.__chart__||{x:0,y:0,k:1},s(t)}).tween(\"zoom:zoom\",function(){var n=A[0],r=A[1],a=v?v[0]:n/2,o=v?v[1]:r/2,i=ui.interpolateZoom([(a-M.x)/M.k,(o-M.y)/M.k,n/M.k],[(a-e.x)/e.k,(o-e.y)/e.k,n/e.k]);return function(e){var r=i(e),l=n/r[2];this.__chart__=M={x:a-r[0]*l,y:o-r[1]*l,k:l},c(t)}}).each(\"interrupt.zoom\",function(){u(t)}).each(\"end.zoom\",function(){u(t)}):(this.__chart__=M,s(t),c(t),u(t))})},t.translate=function(e){return arguments.length?(M={x:+e[0],y:+e[1],k:M.k},l(),t):[M.x,M.y]},t.scale=function(e){return arguments.length?(M={x:M.x,y:M.y,k:null},a(+e),l(),t):M.k},t.scaleExtent=function(e){return arguments.length?(T=null==e?Ji:[+e[0],+e[1]],t):T},t.center=function(e){return arguments.length?(m=e&&[+e[0],+e[1]],t):m},t.size=function(e){return arguments.length?(A=e&&[+e[0],+e[1]],t):A},t.duration=function(e){return arguments.length?(S=+e,t):S},t.x=function(e){return arguments.length?(_=e,b=e.copy(),M={x:0,y:0,k:1},t):_},t.y=function(e){return arguments.length?(k=e,w=e.copy(),M={x:0,y:0,k:1},t):k},ui.rebind(t,D,\"on\")};var Qi,Wi,Ji=[0,1/0];ui.color=st,st.prototype.toString=function(){return this.rgb()+\"\"},ui.hsl=ct;var Ki=ct.prototype=new st;Ki.brighter=function(t){return t=Math.pow(.7,arguments.length?t:1),new ct(this.h,this.s,this.l/t)},Ki.darker=function(t){return t=Math.pow(.7,arguments.length?t:1),new ct(this.h,this.s,t*this.l)},Ki.rgb=function(){return ut(this.h,this.s,this.l)},ui.hcl=ft;var tl=ft.prototype=new st;tl.brighter=function(t){return new ft(this.h,this.c,Math.min(100,this.l+el*(arguments.length?t:1)))},tl.darker=function(t){return new ft(this.h,this.c,Math.max(0,this.l-el*(arguments.length?t:1)))},tl.rgb=function(){return dt(this.h,this.c,this.l).rgb()},ui.lab=ht;var el=18,nl=.95047,rl=1,al=1.08883,ol=ht.prototype=new st;ol.brighter=function(t){return new ht(Math.min(100,this.l+el*(arguments.length?t:1)),this.a,this.b)},ol.darker=function(t){return new ht(Math.max(0,this.l-el*(arguments.length?t:1)),this.a,this.b)},ol.rgb=function(){return pt(this.l,this.a,this.b)},ui.rgb=xt;var il=xt.prototype=new st;il.brighter=function(t){t=Math.pow(.7,arguments.length?t:1);var e=this.r,n=this.g,r=this.b,a=30;return e||n||r?(e&&a>e&&(e=a),n&&a>n&&(n=a),r&&a>r&&(r=a),new xt(Math.min(255,e/t),Math.min(255,n/t),Math.min(255,r/t))):new xt(a,a,a)},il.darker=function(t){return t=Math.pow(.7,arguments.length?t:1),new xt(t*this.r,t*this.g,t*this.b)},il.hsl=function(){return Mt(this.r,this.g,this.b)},il.toString=function(){return\"#\"+wt(this.r)+wt(this.g)+wt(this.b)};var ll=ui.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsa" -, -"lmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ll.forEach(function(t,e){ll.set(t,bt(e))}),ui.functor=zt,ui.xhr=St(b),ui.dsv=function(t,e){function n(t,n,o){arguments.length<3&&(o=n,n=null);var i=Et(t,e,null==n?r:a(n),o);return i.row=function(t){return arguments.length?i.response(null==(n=t)?r:a(t)):n},i}function r(t){return n.parse(t.responseText)}function a(t){return function(e){return n.parse(e.responseText,t)}}function o(e){return e.map(i).join(t)}function i(t){return l.test(t)?'\"'+t.replace(/\\\"/g,'\"\"')+'\"':t}var l=new RegExp('[\"'+t+\"\\n]\"),s=t.charCodeAt(0);return n.parse=function(t,e){var r;return n.parseRows(t,function(t,n){if(r)return r(t,n-1);var a=new Function(\"d\",\"return {\"+t.map(function(t,e){return JSON.stringify(t)+\": d[\"+e+\"]\"}).join(\",\")+\"}\");r=e?function(t,n){return e(a(t),n)}:a})},n.parseRows=function(t,e){function n(){if(u>=c)return i;if(a)return a=!1,o;var e=u;if(34===t.charCodeAt(e)){for(var n=e;n++<c;)if(34===t.charCodeAt(n)){if(34!==t.charCodeAt(n+1))break;++n}u=n+2;var r=t.charCodeAt(n+1);return 13===r?(a=!0,10===t.charCodeAt(n+2)&&++u):10===r&&(a=!0),t.slice(e+1,n).replace(/\"\"/g,'\"')}for(;c>u;){var r=t.charCodeAt(u++),l=1;if(10===r)a=!0;else if(13===r)a=!0,10===t.charCodeAt(u)&&(++u,++l);else if(r!==s)continue;return t.slice(e,u-l)}return t.slice(e)}for(var r,a,o={},i={},l=[],c=t.length,u=0,f=0;(r=n())!==i;){for(var d=[];r!==o&&r!==i;)d.push(r),r=n();e&&null==(d=e(d,f++))||l.push(d)}return l},n.format=function(e){if(Array.isArray(e[0]))return n.formatRows(e);var r=new x,a=[];return e.forEach(function(t){for(var e in t)r.has(e)||a.push(r.add(e))}),[a.map(i).join(t)].concat(e.map(function(e){return a.map(function(t){return i(e[t])}).join(t)})).join(\"\\n\")},n.formatRows=function(t){return t.map(o).join(\"\\n\")},n},ui.csv=ui.dsv(\",\",\"text/csv\"),ui.tsv=ui.dsv(\" \",\"text/tab-separated-values\");var sl,cl,ul,fl,dl=this[w(this,\"requestAnimationFrame\")]||function(t){setTimeout(t,17)};ui.timer=function(){Pt.apply(this,arguments)},ui.timer.flush=function(){Dt(),It()},ui.round=function(t,e){return e?Math.round(t*(e=Math.pow(10,e)))/e:Math.round(t)};var hl=[\"y\",\"z\",\"a\",\"f\",\"p\",\"n\",\"\\xb5\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\",\"P\",\"E\",\"Z\",\"Y\"].map(jt);ui.formatPrefix=function(t,e){var n=0;return(t=+t)&&(0>t&&(t*=-1),e&&(t=ui.round(t,Rt(t,e))),n=1+Math.floor(1e-12+Math.log(t)/Math.LN10),n=Math.max(-24,Math.min(24,3*Math.floor((n-1)/3)))),hl[8+n/3]};var pl=/(?:([^{])?([<>=^]))?([+\\- ])?([$#])?(0)?(\\d+)?(,)?(\\.-?\\d+)?([a-z%])?/i,gl=ui.map({b:function(t){return t.toString(2)},c:function(t){return String.fromCharCode(t)},o:function(t){return t.toString(8)},x:function(t){return t.toString(16)},X:function(t){return t.toString(16).toUpperCase()},g:function(t,e){return t.toPrecision(e)},e:function(t,e){return t.toExponential(e)},f:function(t,e){return t.toFixed(e)},r:function(t,e){return(t=ui.round(t,Rt(t,e))).toFixed(Math.max(0,Math.min(20,Rt(t*(1+1e-15),e))))}}),vl=ui.time={},ml=Date;Bt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){yl.setUTCDate.apply(this._,arguments)},setDay:function(){yl.setUTCDay.apply(this._,arguments)},setFullYear:function(){yl.setUTCFullYear.apply(this._,arguments)},setHours:function(){yl.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){yl.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){yl.setUTCMinutes.apply(this._,arguments)},setMonth:function(){yl.setUTCMonth.apply(this._,arguments)},setSeconds:function(){yl.setUTCSeconds.apply(this._,arguments)},setTime:function(){yl.setTime.apply(this._,arguments)}};var yl=Date.prototype;vl.year=Ht(function(t){return t=vl.day(t),t.setMonth(0,1),t},function(t,e){t.setFullYear(t.getFullYear()+e)},function(t){return t.getFullYear()}),vl.years=vl.year.range,vl.years.utc=vl.year.utc.range,vl.day=Ht(function(t){var e=new ml(2e3,0);return e.setFullYear(t.getFullYear(),t.getMonth(),t.getDate()),e},function(t,e){t.setDate(t.getDate()+e)},function(t){return t.getDate()-1}),vl.days=vl.day.range,vl.days.utc=vl.day.utc.range,vl.dayOfYear=function(t){var e=vl.year(t);return Math.floor((t-e-6e4*(t.getTimezoneOffset()-e.getTimezoneOffset()))/864e5)},[\"sunday\",\"monday\",\"tuesday\",\"wednesday\",\"thursday\",\"friday\",\"saturday\"].forEach(function(t,e){e=7-e;var n=vl[t]=Ht(function(t){return(t=vl.day(t)).setDate(t.getDate()-(t.getDay()+e)%7),t},function(t,e){t.setDate(t.getDate()+7*Math.floor(e))},function(t){var n=vl.year(t).getDay();return Math.floor((vl.dayOfYear(t)+(n+e)%7)/7)-(n!==e)});vl[t+\"s\"]=n.range,vl[t+\"s\"].utc=n.utc.range,vl[t+\"OfYear\"]=function(t){var n=vl.year(t).getDay();return Math.floor((vl.dayOfYear(t)+(n+e)%7)/7)}}),vl.week=vl.sunday,vl.weeks=vl.sunday.range,vl.weeks.utc=vl.sunday.utc.range,vl.weekOfYear=vl.sundayOfYear;var xl={\"-\":\"\",_:\" \",0:\"0\"},bl=/^\\s*\\d+/,_l=/^%/;ui.locale=function(t){return{numberFormat:qt(t),timeFormat:Zt(t)}};var wl=ui.locale({decimal:\".\",thousands:\",\",grouping:[3],currency:[\"$\",\"\"],dateTime:\"%a %b %e %X %Y\",date:\"%m/%d/%Y\",time:\"%H:%M:%S\",periods:[\"AM\",\"PM\"],days:[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"],shortDays:[\"Sun\",\"Mon\",\"Tue\",\"Wed\",\"Thu\",\"Fri\",\"Sat\"],months:[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"],shortMonths:[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"]});ui.format=wl.numberFormat,ui.geo={},fe.prototype={s:0,t:0,add:function(t){de(t,this.t,kl),de(kl.s,this.s,this),this.s?this.t+=kl.t:this.s=kl.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var kl=new fe;ui.geo.stream=function(t,e){t&&Ml.hasOwnProperty(t.type)?Ml[t.type](t,e):he(t,e)};var Ml={Feature:function(t,e){he(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,a=n.length;++r<a;)he(n[r].geometry,e)}},Al={Sphere:function(t,e){e.sphere()},Point:function(t,e){t=t.coordinates,e.point(t[0],t[1],t[2])},MultiPoint:function(t,e){for(var n=t.coordinates,r=-1,a=n.length;++r<a;)t=n[r],e.point(t[0],t[1],t[2])},LineString:function(t,e){pe(t.coordinates,e,0)},MultiLineString:function(t,e){for(var n=t.coordinates,r=-1,a=n.length;++r<a;)pe(n[r],e,0)},Polygon:function(t,e){ge(t.coordinates,e)},MultiPolygon:function(t,e){for(var n=t.coordinates,r=-1,a=n.length;++r<a;)ge(n[r],e)},GeometryCollection:function(t,e){for(var n=t.geometries,r=-1,a=n.length;++r<a;)he(n[r],e)}};ui.geo.area=function(t){return Ll=0,ui.geo.stream(t,zl),Ll};var Ll,Tl=new fe,zl={sphere:function(){Ll+=4*Bi},point:k,lineStart:k,lineEnd:k,polygonStart:function(){Tl.reset(),zl.lineStart=ve},polygonEnd:function(){var t=2*Tl;Ll+=0>t?4*Bi+t:t,zl.lineStart=zl.lineEnd=zl.point=k}};ui.geo.bounds=function(){function t(t,e){x.push(b=[u=t,d=t]),f>e&&(f=e),e>h&&(h=e)}function e(e,n){var r=me([e*Yi,n*Yi]);if(m){var a=xe(m,r),o=[a[1],-a[0],0],i=xe(o,a);we(i),i=ke(i);var s=e-p,c=s>0?1:-1,g=i[0]*Ui*c,v=wi(s)>180;if(v^(g>c*p&&c*e>g)){var y=i[1]*Ui;y>h&&(h=y)}else if(g=(g+360)%360-180,v^(g>c*p&&c*e>g)){var y=-i[1]*Ui;f>y&&(f=y)}else f>n&&(f=n),n>h&&(h=n);v?p>e?l(u,e)>l(u,d)&&(d=e):l(e,d)>l(u,d)&&(u=e):d>=u?(u>e&&(u=e),e>d&&(d=e)):e>p?l(u,e)>l(u,d)&&(d=e):l(e,d)>l(u,d)&&(u=e)}else t(e,n);m=r,p=e}function n(){_.point=e}function r(){b[0]=u,b[1]=d,_.point=t,m=null}function a(t,n){if(m){var r=t-p;y+=wi(r)>180?r+(r>0?360:-360):r}else g=t,v=n;zl.point(t,n),e(t,n)}function o(){zl.lineStart()}function i(){a(g,v),zl.lineEnd(),wi(y)>qi&&(u=-(d=180)),b[0]=u,b[1]=d,m=null}function l(t,e){return(e-=t)<0?e+360:e}function s(t,e){return t[0]-e[0]}function c(t,e){return e[0]<=e[1]?e[0]<=t&&t<=e[1]:t<e[0]||e[1]<t}var u,f,d,h,p,g,v,m,y,x,b,_={point:t,lineStart:n,lineEnd:r,polygonStart:function(){_.point=a,_.lineStart=o,_.lineEnd=i,y=0,zl.polygonStart()},polygonEnd:function(){zl.polygonEnd(),_.point=t,_.lineStart=n,_.lineEnd=r,0>Tl?(u=-(d=180),f=-(h=90)):y>qi?h=90:-qi>y&&(f=-90),b[0]=u,b[1]=d}};return function(t){h=d=-(u=f=1/0),x=[],ui.geo.stream(t,_);var e=x.length;if(e){x.sort(s);for(var n,r=1,a=x[0],o=[a];e>r;++r)n=x[r],c(n[0],a)||c(n[1],a)?(l(a[0],n[1])>l(a[0],a[1])&&(a[1]=n[1]),l(n[0],a[1])>l(a[0],a[1])&&(a[0]=n[0])):o.push(a=n);for(var i,n,p=-(1/0),e=o.length-1,r=0,a=o[e];e>=r;a=n,++r)n=o[r],(i=l(a[1],n[0]))>p&&(p=i,u=n[0],d=a[1])}return x=b=null,u===1/0||f===1/0?[[NaN,NaN],[NaN,NaN]]:" -, -"[[u,f],[d,h]]}}(),ui.geo.centroid=function(t){Sl=El=Cl=Ol=Pl=Nl=Dl=Il=Rl=jl=ql=0,ui.geo.stream(t,Fl);var e=Rl,n=jl,r=ql,a=e*e+n*n+r*r;return Fi>a&&(e=Nl,n=Dl,r=Il,qi>El&&(e=Cl,n=Ol,r=Pl),a=e*e+n*n+r*r,Fi>a)?[NaN,NaN]:[Math.atan2(n,e)*Ui,rt(r/Math.sqrt(a))*Ui]};var Sl,El,Cl,Ol,Pl,Nl,Dl,Il,Rl,jl,ql,Fl={sphere:k,point:Ae,lineStart:Te,lineEnd:ze,polygonStart:function(){Fl.lineStart=Se},polygonEnd:function(){Fl.lineStart=Te}},Bl=De(Ce,qe,Be,[-Bi,-Bi/2]),Hl=1e9;ui.geo.clipExtent=function(){var t,e,n,r,a,o,i={stream:function(t){return a&&(a.valid=!1),a=o(t),a.valid=!0,a},extent:function(l){return arguments.length?(o=Ye(t=+l[0][0],e=+l[0][1],n=+l[1][0],r=+l[1][1]),a&&(a.valid=!1,a=null),i):[[t,e],[n,r]]}};return i.extent([[0,0],[960,500]])},(ui.geo.conicEqualArea=function(){return Ue(Xe)}).raw=Xe,ui.geo.albers=function(){return ui.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ui.geo.albersUsa=function(){function t(t){var o=t[0],i=t[1];return e=null,n(o,i),e||(r(o,i),e)||a(o,i),e}var e,n,r,a,o=ui.geo.albers(),i=ui.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),l=ui.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),s={point:function(t,n){e=[t,n]}};return t.invert=function(t){var e=o.scale(),n=o.translate(),r=(t[0]-n[0])/e,a=(t[1]-n[1])/e;return(a>=.12&&.234>a&&r>=-.425&&-.214>r?i:a>=.166&&.234>a&&r>=-.214&&-.115>r?l:o).invert(t)},t.stream=function(t){var e=o.stream(t),n=i.stream(t),r=l.stream(t);return{point:function(t,a){e.point(t,a),n.point(t,a),r.point(t,a)},sphere:function(){e.sphere(),n.sphere(),r.sphere()},lineStart:function(){e.lineStart(),n.lineStart(),r.lineStart()},lineEnd:function(){e.lineEnd(),n.lineEnd(),r.lineEnd()},polygonStart:function(){e.polygonStart(),n.polygonStart(),r.polygonStart()},polygonEnd:function(){e.polygonEnd(),n.polygonEnd(),r.polygonEnd()}}},t.precision=function(e){return arguments.length?(o.precision(e),i.precision(e),l.precision(e),t):o.precision()},t.scale=function(e){return arguments.length?(o.scale(e),i.scale(.35*e),l.scale(e),t.translate(o.translate())):o.scale()},t.translate=function(e){if(!arguments.length)return o.translate();var c=o.scale(),u=+e[0],f=+e[1];return n=o.translate(e).clipExtent([[u-.455*c,f-.238*c],[u+.455*c,f+.238*c]]).stream(s).point,r=i.translate([u-.307*c,f+.201*c]).clipExtent([[u-.425*c+qi,f+.12*c+qi],[u-.214*c-qi,f+.234*c-qi]]).stream(s).point,a=l.translate([u-.205*c,f+.212*c]).clipExtent([[u-.214*c+qi,f+.166*c+qi],[u-.115*c-qi,f+.234*c-qi]]).stream(s).point,t},t.scale(1070)};var Vl,Zl,Yl,Ul,Xl,Gl,$l={point:k,lineStart:k,lineEnd:k,polygonStart:function(){Zl=0,$l.lineStart=Ge},polygonEnd:function(){$l.lineStart=$l.lineEnd=$l.point=k,Vl+=wi(Zl/2)}},Ql={point:$e,lineStart:k,lineEnd:k,polygonStart:k,polygonEnd:k},Wl={point:Je,lineStart:Ke,lineEnd:tn,polygonStart:function(){Wl.lineStart=en},polygonEnd:function(){Wl.point=Je,Wl.lineStart=Ke,Wl.lineEnd=tn}};ui.geo.path=function(){function t(t){return t&&(\"function\"==typeof l&&o.pointRadius(+l.apply(this,arguments)),i&&i.valid||(i=a(o)),ui.geo.stream(t,i)),o.result()}function e(){return i=null,t}var n,r,a,o,i,l=4.5;return t.area=function(t){return Vl=0,ui.geo.stream(t,a($l)),Vl},t.centroid=function(t){return Cl=Ol=Pl=Nl=Dl=Il=Rl=jl=ql=0,ui.geo.stream(t,a(Wl)),ql?[Rl/ql,jl/ql]:Il?[Nl/Il,Dl/Il]:Pl?[Cl/Pl,Ol/Pl]:[NaN,NaN]},t.bounds=function(t){return Xl=Gl=-(Yl=Ul=1/0),ui.geo.stream(t,a(Ql)),[[Yl,Ul],[Xl,Gl]]},t.projection=function(t){return arguments.length?(a=(n=t)?t.stream||an(t):b,e()):n},t.context=function(t){return arguments.length?(o=null==(r=t)?new Qe:new nn(t),\"function\"!=typeof l&&o.pointRadius(l),e()):r},t.pointRadius=function(e){return arguments.length?(l=\"function\"==typeof e?e:(o.pointRadius(+e),+e),t):l},t.projection(ui.geo.albersUsa()).context(null)},ui.geo.transform=function(t){return{stream:function(e){var n=new on(e);for(var r in t)n[r]=t[r];return n}}},on.prototype={point:function(t,e){this.stream.point(t,e)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ui.geo.projection=sn,ui.geo.projectionMutator=cn,(ui.geo.equirectangular=function(){return sn(fn)}).raw=fn.invert=fn,ui.geo.rotation=function(t){function e(e){return e=t(e[0]*Yi,e[1]*Yi),e[0]*=Ui,e[1]*=Ui,e}return t=hn(t[0]%360*Yi,t[1]*Yi,t.length>2?t[2]*Yi:0),e.invert=function(e){return e=t.invert(e[0]*Yi,e[1]*Yi),e[0]*=Ui,e[1]*=Ui,e},e},dn.invert=fn,ui.geo.circle=function(){function t(){var t=\"function\"==typeof r?r.apply(this,arguments):r,e=hn(-t[0]*Yi,-t[1]*Yi,0).invert,a=[];return n(null,null,1,{point:function(t,n){a.push(t=e(t,n)),t[0]*=Ui,t[1]*=Ui}}),{type:\"Polygon\",coordinates:[a]}}var e,n,r=[0,0],a=6;return t.origin=function(e){return arguments.length?(r=e,t):r},t.angle=function(r){return arguments.length?(n=mn((e=+r)*Yi,a*Yi),t):e},t.precision=function(r){return arguments.length?(n=mn(e*Yi,(a=+r)*Yi),t):a},t.angle(90)},ui.geo.distance=function(t,e){var n,r=(e[0]-t[0])*Yi,a=t[1]*Yi,o=e[1]*Yi,i=Math.sin(r),l=Math.cos(r),s=Math.sin(a),c=Math.cos(a),u=Math.sin(o),f=Math.cos(o);return Math.atan2(Math.sqrt((n=f*i)*n+(n=c*u-s*f*l)*n),s*u+c*f*l)},ui.geo.graticule=function(){function t(){return{type:\"MultiLineString\",coordinates:e()}}function e(){return ui.range(Math.ceil(o/v)*v,a,v).map(d).concat(ui.range(Math.ceil(c/m)*m,s,m).map(h)).concat(ui.range(Math.ceil(r/p)*p,n,p).filter(function(t){return wi(t%v)>qi}).map(u)).concat(ui.range(Math.ceil(l/g)*g,i,g).filter(function(t){return wi(t%m)>qi}).map(f))}var n,r,a,o,i,l,s,c,u,f,d,h,p=10,g=p,v=90,m=360,y=2.5;return t.lines=function(){return e().map(function(t){return{type:\"LineString\",coordinates:t}})},t.outline=function(){return{type:\"Polygon\",coordinates:[d(o).concat(h(s).slice(1),d(a).reverse().slice(1),h(c).reverse().slice(1))]}},t.extent=function(e){return arguments.length?t.majorExtent(e).minorExtent(e):t.minorExtent()},t.majorExtent=function(e){return arguments.length?(o=+e[0][0],a=+e[1][0],c=+e[0][1],s=+e[1][1],o>a&&(e=o,o=a,a=e),c>s&&(e=c,c=s,s=e),t.precision(y)):[[o,c],[a,s]]},t.minorExtent=function(e){return arguments.length?(r=+e[0][0],n=+e[1][0],l=+e[0][1],i=+e[1][1],r>n&&(e=r,r=n,n=e),l>i&&(e=l,l=i,i=e),t.precision(y)):[[r,l],[n,i]]},t.step=function(e){return arguments.length?t.majorStep(e).minorStep(e):t.minorStep()},t.majorStep=function(e){return arguments.length?(v=+e[0],m=+e[1],t):[v,m]},t.minorStep=function(e){return arguments.length?(p=+e[0],g=+e[1],t):[p,g]},t.precision=function(e){return arguments.length?(y=+e,u=xn(l,i,90),f=bn(r,n,y),d=xn(c,s,90),h=bn(o,a,y),t):y},t.majorExtent([[-180,-90+qi],[180,90-qi]]).minorExtent([[-180,-80-qi],[180,80+qi]])},ui.geo.greatArc=function(){function t(){return{type:\"LineString\",coordinates:[e||r.apply(this,arguments),n||a.apply(this,arguments)]}}var e,n,r=_n,a=wn;return t.distance=function(){return ui.geo.distance(e||r.apply(this,arguments),n||a.apply(this,arguments))},t.source=function(n){return arguments.length?(r=n,e=\"function\"==typeof n?null:n,t):r},t.target=function(e){return arguments.length?(a=e,n=\"function\"==typeof e?null:e,t):a},t.precision=function(){return arguments.length?t:0},t},ui.geo.interpolate=function(t,e){return kn(t[0]*Yi,t[1]*Yi,e[0]*Yi,e[1]*Yi)},ui.geo.length=function(t){return Jl=0,ui.geo.stream(t,Kl),Jl};var Jl,Kl={sphere:k,point:k,lineStart:Mn,lineEnd:k,polygonStart:k,polygonEnd:k},ts=An(function(t){return Math.sqrt(2/(1+t))},function(t){return 2*Math.asin(t/2)});(ui.geo.azimuthalEqualArea=function(){return sn(ts)}).raw=ts;var es=An(function(t){var e=Math.acos(t);return e&&e/Math.sin(e)},b);(ui.geo.azimuthalEquidistant=function(){return sn(es)}).raw=es,(ui.geo.conicConformal=function(){return Ue(Ln)}).raw=Ln,(ui.geo.conicEquidistant=function(){return Ue(Tn)}).raw=Tn;var ns=An(function(t){return 1/t},Math.atan);(ui.geo.gnomonic=function(){return sn(ns)}).raw=ns,zn.invert=function(t,e){return[t,2*Math.atan(Math.exp(e))-Zi]},(ui.geo.mercator=function(){return Sn(zn)}).raw=zn;var rs=An(function(){return 1},Math.asin);(ui.geo.orthographic=function(){return sn(rs)}).raw=rs;var as=An(function(t){return 1/(1+t)},function(t){return 2*Math.atan(t)});(ui.geo.stereographic=function(){return sn(as)}).raw=as,En.invert=function(t,e){return[-e,2*Math.atan(Math.exp(t))-Zi]},(ui.geo.transverseMercator=function(){var t=Sn(En),e=t.center,n=t.rotate;return t.center=function(t){return t?e([-t[1],t[0]]):(t=e(),[t[1],-t[0]])},t.rotate=function(t){return t?n([t[0],t[1],t.length>2?t[2]+90:90]):(t=n(),[t[0],t[1],t[2]-90])},n([0,0,90])}).raw=En,ui.geom={},ui.geom.hull=function(t){function e(t){if(t.length<3)return[];var e,a=zt(n),o=zt(r),i=t.length,l=[],s=[];for(e=0;i>e;e++)l.push([+a.call(this,t[e],e),+o.call(this,t[e],e),e]);for(l.sort(Nn),e=0;i>e;e++)s.push([l[e][0],-l[e][1]]);var c=Pn(l),u=Pn(s),f=u[0]===c[0],d=u[u.length-1]===c[c.length-1],h=[];for(e=c.length-1;e>=0;--e)h.push(t[l[c[e]][2]]);for(e=+f;e<u.length-d;++e)h.push(t[l[u[e]][2]]);return h}var n=Cn,r=On;return arguments.length?e(t):(e.x=function(t){return arguments.length?(n=t,e):n},e.y=function(t){return arguments.length?(r=t,e):r},e)},ui.geom.polygon=function(t){return Ti(t,os),t};var os=ui.geom.polygon.prototype=[];os.area=function(){for(var t,e=-1,n=this.length,r=this[n-1],a=0;++e<n;)t=r,r=this[e],a+=t[1]*r[0]-t[0]*r[1];return.5*a},os.centroid=function(t){var e,n,r=-1,a=this.length,o=0,i=0,l=this[a-1];for(arguments.length||(t=-1/(6*this.area()));++r<a;)e=l,l=this[r],n=e[0]*l[1]-l[0]*e[1],o+=(e[0]+l[0])*n,i+=(e[1]+l[1])*n;return[o*t,i*t]},os.clip=function(t){for(var e,n,r,a,o,i,l=Rn(t),s=-1,c=this.length-Rn(this),u=this[c-1];++s<c;){for(e=t.slice(),t.length=0,a=this[s],o=e[(r=e.length-l)-1],n=-1;++n<r;)i=e[n],Dn(i,u,a)?(Dn(o,u,a)||t.push(In(o,i,u,a)),t.push(i)):Dn(o,u,a)&&t.push(In(o,i,u,a)),o=i;l&&t.push(t[0]),u=a}return t};var is,ls,ss,cs,us,fs=[],ds=[];Yn.prototype.prepare=function(){for(var t,e=this.edges,n=e" -, -".length;n--;)t=e[n].edge,t.b&&t.a||e.splice(n,1);return e.sort(Xn),e.length},rr.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},ar.prototype={insert:function(t,e){var n,r,a;if(t){if(e.P=t,e.N=t.N,t.N&&(t.N.P=e),t.N=e,t.R){for(t=t.R;t.L;)t=t.L;t.L=e}else t.R=e;n=t}else this._?(t=sr(this._),e.P=null,e.N=t,t.P=t.L=e,n=t):(e.P=e.N=null,this._=e,n=null);for(e.L=e.R=null,e.U=n,e.C=!0,t=e;n&&n.C;)r=n.U,n===r.L?(a=r.R,a&&a.C?(n.C=a.C=!1,r.C=!0,t=r):(t===n.R&&(ir(this,n),t=n,n=t.U),n.C=!1,r.C=!0,lr(this,r))):(a=r.L,a&&a.C?(n.C=a.C=!1,r.C=!0,t=r):(t===n.L&&(lr(this,n),t=n,n=t.U),n.C=!1,r.C=!0,ir(this,r))),n=t.U;this._.C=!1},remove:function(t){t.N&&(t.N.P=t.P),t.P&&(t.P.N=t.N),t.N=t.P=null;var e,n,r,a=t.U,o=t.L,i=t.R;if(n=o?i?sr(i):o:i,a?a.L===t?a.L=n:a.R=n:this._=n,o&&i?(r=n.C,n.C=t.C,n.L=o,o.U=n,n!==i?(a=n.U,n.U=t.U,t=n.R,a.L=t,n.R=i,i.U=n):(n.U=a,a=n,t=n.R)):(r=t.C,t=n),t&&(t.U=a),!r){if(t&&t.C)return void(t.C=!1);do{if(t===this._)break;if(t===a.L){if(e=a.R,e.C&&(e.C=!1,a.C=!0,ir(this,a),e=a.R),e.L&&e.L.C||e.R&&e.R.C){e.R&&e.R.C||(e.L.C=!1,e.C=!0,lr(this,e),e=a.R),e.C=a.C,a.C=e.R.C=!1,ir(this,a),t=this._;break}}else if(e=a.L,e.C&&(e.C=!1,a.C=!0,lr(this,a),e=a.L),e.L&&e.L.C||e.R&&e.R.C){e.L&&e.L.C||(e.R.C=!1,e.C=!0,ir(this,e),e=a.L),e.C=a.C,a.C=e.L.C=!1,lr(this,a),t=this._;break}e.C=!0,t=a,a=a.U}while(!t.C);t&&(t.C=!1)}}},ui.geom.voronoi=function(t){function e(t){var e=new Array(t.length),r=l[0][0],a=l[0][1],o=l[1][0],i=l[1][1];return cr(n(t),l).cells.forEach(function(n,l){var s=n.edges,c=n.site,u=e[l]=s.length?s.map(function(t){var e=t.start();return[e.x,e.y]}):c.x>=r&&c.x<=o&&c.y>=a&&c.y<=i?[[r,i],[o,i],[o,a],[r,a]]:[];u.point=t[l]}),e}function n(t){return t.map(function(t,e){return{x:Math.round(o(t,e)/qi)*qi,y:Math.round(i(t,e)/qi)*qi,i:e}})}var r=Cn,a=On,o=r,i=a,l=hs;return t?e(t):(e.links=function(t){return cr(n(t)).edges.filter(function(t){return t.l&&t.r}).map(function(e){\n" -, -"return{source:t[e.l.i],target:t[e.r.i]}})},e.triangles=function(t){var e=[];return cr(n(t)).cells.forEach(function(n,r){for(var a,o,i=n.site,l=n.edges.sort(Xn),s=-1,c=l.length,u=l[c-1].edge,f=u.l===i?u.r:u.l;++s<c;)a=u,o=f,u=l[s].edge,f=u.l===i?u.r:u.l,r<o.i&&r<f.i&&fr(i,o,f)<0&&e.push([t[r],t[o.i],t[f.i]])}),e},e.x=function(t){return arguments.length?(o=zt(r=t),e):r},e.y=function(t){return arguments.length?(i=zt(a=t),e):a},e.clipExtent=function(t){return arguments.length?(l=null==t?hs:t,e):l===hs?null:l},e.size=function(t){return arguments.length?e.clipExtent(t&&[[0,0],t]):l===hs?null:l&&l[1]},e)};var hs=[[-1e6,-1e6],[1e6,1e6]];ui.geom.delaunay=function(t){return ui.geom.voronoi().triangles(t)},ui.geom.quadtree=function(t,e,n,r,a){function o(t){function o(t,e,n,r,a,o,i,l){if(!isNaN(n)&&!isNaN(r))if(t.leaf){var s=t.x,u=t.y;if(null!=s)if(wi(s-n)+wi(u-r)<.01)c(t,e,n,r,a,o,i,l);else{var f=t.point;t.x=t.y=t.point=null,c(t,f,s,u,a,o,i,l),c(t,e,n,r,a,o,i,l)}else t.x=n,t.y=r,t.point=e}else c(t,e,n,r,a,o,i,l)}function c(t,e,n,r,a,i,l,s){var c=.5*(a+l),u=.5*(i+s),f=n>=c,d=r>=u,h=d<<1|f;t.leaf=!1,t=t.nodes[h]||(t.nodes[h]=pr()),f?a=c:l=c,d?i=u:s=u,o(t,e,n,r,a,i,l,s)}var u,f,d,h,p,g,v,m,y,x=zt(l),b=zt(s);if(null!=e)g=e,v=n,m=r,y=a;else if(m=y=-(g=v=1/0),f=[],d=[],p=t.length,i)for(h=0;p>h;++h)u=t[h],u.x<g&&(g=u.x),u.y<v&&(v=u.y),u.x>m&&(m=u.x),u.y>y&&(y=u.y),f.push(u.x),d.push(u.y);else for(h=0;p>h;++h){var _=+x(u=t[h],h),w=+b(u,h);g>_&&(g=_),v>w&&(v=w),_>m&&(m=_),w>y&&(y=w),f.push(_),d.push(w)}var k=m-g,M=y-v;k>M?y=v+k:m=g+M;var A=pr();if(A.add=function(t){o(A,t,+x(t,++h),+b(t,h),g,v,m,y)},A.visit=function(t){gr(t,A,g,v,m,y)},A.find=function(t){return vr(A,t[0],t[1],g,v,m,y)},h=-1,null==e){for(;++h<p;)o(A,t[h],f[h],d[h],g,v,m,y);--h}else t.forEach(A.add);return f=d=t=u=null,A}var i,l=Cn,s=On;return(i=arguments.length)?(l=dr,s=hr,3===i&&(a=n,r=e,n=e=0),o(t)):(o.x=function(t){return arguments.length?(l=t,o):l},o.y=function(t){return arguments.length?(s=t,o):s},o.extent=function(t){return arguments.length?(null==t?e=n=r=a=null:(e=+t[0][0],n=+t[0][1],r=+t[1][0],a=+t[1][1]),o):null==e?null:[[e,n],[r,a]]},o.size=function(t){return arguments.length?(null==t?e=n=r=a=null:(e=n=0,r=+t[0],a=+t[1]),o):null==e?null:[r-e,a-n]},o)},ui.interpolateRgb=mr,ui.interpolateObject=yr,ui.interpolateNumber=xr,ui.interpolateString=br;var ps=/[-+]?(?:\\d+\\.?\\d*|\\.?\\d+)(?:[eE][-+]?\\d+)?/g,gs=new RegExp(ps.source,\"g\");ui.interpolate=_r,ui.interpolators=[function(t,e){var n=typeof e;return(\"string\"===n?ll.has(e.toLowerCase())||/^(#|rgb\\(|hsl\\()/i.test(e)?mr:br:e instanceof st?mr:Array.isArray(e)?wr:\"object\"===n&&isNaN(e)?yr:xr)(t,e)}],ui.interpolateArray=wr;var vs=function(){return b},ms=ui.map({linear:vs,poly:Sr,quad:function(){return Lr},cubic:function(){return Tr},sin:function(){return Er},exp:function(){return Cr},circle:function(){return Or},elastic:Pr,back:Nr,bounce:function(){return Dr}}),ys=ui.map({\"in\":b,out:Mr,\"in-out\":Ar,\"out-in\":function(t){return Ar(Mr(t))}});ui.ease=function(t){var e=t.indexOf(\"-\"),n=e>=0?t.slice(0,e):t,r=e>=0?t.slice(e+1):\"in\";return n=ms.get(n)||vs,r=ys.get(r)||b,kr(r(n.apply(null,fi.call(arguments,1))))},ui.interpolateHcl=Ir,ui.interpolateHsl=Rr,ui.interpolateLab=jr,ui.interpolateRound=qr,ui.transform=function(t){var e=hi.createElementNS(ui.ns.prefix.svg,\"g\");return(ui.transform=function(t){if(null!=t){e.setAttribute(\"transform\",t);var n=e.transform.baseVal.consolidate()}return new Fr(n?n.matrix:xs)})(t)},Fr.prototype.toString=function(){return\"translate(\"+this.translate+\")rotate(\"+this.rotate+\")skewX(\"+this.skew+\")scale(\"+this.scale+\")\"};var xs={a:1,b:0,c:0,d:1,e:0,f:0};ui.interpolateTransform=$r,ui.layout={},ui.layout.bundle=function(){return function(t){for(var e=[],n=-1,r=t.length;++n<r;)e.push(Jr(t[n]));return e}},ui.layout.chord=function(){function t(){var t,c,f,d,h,p={},g=[],v=ui.range(o),m=[];for(n=[],r=[],t=0,d=-1;++d<o;){for(c=0,h=-1;++h<o;)c+=a[d][h];g.push(c),m.push(ui.range(o)),t+=c}for(i&&v.sort(function(t,e){return i(g[t],g[e])}),l&&m.forEach(function(t,e){t.sort(function(t,n){return l(a[e][t],a[e][n])})}),t=(Hi-u*o)/t,c=0,d=-1;++d<o;){for(f=c,h=-1;++h<o;){var y=v[d],x=m[y][h],b=a[y][x],_=c,w=c+=b*t;p[y+\"-\"+x]={index:y,subindex:x,startAngle:_,endAngle:w,value:b}}r[y]={index:y,startAngle:f,endAngle:c,value:g[y]},c+=u}for(d=-1;++d<o;)for(h=d-1;++h<o;){var k=p[d+\"-\"+h],M=p[h+\"-\"+d];(k.value||M.value)&&n.push(k.value<M.value?{source:M,target:k}:{source:k,target:M})}s&&e()}function e(){n.sort(function(t,e){return s((t.source.value+t.target.value)/2,(e.source.value+e.target.value)/2)})}var n,r,a,o,i,l,s,c={},u=0;return c.matrix=function(t){return arguments.length?(o=(a=t)&&a.length,n=r=null,c):a},c.padding=function(t){return arguments.length?(u=t,n=r=null,c):u},c.sortGroups=function(t){return arguments.length?(i=t,n=r=null,c):i},c.sortSubgroups=function(t){return arguments.length?(l=t,n=null,c):l},c.sortChords=function(t){return arguments.length?(s=t,n&&e(),c):s},c.chords=function(){return n||t(),n},c.groups=function(){return r||t(),r},c},ui.layout.force=function(){function t(t){return function(e,n,r,a){if(e.point!==t){var o=e.cx-t.x,i=e.cy-t.y,l=a-n,s=o*o+i*i;if(s>l*l/m){if(g>s){var c=e.charge/s;t.px-=o*c,t.py-=i*c}return!0}if(e.point&&s&&g>s){var c=e.pointCharge/s;t.px-=o*c,t.py-=i*c}}return!e.charge}}function e(t){t.px=ui.event.x,t.py=ui.event.y,s.resume()}var n,r,a,o,i,l,s={},c=ui.dispatch(\"start\",\"tick\",\"end\"),u=[1,1],f=.9,d=bs,h=_s,p=-30,g=ws,v=.1,m=.64,y=[],x=[];return s.tick=function(){if((a*=.99)<.005)return n=null,c.end({type:\"end\",alpha:a=0}),!0;var e,r,s,d,h,g,m,b,_,w=y.length,k=x.length;for(r=0;k>r;++r)s=x[r],d=s.source,h=s.target,b=h.x-d.x,_=h.y-d.y,(g=b*b+_*_)&&(g=a*i[r]*((g=Math.sqrt(g))-o[r])/g,b*=g,_*=g,h.x-=b*(m=d.weight+h.weight?d.weight/(d.weight+h.weight):.5),h.y-=_*m,d.x+=b*(m=1-m),d.y+=_*m);if((m=a*v)&&(b=u[0]/2,_=u[1]/2,r=-1,m))for(;++r<w;)s=y[r],s.x+=(b-s.x)*m,s.y+=(_-s.y)*m;if(p)for(oa(e=ui.geom.quadtree(y),a,l),r=-1;++r<w;)(s=y[r]).fixed||e.visit(t(s));for(r=-1;++r<w;)s=y[r],s.fixed?(s.x=s.px,s.y=s.py):(s.x-=(s.px-(s.px=s.x))*f,s.y-=(s.py-(s.py=s.y))*f);c.tick({type:\"tick\",alpha:a})},s.nodes=function(t){return arguments.length?(y=t,s):y},s.links=function(t){return arguments.length?(x=t,s):x},s.size=function(t){return arguments.length?(u=t,s):u},s.linkDistance=function(t){return arguments.length?(d=\"function\"==typeof t?t:+t,s):d},s.distance=s.linkDistance,s.linkStrength=function(t){return arguments.length?(h=\"function\"==typeof t?t:+t,s):h},s.friction=function(t){return arguments.length?(f=+t,s):f},s.charge=function(t){return arguments.length?(p=\"function\"==typeof t?t:+t,s):p},s.chargeDistance=function(t){return arguments.length?(g=t*t,s):Math.sqrt(g)},s.gravity=function(t){return arguments.length?(v=+t,s):v},s.theta=function(t){return arguments.length?(m=t*t,s):Math.sqrt(m)},s.alpha=function(t){return arguments.length?(t=+t,a?t>0?a=t:(n.c=null,n.t=NaN,n=null,c.end({type:\"end\",alpha:a=0})):t>0&&(c.start({type:\"start\",alpha:a=t}),n=Pt(s.tick)),s):a},s.start=function(){function t(t,r){if(!n){for(n=new Array(a),s=0;a>s;++s)n[s]=[];for(s=0;c>s;++s){var o=x[s];n[o.source.index].push(o.target),n[o.target.index].push(o.source)}}for(var i,l=n[e],s=-1,u=l.length;++s<u;)if(!isNaN(i=l[s][t]))return i;return Math.random()*r}var e,n,r,a=y.length,c=x.length,f=u[0],g=u[1];for(e=0;a>e;++e)(r=y[e]).index=e,r.weight=0;for(e=0;c>e;++e)r=x[e],\"number\"==typeof r.source&&(r.source=y[r.source]),\"number\"==typeof r.target&&(r.target=y[r.target]),++r.source.weight,++r.target.weight;for(e=0;a>e;++e)r=y[e],isNaN(r.x)&&(r.x=t(\"x\",f)),isNaN(r.y)&&(r.y=t(\"y\",g)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(o=[],\"function\"==typeof d)for(e=0;c>e;++e)o[e]=+d.call(this,x[e],e);else for(e=0;c>e;++e)o[e]=d;if(i=[],\"function\"==typeof h)for(e=0;c>e;++e)i[e]=+h.call(this,x[e],e);else for(e=0;c>e;++e)i[e]=h;if(l=[],\"function\"==typeof p)for(e=0;a>e;++e)l[e]=+p.call(this,y[e],e);else for(e=0;a>e;++e)l[e]=p;return s.resume()},s.resume=function(){return s.alpha(.1)},s.stop=function(){return s.alpha(0)},s.drag=function(){return r||(r=ui.behavior.drag().origin(b).on(\"dragstart.force\",ea).on(\"drag.force\",e).on(\"dragend.force\",na)),arguments.length?void this.on(\"mouseover.force\",ra).on(\"mouseout.force\",aa).call(r):r},ui.rebind(s,c,\"on\")};var bs=20,_s=1,ws=1/0;ui.layout.hierarchy=function(){function t(a){var o,i=[a],l=[];for(a.depth=0;null!=(o=i.pop());)if(l.push(o),(c=n.call(t,o,o.depth))&&(s=c.length)){for(var s,c,u;--s>=0;)i.push(u=c[s]),u.parent=o,u.depth=o.depth+1;r&&(o.value=0),o.children=c}else r&&(o.value=+r.call(t,o,o.depth)||0),delete o.children;return sa(a,function(t){var n,a;e&&(n=t.children)&&n.sort(e),r&&(a=t.parent)&&(a.value+=t.value)}),l}var e=fa,n=ca,r=ua;return t.sort=function(n){return arguments.length?(e=n,t):e},t.children=function(e){return arguments.length?(n=e,t):n},t.value=function(e){return arguments.length?(r=e,t):r},t.revalue=function(e){return r&&(la(e,function(t){t.children&&(t.value=0)}),sa(e,function(e){var n;e.children||(e.value=+r.call(t,e,e.depth)||0),(n=e.parent)&&(n.value+=e.value)})),e},t},ui.layout.partition=function(){function t(e,n,r,a){var o=e.children;if(e.x=n,e.y=e.depth*a,e.dx=r,e.dy=a,o&&(i=o.length)){var i,l,s,c=-1;for(r=e.value?r/e.value:0;++c<i;)t(l=o[c],n,s=l.value*r,a),n+=s}}function e(t){var n=t.children,r=0;if(n&&(a=n.length))for(var a,o=-1;++o<a;)r=Math.max(r,e(n[o]));return 1+r}function n(n,o){var i=r.call(this,n,o);return t(i[0],0,a[0],a[1]/e(i[0])),i}var r=ui.layout.hierarchy(),a=[1,1];return n.size=function(t){return arguments.length?(a=t,n):a},ia(n,r)},ui.layout.pie=function(){function t(i){var l,s=i.length,c=i.map(function(n,r){return+e.call(t,n,r)}),u=+(\"function\"==typeof r?r.apply(this,arguments):r),f=(\"function\"==typeof a?a.apply(this,arguments):a)-u,d=Math.min(Math.abs(f)/s,+(\"function\"==typeof o?o.apply(this,arguments):o)),h=d*(0>f?-1:1),p=ui.sum(c),g=p?(f-s*h)/p:0,v=ui.range(s),m=[];return null!=n&&v.sort(n===ks?function(t,e){return c[e]-c[t]}:function(t,e){ret" -, -"urn n(i[t],i[e])}),v.forEach(function(t){m[t]={data:i[t],value:l=c[t],startAngle:u,endAngle:u+=l*g+h,padAngle:d}}),m}var e=Number,n=ks,r=0,a=Hi,o=0;return t.value=function(n){return arguments.length?(e=n,t):e},t.sort=function(e){return arguments.length?(n=e,t):n},t.startAngle=function(e){return arguments.length?(r=e,t):r},t.endAngle=function(e){return arguments.length?(a=e,t):a},t.padAngle=function(e){return arguments.length?(o=e,t):o},t};var ks={};ui.layout.stack=function(){function t(l,s){if(!(d=l.length))return l;var c=l.map(function(n,r){return e.call(t,n,r)}),u=c.map(function(e){return e.map(function(e,n){return[o.call(t,e,n),i.call(t,e,n)]})}),f=n.call(t,u,s);c=ui.permute(c,f),u=ui.permute(u,f);var d,h,p,g,v=r.call(t,u,s),m=c[0].length;for(p=0;m>p;++p)for(a.call(t,c[0][p],g=v[p],u[0][p][1]),h=1;d>h;++h)a.call(t,c[h][p],g+=u[h-1][p][1],u[h][p][1]);return l}var e=b,n=va,r=ma,a=ga,o=ha,i=pa;return t.values=function(n){return arguments.length?(e=n,t):e},t.order=function(e){return arguments.length?(n=\"function\"==typeof e?e:Ms.get(e)||va,t):n},t.offset=function(e){return arguments.length?(r=\"function\"==typeof e?e:As.get(e)||ma,t):r},t.x=function(e){return arguments.length?(o=e,t):o},t.y=function(e){return arguments.length?(i=e,t):i},t.out=function(e){return arguments.length?(a=e,t):a},t};var Ms=ui.map({\"inside-out\":function(t){var e,n,r=t.length,a=t.map(ya),o=t.map(xa),i=ui.range(r).sort(function(t,e){return a[t]-a[e]}),l=0,s=0,c=[],u=[];for(e=0;r>e;++e)n=i[e],s>l?(l+=o[n],c.push(n)):(s+=o[n],u.push(n));return u.reverse().concat(c)},reverse:function(t){return ui.range(t.length).reverse()},\"default\":va}),As=ui.map({silhouette:function(t){var e,n,r,a=t.length,o=t[0].length,i=[],l=0,s=[];for(n=0;o>n;++n){for(e=0,r=0;a>e;e++)r+=t[e][n][1];r>l&&(l=r),i.push(r)}for(n=0;o>n;++n)s[n]=(l-i[n])/2;return s},wiggle:function(t){var e,n,r,a,o,i,l,s,c,u=t.length,f=t[0],d=f.length,h=[];for(h[0]=s=c=0,n=1;d>n;++n){for(e=0,a=0;u>e;++e)a+=t[e][n][1];for(e=0,o=0,l=f[n][0]-f[n-1][0];u>e;++e){for(r=0,i=(t[e][n][1]-t[e][n-1][1])/(2*l);e>r;++r)i+=(t[r][n][1]-t[r][n-1][1])/l;o+=i*t[e][n][1]}h[n]=s-=a?o/a*l:0,c>s&&(c=s)}for(n=0;d>n;++n)h[n]-=c;return h},expand:function(t){var e,n,r,a=t.length,o=t[0].length,i=1/a,l=[];for(n=0;o>n;++n){for(e=0,r=0;a>e;e++)r+=t[e][n][1];if(r)for(e=0;a>e;e++)t[e][n][1]/=r;else for(e=0;a>e;e++)t[e][n][1]=i}for(n=0;o>n;++n)l[n]=0;return l},zero:ma});ui.layout.histogram=function(){function t(t,o){for(var i,l,s=[],c=t.map(n,this),u=r.call(this,c,o),f=a.call(this,u,c,o),o=-1,d=c.length,h=f.length-1,p=e?1:1/d;++o<h;)i=s[o]=[],i.dx=f[o+1]-(i.x=f[o]),i.y=0;if(h>0)for(o=-1;++o<d;)l=c[o],l>=u[0]&&l<=u[1]&&(i=s[ui.bisect(f,l,1,h)-1],i.y+=p,i.push(t[o]));return s}var e=!0,n=Number,r=ka,a=_a;return t.value=function(e){return arguments.length?(n=e,t):n},t.range=function(e){return arguments.length?(r=zt(e),t):r},t.bins=function(e){return arguments.length?(a=\"number\"==typeof e?function(t){return wa(t,e)}:zt(e),t):a},t.frequency=function(n){return arguments.length?(e=!!n,t):e},t},ui.layout.pack=function(){function t(t,o){var i=n.call(this,t,o),l=i[0],s=a[0],c=a[1],u=null==e?Math.sqrt:\"function\"==typeof e?e:function(){return e};if(l.x=l.y=0,sa(l,function(t){t.r=+u(t.value)}),sa(l,za),r){var f=r*(e?1:Math.max(2*l.r/s,2*l.r/c))/2;sa(l,function(t){t.r+=f}),sa(l,za),sa(l,function(t){t.r-=f})}return Ca(l,s/2,c/2,e?1:1/Math.max(2*l.r/s,2*l.r/c)),i}var e,n=ui.layout.hierarchy().sort(Ma),r=0,a=[1,1];return t.size=function(e){return arguments.length?(a=e,t):a},t.radius=function(n){return arguments.length?(e=null==n||\"function\"==typeof n?n:+n,t):e},t.padding=function(e){return arguments.length?(r=+e,t):r},ia(t,n)},ui.layout.tree=function(){function t(t,a){var u=i.call(this,t,a),f=u[0],d=e(f);if(sa(d,n),d.parent.m=-d.z,la(d,r),c)la(f,o);else{var h=f,p=f,g=f;la(f,function(t){t.x<h.x&&(h=t),t.x>p.x&&(p=t),t.depth>g.depth&&(g=t)});var v=l(h,p)/2-h.x,m=s[0]/(p.x+l(p,h)/2+v),y=s[1]/(g.depth||1);la(f,function(t){t.x=(t.x+v)*m,t.y=t.depth*y})}return u}function e(t){for(var e,n={A:null,children:[t]},r=[n];null!=(e=r.pop());)for(var a,o=e.children,i=0,l=o.length;l>i;++i)r.push((o[i]=a={_:o[i],parent:e,children:(a=o[i].children)&&a.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:i}).a=a);return n.children[0]}function n(t){var e=t.children,n=t.parent.children,r=t.i?n[t.i-1]:null;if(e.length){Ra(t);var o=(e[0].z+e[e.length-1].z)/2;r?(t.z=r.z+l(t._,r._),t.m=t.z-o):t.z=o}else r&&(t.z=r.z+l(t._,r._));t.parent.A=a(t,r,t.parent.A||n[0])}function r(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function a(t,e,n){if(e){for(var r,a=t,o=t,i=e,s=a.parent.children[0],c=a.m,u=o.m,f=i.m,d=s.m;i=Da(i),a=Na(a),i&&a;)s=Na(s),o=Da(o),o.a=t,r=i.z+f-a.z-c+l(i._,a._),r>0&&(Ia(ja(i,t,n),t,r),c+=r,u+=r),f+=i.m,c+=a.m,d+=s.m,u+=o.m;i&&!Da(o)&&(o.t=i,o.m+=f-u),a&&!Na(s)&&(s.t=a,s.m+=c-d,n=t)}return n}function o(t){t.x*=s[0],t.y=t.depth*s[1]}var i=ui.layout.hierarchy().sort(null).value(null),l=Pa,s=[1,1],c=null;return t.separation=function(e){return arguments.length?(l=e,t):l},t.size=function(e){return arguments.length?(c=null==(s=e)?o:null,t):c?null:s},t.nodeSize=function(e){return arguments.length?(c=null==(s=e)?null:o,t):c?s:null},ia(t,i)},ui.layout.cluster=function(){function t(t,o){var i,l=e.call(this,t,o),s=l[0],c=0;sa(s,function(t){var e=t.children;e&&e.length?(t.x=Fa(e),t.y=qa(e)):(t.x=i?c+=n(t,i):0,t.y=0,i=t)});var u=Ba(s),f=Ha(s),d=u.x-n(u,f)/2,h=f.x+n(f,u)/2;return sa(s,a?function(t){t.x=(t.x-s.x)*r[0],t.y=(s.y-t.y)*r[1]}:function(t){t.x=(t.x-d)/(h-d)*r[0],t.y=(1-(s.y?t.y/s.y:1))*r[1]}),l}var e=ui.layout.hierarchy().sort(null).value(null),n=Pa,r=[1,1],a=!1;return t.separation=function(e){return arguments.length?(n=e,t):n},t.size=function(e){return arguments.length?(a=null==(r=e),t):a?null:r},t.nodeSize=function(e){return arguments.length?(a=null!=(r=e),t):a?r:null},ia(t,e)},ui.layout.treemap=function(){function t(t,e){for(var n,r,a=-1,o=t.length;++a<o;)r=(n=t[a]).value*(0>e?0:e),n.area=isNaN(r)||0>=r?0:r}function e(n){var o=n.children;if(o&&o.length){var i,l,s,c=f(n),u=[],d=o.slice(),p=1/0,g=\"slice\"===h?c.dx:\"dice\"===h?c.dy:\"slice-dice\"===h?1&n.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(t(d,c.dx*c.dy/n.value),u.area=0;(s=d.length)>0;)u.push(i=d[s-1]),u.area+=i.area,\"squarify\"!==h||(l=r(u,g))<=p?(d.pop(),p=l):(u.area-=u.pop().area,a(u,g,c,!1),g=Math.min(c.dx,c.dy),u.length=u.area=0,p=1/0);u.length&&(a(u,g,c,!0),u.length=u.area=0),o.forEach(e)}}function n(e){var r=e.children;if(r&&r.length){var o,i=f(e),l=r.slice(),s=[];for(t(l,i.dx*i.dy/e.value),s.area=0;o=l.pop();)s.push(o),s.area+=o.area,null!=o.z&&(a(s,o.z?i.dx:i.dy,i,!l.length),s.length=s.area=0);r.forEach(n)}}function r(t,e){for(var n,r=t.area,a=0,o=1/0,i=-1,l=t.length;++i<l;)(n=t[i].area)&&(o>n&&(o=n),n>a&&(a=n));return r*=r,e*=e,r?Math.max(e*a*p/r,r/(e*o*p)):1/0}function a(t,e,n,r){var a,o=-1,i=t.length,l=n.x,c=n.y,u=e?s(t.area/e):0;if(e==n.dx){for((r||u>n.dy)&&(u=n.dy);++o<i;)a=t[o],a.x=l,a.y=c,a.dy=u,l+=a.dx=Math.min(n.x+n.dx-l,u?s(a.area/u):0);a.z=!0,a.dx+=n.x+n.dx-l,n.y+=u,n.dy-=u}else{for((r||u>n.dx)&&(u=n.dx);++o<i;)a=t[o],a.x=l,a.y=c,a.dx=u,c+=a.dy=Math.min(n.y+n.dy-c,u?s(a.area/u):0);a.z=!1,a.dy+=n.y+n.dy-c,n.x+=u,n.dx-=u}}function o(r){var a=i||l(r),o=a[0];return o.x=o.y=0,o.value?(o.dx=c[0],o.dy=c[1]):o.dx=o.dy=0,i&&l.revalue(o),t([o],o.dx*o.dy/o.value),(i?n:e)(o),d&&(i=a),a}var i,l=ui.layout.hierarchy(),s=Math.round,c=[1,1],u=null,f=Va,d=!1,h=\"squarify\",p=.5*(1+Math.sqrt(5));return o.size=function(t){return arguments.length?(c=t,o):c},o.padding=function(t){function e(e){var n=t.call(o,e,e.depth);return null==n?Va(e):Za(e,\"number\"==typeof n?[n,n,n,n]:n)}function n(e){return Za(e,t)}if(!arguments.length)return u;var r;return f=null==(u=t)?Va:\"function\"==(r=typeof t)?e:\"number\"===r?(t=[t,t,t,t],n):n,o},o.round=function(t){return arguments.length?(s=t?Math.round:Number,o):s!=Number},o.sticky=function(t){return arguments.length?(d=t,i=null,o):d},o.ratio=function(t){return arguments.length?(p=t,o):p},o.mode=function(t){return arguments.length?(h=t+\"\",o):h},ia(o,l)},ui.random={normal:function(t,e){var n=arguments.length;return 2>n&&(e=1),1>n&&(t=0),function(){var n,r,a;do n=2*Math.random()-1,r=2*Math.random()-1,a=n*n+r*r;while(!a||a>1);return t+e*n*Math.sqrt(-2*Math.log(a)/a)}},logNormal:function(){var t=ui.random.normal.apply(ui,arguments);return function(){return Math.exp(t())}},bates:function(t){var e=ui.random.irwinHall(t);return function(){return e()/t}},irwinHall:function(t){return function(){for(var e=0,n=0;t>n;n++)e+=Math.random();return e}}},ui.scale={};var Ls={floor:b,ceil:b};ui.scale.linear=function(){return Wa([0,1],[0,1],_r,!1)};var Ts={s:1,g:1,p:1,r:1,e:1};ui.scale.log=function(){return oo(ui.scale.linear().domain([0,1]),10,!0,[1,10])};var zs=ui.format(\".0e\"),Ss={floor:function(t){return-Math.ceil(-t)},ceil:function(t){return-Math.floor(-t)}};ui.scale.pow=function(){return io(ui.scale.linear(),1,[0,1])},ui.scale.sqrt=function(){return ui.scale.pow().exponent(.5)},ui.scale.ordinal=function(){return so([],{t:\"range\",a:[[]]})},ui.scale.category10=function(){return ui.scale.ordinal().range(Es)},ui.scale.category20=function(){return ui.scale.ordinal().range(Cs)},ui.scale.category20b=function(){return ui.scale.ordinal().range(Os)},ui.scale.category20c=function(){return ui.scale.ordinal().range(Ps)};var Es=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(_t),Cs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(_t),Os=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(_t),Ps=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(_t);ui.scale.quantile=function(){return co([],[])},ui.scal" -, -"e.quantize=function(){return uo(0,1,[0,1])},ui.scale.threshold=function(){return fo([.5],[0,1])},ui.scale.identity=function(){return ho([0,1])},ui.svg={},ui.svg.arc=function(){function t(){var t=Math.max(0,+n.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),u=i.apply(this,arguments)-Zi,f=l.apply(this,arguments)-Zi,d=Math.abs(f-u),h=u>f?0:1;if(t>c&&(p=c,c=t,t=p),d>=Vi)return e(c,h)+(t?e(t,1-h):\"\")+\"Z\";var p,g,v,m,y,x,b,_,w,k,M,A,L=0,T=0,z=[];if((m=(+s.apply(this,arguments)||0)/2)&&(v=o===Ns?Math.sqrt(t*t+c*c):+o.apply(this,arguments),h||(T*=-1),c&&(T=rt(v/c*Math.sin(m))),t&&(L=rt(v/t*Math.sin(m)))),c){y=c*Math.cos(u+T),x=c*Math.sin(u+T),b=c*Math.cos(f-T),_=c*Math.sin(f-T);var S=Math.abs(f-u-2*T)<=Bi?0:1;if(T&&bo(y,x,b,_)===h^S){var E=(u+f)/2;y=c*Math.cos(E),x=c*Math.sin(E),b=_=null}}else y=x=0;if(t){w=t*Math.cos(f-L),k=t*Math.sin(f-L),M=t*Math.cos(u+L),A=t*Math.sin(u+L);var C=Math.abs(u-f+2*L)<=Bi?0:1;if(L&&bo(w,k,M,A)===1-h^C){var O=(u+f)/2;w=t*Math.cos(O),k=t*Math.sin(O),M=A=null}}else w=k=0;if(d>qi&&(p=Math.min(Math.abs(c-t)/2,+a.apply(this,arguments)))>.001){g=c>t^h?0:1;var P=p,N=p;if(Bi>d){var D=null==M?[w,k]:null==b?[y,x]:In([y,x],[M,A],[b,_],[w,k]),I=y-D[0],R=x-D[1],j=b-D[0],q=_-D[1],F=1/Math.sin(Math.acos((I*j+R*q)/(Math.sqrt(I*I+R*R)*Math.sqrt(j*j+q*q)))/2),B=Math.sqrt(D[0]*D[0]+D[1]*D[1]);N=Math.min(p,(t-B)/(F-1)),P=Math.min(p,(c-B)/(F+1))}if(null!=b){var H=_o(null==M?[w,k]:[M,A],[y,x],c,P,h),V=_o([b,_],[w,k],c,P,h);p===P?z.push(\"M\",H[0],\"A\",P,\",\",P,\" 0 0,\",g,\" \",H[1],\"A\",c,\",\",c,\" 0 \",1-h^bo(H[1][0],H[1][1],V[1][0],V[1][1]),\",\",h,\" \",V[1],\"A\",P,\",\",P,\" 0 0,\",g,\" \",V[0]):z.push(\"M\",H[0],\"A\",P,\",\",P,\" 0 1,\",g,\" \",V[0])}else z.push(\"M\",y,\",\",x);if(null!=M){var Z=_o([y,x],[M,A],t,-N,h),Y=_o([w,k],null==b?[y,x]:[b,_],t,-N,h);p===N?z.push(\"L\",Y[0],\"A\",N,\",\",N,\" 0 0,\",g,\" \",Y[1],\"A\",t,\",\",t,\" 0 \",h^bo(Y[1][0],Y[1][1],Z[1][0],Z[1][1]),\",\",1-h,\" \",Z[1],\"A\",N,\",\",N,\" 0 0,\",g,\" \",Z[0]):z.push(\"L\",Y[0],\"A\",N,\",\",N,\" 0 0,\",g,\" \",Z[0])}else z.push(\"L\",w,\",\",k)}else z.push(\"M\",y,\",\",x),null!=b&&z.push(\"A\",c,\",\",c,\" 0 \",S,\",\",h,\" \",b,\",\",_),z.push(\"L\",w,\",\",k),null!=M&&z.push(\"A\",t,\",\",t,\" 0 \",C,\",\",1-h,\" \",M,\",\",A);return z.push(\"Z\"),z.join(\"\")}function e(t,e){return\"M0,\"+t+\"A\"+t+\",\"+t+\" 0 1,\"+e+\" 0,\"+-t+\"A\"+t+\",\"+t+\" 0 1,\"+e+\" 0,\"+t}var n=go,r=vo,a=po,o=Ns,i=mo,l=yo,s=xo;return t.innerRadius=function(e){return arguments.length?(n=zt(e),t):n},t.outerRadius=function(e){return arguments.length?(r=zt(e),t):r},t.cornerRadius=function(e){return arguments.length?(a=zt(e),t):a},t.padRadius=function(e){return arguments.length?(o=e==Ns?Ns:zt(e),t):o},t.startAngle=function(e){return arguments.length?(i=zt(e),t):i},t.endAngle=function(e){return arguments.length?(l=zt(e),t):l},t.padAngle=function(e){return arguments.length?(s=zt(e),t):s},t.centroid=function(){var t=(+n.apply(this,arguments)+ +r.apply(this,arguments))/2,e=(+i.apply(this,arguments)+ +l.apply(this,arguments))/2-Zi;return[Math.cos(e)*t,Math.sin(e)*t]},t};var Ns=\"auto\";ui.svg.line=function(){return wo(b)};var Ds=ui.map({linear:ko,\"linear-closed\":Mo,step:Ao,\"step-before\":Lo,\"step-after\":To,basis:Po,\"basis-open\":No,\"basis-closed\":Do,bundle:Io,cardinal:Eo,\"cardinal-open\":zo,\"cardinal-closed\":So,monotone:Ho});Ds.forEach(function(t,e){e.key=t,e.closed=/-closed$/.test(t)});var Is=[0,2/3,1/3,0],Rs=[0,1/3,2/3,0],js=[0,1/6,2/3,1/6];ui.svg.line.radial=function(){var t=wo(Vo);return t.radius=t.x,delete t.x,t.angle=t.y,delete t.y,t},Lo.reverse=To,To.reverse=Lo,ui.svg.area=function(){return Zo(b)},ui.svg.area.radial=function(){var t=Zo(Vo);return t.radius=t.x,delete t.x,t.innerRadius=t.x0,delete t.x0,t.outerRadius=t.x1,delete t.x1,t.angle=t.y,delete t.y,t.startAngle=t.y0,delete t.y0,t.endAngle=t.y1,delete t.y1,t},ui.svg.chord=function(){function t(t,l){var s=e(this,o,t,l),c=e(this,i,t,l);return\"M\"+s.p0+r(s.r,s.p1,s.a1-s.a0)+(n(s,c)?a(s.r,s.p1,s.r,s.p0):a(s.r,s.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+a(c.r,c.p1,s.r,s.p0))+\"Z\"}function e(t,e,n,r){var a=e.call(t,n,r),o=l.call(t,a,r),i=s.call(t,a,r)-Zi,u=c.call(t,a,r)-Zi;return{r:o,a0:i,a1:u,p0:[o*Math.cos(i),o*Math.sin(i)],p1:[o*Math.cos(u),o*Math.sin(u)]}}function n(t,e){return t.a0==e.a0&&t.a1==e.a1}function r(t,e,n){return\"A\"+t+\",\"+t+\" 0 \"+ +(n>Bi)+\",1 \"+e}function a(t,e,n,r){return\"Q 0,0 \"+r}var o=_n,i=wn,l=Yo,s=mo,c=yo;return t.radius=function(e){return arguments.length?(l=zt(e),t):l},t.source=function(e){return arguments.length?(o=zt(e),t):o},t.target=function(e){return arguments.length?(i=zt(e),t):i},t.startAngle=function(e){return arguments.length?(s=zt(e),t):s},t.endAngle=function(e){return arguments.length?(c=zt(e),t):c},t},ui.svg.diagonal=function(){function t(t,a){var o=e.call(this,t,a),i=n.call(this,t,a),l=(o.y+i.y)/2,s=[o,{x:o.x,y:l},{x:i.x,y:l},i];return s=s.map(r),\"M\"+s[0]+\"C\"+s[1]+\" \"+s[2]+\" \"+s[3]}var e=_n,n=wn,r=Uo;return t.source=function(n){return arguments.length?(e=zt(n),t):e},t.target=function(e){return arguments.length?(n=zt(e),t):n},t.projection=function(e){return arguments.length?(r=e,t):r},t},ui.svg.diagonal.radial=function(){var t=ui.svg.diagonal(),e=Uo,n=t.projection;return t.projection=function(t){return arguments.length?n(Xo(e=t)):e},t},ui.svg.symbol=function(){function t(t,r){return(qs.get(e.call(this,t,r))||Qo)(n.call(this,t,r))}var e=$o,n=Go;return t.type=function(n){return arguments.length?(e=zt(n),t):e},t.size=function(e){return arguments.length?(n=zt(e),t):n},t};var qs=ui.map({circle:Qo,cross:function(t){var e=Math.sqrt(t/5)/2;return\"M\"+-3*e+\",\"+-e+\"H\"+-e+\"V\"+-3*e+\"H\"+e+\"V\"+-e+\"H\"+3*e+\"V\"+e+\"H\"+e+\"V\"+3*e+\"H\"+-e+\"V\"+e+\"H\"+-3*e+\"Z\"},diamond:function(t){var e=Math.sqrt(t/(2*Bs)),n=e*Bs;return\"M0,\"+-e+\"L\"+n+\",0 0,\"+e+\" \"+-n+\",0Z\"},square:function(t){var e=Math.sqrt(t)/2;return\"M\"+-e+\",\"+-e+\"L\"+e+\",\"+-e+\" \"+e+\",\"+e+\" \"+-e+\",\"+e+\"Z\"},\"triangle-down\":function(t){var e=Math.sqrt(t/Fs),n=e*Fs/2;return\"M0,\"+n+\"L\"+e+\",\"+-n+\" \"+-e+\",\"+-n+\"Z\"},\"triangle-up\":function(t){var e=Math.sqrt(t/Fs),n=e*Fs/2;return\"M0,\"+-n+\"L\"+e+\",\"+n+\" \"+-e+\",\"+n+\"Z\"}});ui.svg.symbolTypes=qs.keys();var Fs=Math.sqrt(3),Bs=Math.tan(30*Yi);Ci.transition=function(t){for(var e,n,r=Hs||++Us,a=ei(t),o=[],i=Vs||{time:Date.now(),ease:zr,delay:0,duration:250},l=-1,s=this.length;++l<s;){o.push(e=[]);for(var c=this[l],u=-1,f=c.length;++u<f;)(n=c[u])&&ni(n,u,a,r,i),e.push(n)}return Jo(o,a,r)},Ci.interrupt=function(t){return this.each(null==t?Zs:Wo(ei(t)))};var Hs,Vs,Zs=Wo(ei()),Ys=[],Us=0;Ys.call=Ci.call,Ys.empty=Ci.empty,Ys.node=Ci.node,Ys.size=Ci.size,ui.transition=function(t,e){return t&&t.transition?Hs?t.transition(e):t:ui.selection().transition(t)},ui.transition.prototype=Ys,Ys.select=function(t){var e,n,r,a=this.id,o=this.namespace,i=[];t=E(t);for(var l=-1,s=this.length;++l<s;){i.push(e=[]);for(var c=this[l],u=-1,f=c.length;++u<f;)(r=c[u])&&(n=t.call(r,r.__data__,u,l))?(\"__data__\"in r&&(n.__data__=r.__data__),ni(n,u,o,a,r[o][a]),e.push(n)):e.push(null)}return Jo(i,o,a)},Ys.selectAll=function(t){var e,n,r,a,o,i=this.id,l=this.namespace,s=[];t=C(t);for(var c=-1,u=this.length;++c<u;)for(var f=this[c],d=-1,h=f.length;++d<h;)if(r=f[d]){o=r[l][i],n=t.call(r,r.__data__,d,c),s.push(e=[]);for(var p=-1,g=n.length;++p<g;)(a=n[p])&&ni(a,p,l,i,o),e.push(a)}return Jo(s,l,i)},Ys.filter=function(t){var e,n,r,a=[];\"function\"!=typeof t&&(t=V(t));for(var o=0,i=this.length;i>o;o++){a.push(e=[]);for(var n=this[o],l=0,s=n.length;s>l;l++)(r=n[l])&&t.call(r,r.__data__,l,o)&&e.push(r)}return Jo(a,this.namespace,this.id)},Ys.tween=function(t,e){var n=this.id,r=this.namespace;return arguments.length<2?this.node()[r][n].tween.get(t):Y(this,null==e?function(e){e[r][n].tween.remove(t)}:function(a){a[r][n].tween.set(t,e)})},Ys.attr=function(t,e){function n(){this.removeAttribute(l)}function r(){this.removeAttributeNS(l.space,l.local)}function a(t){return null==t?n:(t+=\"\",function(){var e,n=this.getAttribute(l);return n!==t&&(e=i(n,t),function(t){this.setAttribute(l,e(t))})})}function o(t){return null==t?r:(t+=\"\",function(){var e,n=this.getAttributeNS(l.space,l.local);return n!==t&&(e=i(n,t),function(t){this.setAttributeNS(l.space,l.local,e(t))})})}if(arguments.length<2){for(e in t)this.attr(e,t[e]);return this}var i=\"transform\"==t?$r:_r,l=ui.ns.qualify(t);return Ko(this,\"attr.\"+t,e,l.local?o:a)},Ys.attrTween=function(t,e){function n(t,n){var r=e.call(this,t,n,this.getAttribute(a));return r&&function(t){this.setAttribute(a,r(t))}}function r(t,n){var r=e.call(this,t,n,this.getAttributeNS(a.space,a.local));return r&&function(t){this.setAttributeNS(a.space,a.local,r(t))}}var a=ui.ns.qualify(t);return this.tween(\"attr.\"+t,a.local?r:n)},Ys.style=function(t,e,n){function a(){this.style.removeProperty(t)}function o(e){return null==e?a:(e+=\"\",function(){var a,o=r(this).getComputedStyle(this,null).getPropertyValue(t);return o!==e&&(a=_r(o,e),function(e){this.style.setProperty(t,a(e),n)})})}var i=arguments.length;if(3>i){if(\"string\"!=typeof t){2>i&&(e=\"\");for(n in t)this.style(n,t[n],e);return this}n=\"\"}return Ko(this,\"style.\"+t,e,o)},Ys.styleTween=function(t,e,n){function a(a,o){var i=e.call(this,a,o,r(this).getComputedStyle(this,null).getPropertyValue(t));return i&&function(e){this.style.setProperty(t,i(e),n)}}return arguments.length<3&&(n=\"\"),this.tween(\"style.\"+t,a)},Ys.text=function(t){return Ko(this,\"text\",t,ti)},Ys.remove=function(){var t=this.namespace;return this.each(\"end.transition\",function(){var e;this[t].count<2&&(e=this.parentNode)&&e.removeChild(this)})},Ys.ease=function(t){var e=this.id,n=this.namespace;return arguments.length<1?this.node()[n][e].ease:(\"function\"!=typeof t&&(t=ui.ease.apply(ui,arguments)),Y(this,function(r){r[n][e].ease=t}))},Ys.delay=function(t){var e=this.id,n=this.namespace;return arguments.length<1?this.node()[n][e].delay:Y(this,\"function\"==typeof t?function(r,a,o){r[n][e].delay=+t.call(r,r.__data__,a,o)}:(t=+t,function(r){r[n][e].delay=t}))},Ys.duration=function(t){var e=this.id,n=this.namespace;return arguments.length<1?this.node()[n][e].duration:Y(this,\"function\"==typeof t?function(r,a,o){r[n][e].duration=Math.max(1,t.call(r,r.__" -, -"data__,a,o))}:(t=Math.max(1,t),function(r){r[n][e].duration=t}))},Ys.each=function(t,e){var n=this.id,r=this.namespace;if(arguments.length<2){var a=Vs,o=Hs;try{Hs=n,Y(this,function(e,a,o){Vs=e[r][n],t.call(e,e.__data__,a,o)})}finally{Vs=a,Hs=o}}else Y(this,function(a){var o=a[r][n];(o.event||(o.event=ui.dispatch(\"start\",\"end\",\"interrupt\"))).on(t,e)});return this},Ys.transition=function(){for(var t,e,n,r,a=this.id,o=++Us,i=this.namespace,l=[],s=0,c=this.length;c>s;s++){l.push(t=[]);for(var e=this[s],u=0,f=e.length;f>u;u++)(n=e[u])&&(r=n[i][a],ni(n,u,i,o,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),t.push(n)}return Jo(l,i,o)},ui.svg.axis=function(){function t(t){t.each(function(){var t,c=ui.select(this),u=this.__chart__||n,f=this.__chart__=n.copy(),d=null==s?f.ticks?f.ticks.apply(f,l):f.domain():s,h=null==e?f.tickFormat?f.tickFormat.apply(f,l):b:e,p=c.selectAll(\".tick\").data(d,f),g=p.enter().insert(\"g\",\".domain\").attr(\"class\",\"tick\").style(\"opacity\",qi),v=ui.transition(p.exit()).style(\"opacity\",qi).remove(),m=ui.transition(p.order()).style(\"opacity\",1),y=Math.max(a,0)+i,x=Ua(f),_=c.selectAll(\".domain\").data([0]),w=(_.enter().append(\"path\").attr(\"class\",\"domain\"),ui.transition(_));g.append(\"line\"),g.append(\"text\");var k,M,A,L,T=g.select(\"line\"),z=m.select(\"line\"),S=p.select(\"text\").text(h),E=g.select(\"text\"),C=m.select(\"text\"),O=\"top\"===r||\"left\"===r?-1:1;if(\"bottom\"===r||\"top\"===r?(t=ri,k=\"x\",A=\"y\",M=\"x2\",L=\"y2\",S.attr(\"dy\",0>O?\"0em\":\".71em\").style(\"text-anchor\",\"middle\"),w.attr(\"d\",\"M\"+x[0]+\",\"+O*o+\"V0H\"+x[1]+\"V\"+O*o)):(t=ai,k=\"y\",A=\"x\",M=\"y2\",L=\"x2\",S.attr(\"dy\",\".32em\").style(\"text-anchor\",0>O?\"end\":\"start\"),w.attr(\"d\",\"M\"+O*o+\",\"+x[0]+\"H0V\"+x[1]+\"H\"+O*o)),T.attr(L,O*a),E.attr(A,O*y),z.attr(M,0).attr(L,O*a),C.attr(k,0).attr(A,O*y),f.rangeBand){var P=f,N=P.rangeBand()/2;u=f=function(t){return P(t)+N}}else u.rangeBand?u=f:v.call(t,f,u);g.call(t,u,f),m.call(t,f,f)})}var e,n=ui.scale.linear(),r=Xs,a=6,o=6,i=3,l=[10],s=null;return t.scale=function(e){\n" -, -"return arguments.length?(n=e,t):n},t.orient=function(e){return arguments.length?(r=e in Gs?e+\"\":Xs,t):r},t.ticks=function(){return arguments.length?(l=di(arguments),t):l},t.tickValues=function(e){return arguments.length?(s=e,t):s},t.tickFormat=function(n){return arguments.length?(e=n,t):e},t.tickSize=function(e){var n=arguments.length;return n?(a=+e,o=+arguments[n-1],t):a},t.innerTickSize=function(e){return arguments.length?(a=+e,t):a},t.outerTickSize=function(e){return arguments.length?(o=+e,t):o},t.tickPadding=function(e){return arguments.length?(i=+e,t):i},t.tickSubdivide=function(){return arguments.length&&t},t};var Xs=\"bottom\",Gs={top:1,right:1,bottom:1,left:1};ui.svg.brush=function(){function t(r){r.each(function(){var r=ui.select(this).style(\"pointer-events\",\"all\").style(\"-webkit-tap-highlight-color\",\"rgba(0,0,0,0)\").on(\"mousedown.brush\",o).on(\"touchstart.brush\",o),i=r.selectAll(\".background\").data([0]);i.enter().append(\"rect\").attr(\"class\",\"background\").style(\"visibility\",\"hidden\").style(\"cursor\",\"crosshair\"),r.selectAll(\".extent\").data([0]).enter().append(\"rect\").attr(\"class\",\"extent\").style(\"cursor\",\"move\");var l=r.selectAll(\".resize\").data(g,b);l.exit().remove(),l.enter().append(\"g\").attr(\"class\",function(t){return\"resize \"+t}).style(\"cursor\",function(t){return $s[t]}).append(\"rect\").attr(\"x\",function(t){return/[ew]$/.test(t)?-3:null}).attr(\"y\",function(t){return/^[ns]/.test(t)?-3:null}).attr(\"width\",6).attr(\"height\",6).style(\"visibility\",\"hidden\"),l.style(\"display\",t.empty()?\"none\":null);var s,f=ui.transition(r),d=ui.transition(i);c&&(s=Ua(c),d.attr(\"x\",s[0]).attr(\"width\",s[1]-s[0]),n(f)),u&&(s=Ua(u),d.attr(\"y\",s[0]).attr(\"height\",s[1]-s[0]),a(f)),e(f)})}function e(t){t.selectAll(\".resize\").attr(\"transform\",function(t){return\"translate(\"+f[+/e$/.test(t)]+\",\"+d[+/^s/.test(t)]+\")\"})}function n(t){t.select(\".extent\").attr(\"x\",f[0]),t.selectAll(\".extent,.n>rect,.s>rect\").attr(\"width\",f[1]-f[0])}function a(t){t.select(\".extent\").attr(\"y\",d[0]),t.selectAll(\".extent,.e>rect,.w>rect\").attr(\"height\",d[1]-d[0])}function o(){function o(){32==ui.event.keyCode&&(S||(x=null,C[0]-=f[1],C[1]-=d[1],S=2),L())}function g(){32==ui.event.keyCode&&2==S&&(C[0]+=f[1],C[1]+=d[1],S=0,L())}function v(){var t=ui.mouse(_),r=!1;b&&(t[0]+=b[0],t[1]+=b[1]),S||(ui.event.altKey?(x||(x=[(f[0]+f[1])/2,(d[0]+d[1])/2]),C[0]=f[+(t[0]<x[0])],C[1]=d[+(t[1]<x[1])]):x=null),T&&m(t,c,0)&&(n(M),r=!0),z&&m(t,u,1)&&(a(M),r=!0),r&&(e(M),k({type:\"brush\",mode:S?\"move\":\"resize\"}))}function m(t,e,n){var r,a,o=Ua(e),s=o[0],c=o[1],u=C[n],g=n?d:f,v=g[1]-g[0];return S&&(s-=u,c-=v+u),r=(n?p:h)?Math.max(s,Math.min(c,t[n])):t[n],S?a=(r+=u)+v:(x&&(u=Math.max(s,Math.min(c,2*x[n]-r))),r>u?(a=r,r=u):a=u),g[0]!=r||g[1]!=a?(n?l=null:i=null,g[0]=r,g[1]=a,!0):void 0}function y(){v(),M.style(\"pointer-events\",\"all\").selectAll(\".resize\").style(\"display\",t.empty()?\"none\":null),ui.select(\"body\").style(\"cursor\",null),O.on(\"mousemove.brush\",null).on(\"mouseup.brush\",null).on(\"touchmove.brush\",null).on(\"touchend.brush\",null).on(\"keydown.brush\",null).on(\"keyup.brush\",null),E(),k({type:\"brushend\"})}var x,b,_=this,w=ui.select(ui.event.target),k=s.of(_,arguments),M=ui.select(_),A=w.datum(),T=!/^(n|s)$/.test(A)&&c,z=!/^(e|w)$/.test(A)&&u,S=w.classed(\"extent\"),E=W(_),C=ui.mouse(_),O=ui.select(r(_)).on(\"keydown.brush\",o).on(\"keyup.brush\",g);if(ui.event.changedTouches?O.on(\"touchmove.brush\",v).on(\"touchend.brush\",y):O.on(\"mousemove.brush\",v).on(\"mouseup.brush\",y),M.interrupt().selectAll(\"*\").interrupt(),S)C[0]=f[0]-C[0],C[1]=d[0]-C[1];else if(A){var P=+/w$/.test(A),N=+/^n/.test(A);b=[f[1-P]-C[0],d[1-N]-C[1]],C[0]=f[P],C[1]=d[N]}else ui.event.altKey&&(x=C.slice());M.style(\"pointer-events\",\"none\").selectAll(\".resize\").style(\"display\",null),ui.select(\"body\").style(\"cursor\",w.style(\"cursor\")),k({type:\"brushstart\"}),v()}var i,l,s=z(t,\"brushstart\",\"brush\",\"brushend\"),c=null,u=null,f=[0,0],d=[0,0],h=!0,p=!0,g=Qs[0];return t.event=function(t){t.each(function(){var t=s.of(this,arguments),e={x:f,y:d,i:i,j:l},n=this.__chart__||e;this.__chart__=e,Hs?ui.select(this).transition().each(\"start.brush\",function(){i=n.i,l=n.j,f=n.x,d=n.y,t({type:\"brushstart\"})}).tween(\"brush:brush\",function(){var n=wr(f,e.x),r=wr(d,e.y);return i=l=null,function(a){f=e.x=n(a),d=e.y=r(a),t({type:\"brush\",mode:\"resize\"})}}).each(\"end.brush\",function(){i=e.i,l=e.j,t({type:\"brush\",mode:\"resize\"}),t({type:\"brushend\"})}):(t({type:\"brushstart\"}),t({type:\"brush\",mode:\"resize\"}),t({type:\"brushend\"}))})},t.x=function(e){return arguments.length?(c=e,g=Qs[!c<<1|!u],t):c},t.y=function(e){return arguments.length?(u=e,g=Qs[!c<<1|!u],t):u},t.clamp=function(e){return arguments.length?(c&&u?(h=!!e[0],p=!!e[1]):c?h=!!e:u&&(p=!!e),t):c&&u?[h,p]:c?h:u?p:null},t.extent=function(e){var n,r,a,o,s;return arguments.length?(c&&(n=e[0],r=e[1],u&&(n=n[0],r=r[0]),i=[n,r],c.invert&&(n=c(n),r=c(r)),n>r&&(s=n,n=r,r=s),n==f[0]&&r==f[1]||(f=[n,r])),u&&(a=e[0],o=e[1],c&&(a=a[1],o=o[1]),l=[a,o],u.invert&&(a=u(a),o=u(o)),a>o&&(s=a,a=o,o=s),a==d[0]&&o==d[1]||(d=[a,o])),t):(c&&(i?(n=i[0],r=i[1]):(n=f[0],r=f[1],c.invert&&(n=c.invert(n),r=c.invert(r)),n>r&&(s=n,n=r,r=s))),u&&(l?(a=l[0],o=l[1]):(a=d[0],o=d[1],u.invert&&(a=u.invert(a),o=u.invert(o)),a>o&&(s=a,a=o,o=s))),c&&u?[[n,a],[r,o]]:c?[n,r]:u&&[a,o])},t.clear=function(){return t.empty()||(f=[0,0],d=[0,0],i=l=null),t},t.empty=function(){return!!c&&f[0]==f[1]||!!u&&d[0]==d[1]},ui.rebind(t,s,\"on\")};var $s={n:\"ns-resize\",e:\"ew-resize\",s:\"ns-resize\",w:\"ew-resize\",nw:\"nwse-resize\",ne:\"nesw-resize\",se:\"nwse-resize\",sw:\"nesw-resize\"},Qs=[[\"n\",\"e\",\"s\",\"w\",\"nw\",\"ne\",\"se\",\"sw\"],[\"e\",\"w\"],[\"n\",\"s\"],[]],Ws=vl.format=wl.timeFormat,Js=Ws.utc,Ks=Js(\"%Y-%m-%dT%H:%M:%S.%LZ\");Ws.iso=Date.prototype.toISOString&&+new Date(\"2000-01-01T00:00:00.000Z\")?oi:Ks,oi.parse=function(t){var e=new Date(t);return isNaN(e)?null:e},oi.toString=Ks.toString,vl.second=Ht(function(t){return new ml(1e3*Math.floor(t/1e3))},function(t,e){t.setTime(t.getTime()+1e3*Math.floor(e))},function(t){return t.getSeconds()}),vl.seconds=vl.second.range,vl.seconds.utc=vl.second.utc.range,vl.minute=Ht(function(t){return new ml(6e4*Math.floor(t/6e4))},function(t,e){t.setTime(t.getTime()+6e4*Math.floor(e))},function(t){return t.getMinutes()}),vl.minutes=vl.minute.range,vl.minutes.utc=vl.minute.utc.range,vl.hour=Ht(function(t){var e=t.getTimezoneOffset()/60;return new ml(36e5*(Math.floor(t/36e5-e)+e))},function(t,e){t.setTime(t.getTime()+36e5*Math.floor(e))},function(t){return t.getHours()}),vl.hours=vl.hour.range,vl.hours.utc=vl.hour.utc.range,vl.month=Ht(function(t){return t=vl.day(t),t.setDate(1),t},function(t,e){t.setMonth(t.getMonth()+e)},function(t){return t.getMonth()}),vl.months=vl.month.range,vl.months.utc=vl.month.utc.range;var tc=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],ec=[[vl.second,1],[vl.second,5],[vl.second,15],[vl.second,30],[vl.minute,1],[vl.minute,5],[vl.minute,15],[vl.minute,30],[vl.hour,1],[vl.hour,3],[vl.hour,6],[vl.hour,12],[vl.day,1],[vl.day,2],[vl.week,1],[vl.month,1],[vl.month,3],[vl.year,1]],nc=Ws.multi([[\".%L\",function(t){return t.getMilliseconds()}],[\":%S\",function(t){return t.getSeconds()}],[\"%I:%M\",function(t){return t.getMinutes()}],[\"%I %p\",function(t){return t.getHours()}],[\"%a %d\",function(t){return t.getDay()&&1!=t.getDate()}],[\"%b %d\",function(t){return 1!=t.getDate()}],[\"%B\",function(t){return t.getMonth()}],[\"%Y\",Ce]]),rc={range:function(t,e,n){return ui.range(Math.ceil(t/n)*n,+e,n).map(li)},floor:b,ceil:b};ec.year=vl.year,vl.scale=function(){return ii(ui.scale.linear(),ec,nc)};var ac=ec.map(function(t){return[t[0].utc,t[1]]}),oc=Js.multi([[\".%L\",function(t){return t.getUTCMilliseconds()}],[\":%S\",function(t){return t.getUTCSeconds()}],[\"%I:%M\",function(t){return t.getUTCMinutes()}],[\"%I %p\",function(t){return t.getUTCHours()}],[\"%a %d\",function(t){return t.getUTCDay()&&1!=t.getUTCDate()}],[\"%b %d\",function(t){return 1!=t.getUTCDate()}],[\"%B\",function(t){return t.getUTCMonth()}],[\"%Y\",Ce]]);ac.year=vl.year.utc,vl.scale.utc=function(){return ii(ui.scale.linear(),ac,oc)},ui.text=St(function(t){return t.responseText}),ui.json=function(t,e){return Et(t,\"application/json\",si,e)},ui.html=function(t,e){return Et(t,\"text/html\",ci,e)},ui.xml=St(function(t){return t.responseXML}),\"function\"==typeof t&&t.amd?(this.d3=ui,t(ui)):\"object\"==typeof n&&n.exports?n.exports=ui:this.d3=ui}()},{}],10:[function(e,n,r){(function(r,a){(function(){\"use strict\";function o(t){return\"function\"==typeof t||\"object\"==typeof t&&null!==t}function i(t){return\"function\"==typeof t}function l(t){U=t}function s(t){Q=t}function c(){return function(){r.nextTick(p)}}function u(){return function(){Y(p)}}function f(){var t=0,e=new K(p),n=document.createTextNode(\"\");return e.observe(n,{characterData:!0}),function(){n.data=t=++t%2}}function d(){var t=new MessageChannel;return t.port1.onmessage=p,function(){t.port2.postMessage(0)}}function h(){return function(){setTimeout(p,1)}}function p(){for(var t=0;$>t;t+=2){var e=nt[t],n=nt[t+1];e(n),nt[t]=void 0,nt[t+1]=void 0}$=0}function g(){try{var t=e,n=t(\"vertx\");return Y=n.runOnLoop||n.runOnContext,u()}catch(r){return h()}}function v(t,e){var n=this,r=n._state;if(r===it&&!t||r===lt&&!e)return this;var a=new this.constructor(y),o=n._result;if(r){var i=arguments[r-1];Q(function(){N(r,a,i,o)})}else E(n,a,t,e);return a}function m(t){var e=this;if(t&&\"object\"==typeof t&&t.constructor===e)return t;var n=new e(y);return L(n,t),n}function y(){}function x(){return new TypeError(\"You cannot resolve a promise with itself\")}function b(){return new TypeError(\"A promises callback cannot return that same promise.\")}function _(t){try{return t.then}catch(e){return st.error=e,st}}function w(t,e,n,r){try{t.call(e,n,r)}catch(a){return a}}function k(t,e,n){Q(function(t){var r=!1,a=w(n,e,function(n){r||(r=!0,e!==n?L(t,n):z(t,n))},function(e){r||(r=!0,S(t,e))},\"Settle: \"+(t._label||\" unknown promise\"));!r&&a&&(r=!0,S(t,a))},t)}function M(t,e){e._state===it?z(t,e._result):e._state===lt?S(t," -, -"e._result):E(e,void 0,function(e){L(t,e)},function(e){S(t,e)})}function A(t,e,n){e.constructor===t.constructor&&n===rt&&constructor.resolve===at?M(t,e):n===st?S(t,st.error):void 0===n?z(t,e):i(n)?k(t,e,n):z(t,e)}function L(t,e){t===e?S(t,x()):o(e)?A(t,e,_(e)):z(t,e)}function T(t){t._onerror&&t._onerror(t._result),C(t)}function z(t,e){t._state===ot&&(t._result=e,t._state=it,0!==t._subscribers.length&&Q(C,t))}function S(t,e){t._state===ot&&(t._state=lt,t._result=e,Q(T,t))}function E(t,e,n,r){var a=t._subscribers,o=a.length;t._onerror=null,a[o]=e,a[o+it]=n,a[o+lt]=r,0===o&&t._state&&Q(C,t)}function C(t){var e=t._subscribers,n=t._state;if(0!==e.length){for(var r,a,o=t._result,i=0;i<e.length;i+=3)r=e[i],a=e[i+n],r?N(n,r,a,o):a(o);t._subscribers.length=0}}function O(){this.error=null}function P(t,e){try{return t(e)}catch(n){return ct.error=n,ct}}function N(t,e,n,r){var a,o,l,s,c=i(n);if(c){if(a=P(n,r),a===ct?(s=!0,o=a.error,a=null):l=!0,e===a)return void S(e,b())}else a=r,l=!0;e._state!==ot||(c&&l?L(e,a):s?S(e,o):t===it?z(e,a):t===lt&&S(e,a))}function D(t,e){try{e(function(e){L(t,e)},function(e){S(t,e)})}catch(n){S(t,n)}}function I(t){return new gt(this,t).promise}function R(t){function e(t){L(a,t)}function n(t){S(a,t)}var r=this,a=new r(y);if(!G(t))return S(a,new TypeError(\"You must pass an array to race.\")),a;for(var o=t.length,i=0;a._state===ot&&o>i;i++)E(r.resolve(t[i]),void 0,e,n);return a}function j(t){var e=this,n=new e(y);return S(n,t),n}function q(){throw new TypeError(\"You must pass a resolver function as the first argument to the promise constructor\")}function F(){throw new TypeError(\"Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.\")}function B(t){this._id=ht++,this._state=void 0,this._result=void 0,this._subscribers=[],y!==t&&(\"function\"!=typeof t&&q(),this instanceof B?D(this,t):F())}function H(t,e){this._instanceConstructor=t,this.promise=new t(y),Array.isArray(e)?(this._input=e,this.length=e.length,this._remaining=e.length,this._result=new Array(this.length),0===this.length?z(this.promise,this._result):(this.length=this.length||0,this._enumerate(),0===this._remaining&&z(this.promise,this._result))):S(this.promise,this._validationError())}function V(){var t;if(\"undefined\"!=typeof a)t=a;else if(\"undefined\"!=typeof self)t=self;else try{t=Function(\"return this\")()}catch(e){throw new Error(\"polyfill failed because global object is unavailable in this environment\")}var n=t.Promise;n&&\"[object Promise]\"===Object.prototype.toString.call(n.resolve())&&!n.cast||(t.Promise=pt)}var Z;Z=Array.isArray?Array.isArray:function(t){return\"[object Array]\"===Object.prototype.toString.call(t)};var Y,U,X,G=Z,$=0,Q=function(t,e){nt[$]=t,nt[$+1]=e,$+=2,2===$&&(U?U(p):X())},W=\"undefined\"!=typeof window?window:void 0,J=W||{},K=J.MutationObserver||J.WebKitMutationObserver,tt=\"undefined\"!=typeof r&&\"[object process]\"==={}.toString.call(r),et=\"undefined\"!=typeof Uint8ClampedArray&&\"undefined\"!=typeof importScripts&&\"undefined\"!=typeof MessageChannel,nt=new Array(1e3);X=tt?c():K?f():et?d():void 0===W&&\"function\"==typeof e?g():h();var rt=v,at=m,ot=void 0,it=1,lt=2,st=new O,ct=new O,ut=I,ft=R,dt=j,ht=0,pt=B;B.all=ut,B.race=ft,B.resolve=at,B.reject=dt,B._setScheduler=l,B._setAsap=s,B._asap=Q,B.prototype={constructor:B,then:rt,\"catch\":function(t){return this.then(null,t)}};var gt=H;H.prototype._validationError=function(){return new Error(\"Array Methods must be provided an Array\")},H.prototype._enumerate=function(){for(var t=this.length,e=this._input,n=0;this._state===ot&&t>n;n++)this._eachEntry(e[n],n)},H.prototype._eachEntry=function(t,e){var n=this._instanceConstructor,r=n.resolve;if(r===at){var a=_(t);if(a===rt&&t._state!==ot)this._settledAt(t._state,e,t._result);else if(\"function\"!=typeof a)this._remaining--,this._result[e]=t;else if(n===pt){var o=new n(y);A(o,t,a),this._willSettleAt(o,e)}else this._willSettleAt(new n(function(e){e(t)}),e)}else this._willSettleAt(r(t),e)},H.prototype._settledAt=function(t,e,n){var r=this.promise;r._state===ot&&(this._remaining--,t===lt?S(r,n):this._result[e]=n),0===this._remaining&&z(r,this._result)},H.prototype._willSettleAt=function(t,e){var n=this;E(t,void 0,function(t){n._settledAt(it,e,t)},function(t){n._settledAt(lt,e,t)})};var vt=V,mt={Promise:pt,polyfill:vt};\"function\"==typeof t&&t.amd?t(function(){return mt}):\"undefined\"!=typeof n&&n.exports?n.exports=mt:\"undefined\"!=typeof this&&(this.ES6Promise=mt),vt()}).call(this)}).call(this,e(\"_process\"),\"undefined\"!=typeof global?global:\"undefined\"!=typeof self?self:\"undefined\"!=typeof window?window:{})},{_process:8}],11:[function(t,e,n){\"use strict\";function r(t){for(var e,n=t.length,r=0;n>r;r++)if(e=t.charCodeAt(r),(9>e||e>13)&&32!==e&&133!==e&&160!==e&&5760!==e&&6158!==e&&(8192>e||e>8205)&&8232!==e&&8233!==e&&8239!==e&&8287!==e&&8288!==e&&12288!==e&&65279!==e)return!1;return!0}e.exports=function(t){var e=typeof t;if(\"string\"===e){var n=t;if(t=+t,0===t&&r(n))return!1}else if(\"number\"!==e)return!1;return 1>t-t}},{}],12:[function(t,e,n){function r(t,e){var n=e[0],r=e[1],a=e[2],o=e[3],i=n+n,l=r+r,s=a+a,c=n*i,u=r*i,f=r*l,d=a*i,h=a*l,p=a*s,g=o*i,v=o*l,m=o*s;return t[0]=1-f-p,t[1]=u+m,t[2]=d-v,t[3]=0,t[4]=u-m,t[5]=1-c-p,t[6]=h+g,t[7]=0,t[8]=d+v,t[9]=h-g,t[10]=1-c-f,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t}e.exports=r},{}],13:[function(e,n,r){!function(){function e(t,n){if(t=t?t:\"\",n=n||{},t instanceof e)return t;if(!(this instanceof e))return new e(t,n);var a=r(t);this._originalInput=t,this._r=a.r,this._g=a.g,this._b=a.b,this._a=a.a,this._roundA=B(100*this._a)/100,this._format=n.format||a.format,this._gradientType=n.gradientType,this._r<1&&(this._r=B(this._r)),this._g<1&&(this._g=B(this._g)),this._b<1&&(this._b=B(this._b)),this._ok=a.ok,this._tc_id=q++}function r(t){var e={r:0,g:0,b:0},n=1,r=!1,o=!1;return\"string\"==typeof t&&(t=D(t)),\"object\"==typeof t&&(t.hasOwnProperty(\"r\")&&t.hasOwnProperty(\"g\")&&t.hasOwnProperty(\"b\")?(e=a(t.r,t.g,t.b),r=!0,o=\"%\"===String(t.r).substr(-1)?\"prgb\":\"rgb\"):t.hasOwnProperty(\"h\")&&t.hasOwnProperty(\"s\")&&t.hasOwnProperty(\"v\")?(t.s=O(t.s),t.v=O(t.v),e=s(t.h,t.s,t.v),r=!0,o=\"hsv\"):t.hasOwnProperty(\"h\")&&t.hasOwnProperty(\"s\")&&t.hasOwnProperty(\"l\")&&(t.s=O(t.s),t.l=O(t.l),e=i(t.h,t.s,t.l),r=!0,o=\"hsl\"),t.hasOwnProperty(\"a\")&&(n=t.a)),n=A(n),{ok:r,format:t.format||o,r:H(255,V(e.r,0)),g:H(255,V(e.g,0)),b:H(255,V(e.b,0)),a:n}}function a(t,e,n){return{r:255*L(t,255),g:255*L(e,255),b:255*L(n,255)}}function o(t,e,n){t=L(t,255),e=L(e,255),n=L(n,255);var r,a,o=V(t,e,n),i=H(t,e,n),l=(o+i)/2;if(o==i)r=a=0;else{var s=o-i;switch(a=l>.5?s/(2-o-i):s/(o+i),o){case t:r=(e-n)/s+(n>e?6:0);break;case e:r=(n-t)/s+2;break;case n:r=(t-e)/s+4}r/=6}return{h:r,s:a,l:l}}function i(t,e,n){function r(t,e,n){return 0>n&&(n+=1),n>1&&(n-=1),1/6>n?t+6*(e-t)*n:.5>n?e:2/3>n?t+(e-t)*(2/3-n)*6:t}var a,o,i;if(t=L(t,360),e=L(e,100),n=L(n,100),0===e)a=o=i=n;else{var l=.5>n?n*(1+e):n+e-n*e,s=2*n-l;a=r(s,l,t+1/3),o=r(s,l,t),i=r(s,l,t-1/3)}return{r:255*a,g:255*o,b:255*i}}function l(t,e,n){t=L(t,255),e=L(e,255),n=L(n,255);var r,a,o=V(t,e,n),i=H(t,e,n),l=o,s=o-i;if(a=0===o?0:s/o,o==i)r=0;else{switch(o){case t:r=(e-n)/s+(n>e?6:0);break;case e:r=(n-t)/s+2;break;case n:r=(t-e)/s+4}r/=6}return{h:r,s:a,v:l}}function s(t,e,n){t=6*L(t,360),e=L(e,100),n=L(n,100);var r=F.floor(t),a=t-r,o=n*(1-e),i=n*(1-a*e),l=n*(1-(1-a)*e),s=r%6,c=[n,i,o,o,l,n][s],u=[l,n,n,i,o,o][s],f=[o,o,l,n,n,i][s];return{r:255*c,g:255*u,b:255*f}}function c(t,e,n,r){var a=[C(B(t).toString(16)),C(B(e).toString(16)),C(B(n).toString(16))];return r&&a[0].charAt(0)==a[0].charAt(1)&&a[1].charAt(0)==a[1].charAt(1)&&a[2].charAt(0)==a[2].charAt(1)?a[0].charAt(0)+a[1].charAt(0)+a[2].charAt(0):a.join(\"\")}function u(t,e,n,r){var a=[C(P(r)),C(B(t).toString(16)),C(B(e).toString(16)),C(B(n).toString(16))];return a.join(\"\")}function f(t,n){n=0===n?0:n||10;var r=e(t).toHsl();return r.s-=n/100,r.s=T(r.s),e(r)}function d(t,n){n=0===n?0:n||10;var r=e(t).toHsl();return r.s+=n/100,r.s=T(r.s),e(r)}function h(t){return e(t).desaturate(100)}function p(t,n){n=0===n?0:n||10;var r=e(t).toHsl();return r.l+=n/100,r.l=T(r.l),e(r)}function g(t,n){n=0===n?0:n||10;var r=e(t).toRgb();return r.r=V(0,H(255,r.r-B(255*-(n/100)))),r.g=V(0,H(255,r.g-B(255*-(n/100)))),r.b=V(0,H(255,r.b-B(255*-(n/100)))),e(r)}function v(t,n){n=0===n?0:n||10;var r=e(t).toHsl();return r.l-=n/100,r.l=T(r.l),e(r)}function m(t,n){var r=e(t).toHsl(),a=(B(r.h)+n)%360;return r.h=0>a?360+a:a,e(r)}function y(t){var n=e(t).toHsl();return n.h=(n.h+180)%360,e(n)}function x(t){var n=e(t).toHsl(),r=n.h;return[e(t),e({h:(r+120)%360,s:n.s,l:n.l}),e({h:(r+240)%360,s:n.s,l:n.l})]}function b(t){var n=e(t).toHsl(),r=n.h;return[e(t),e({h:(r+90)%360,s:n.s,l:n.l}),e({h:(r+180)%360,s:n.s,l:n.l}),e({h:(r+270)%360,s:n.s,l:n.l})]}function _(t){var n=e(t).toHsl(),r=n.h;return[e(t),e({h:(r+72)%360,s:n.s,l:n.l}),e({h:(r+216)%360,s:n.s,l:n.l})]}function w(t,n,r){n=n||6,r=r||30;var a=e(t).toHsl(),o=360/r,i=[e(t)];for(a.h=(a.h-(o*n>>1)+720)%360;--n;)a.h=(a.h+o)%360,i.push(e(a));return i}function k(t,n){n=n||6;for(var r=e(t).toHsv(),a=r.h,o=r.s,i=r.v,l=[],s=1/n;n--;)l.push(e({h:a,s:o,v:i})),i=(i+s)%1;return l}function M(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[t[n]]=n);return e}function A(t){return t=parseFloat(t),(isNaN(t)||0>t||t>1)&&(t=1),t}function L(t,e){S(t)&&(t=\"100%\");var n=E(t);return t=H(e,V(0,parseFloat(t))),n&&(t=parseInt(t*e,10)/100),F.abs(t-e)<1e-6?1:t%e/parseFloat(e)}function T(t){return H(1,V(0,t))}function z(t){return parseInt(t,16)}function S(t){return\"string\"==typeof t&&-1!=t.indexOf(\".\")&&1===parseFloat(t)}function E(t){return\"string\"==typeof t&&-1!=t.indexOf(\"%\")}function C(t){return 1==t.length?\"0\"+t:\"\"+t}function O(t){return 1>=t&&(t=100*t+\"%\"),t}function P(t){return Math.round(255*parseFloat(t)).toString(16)}function N(t){return z(t)/255}function D(t){t=t.replace(R,\"\").replace(j,\"\").toLowerCase();var e=!1;if(Y[t])t=Y[t],e=!0;else if(\"transparent\"==t)return{r:0,g:0,b:0,a:0,format:\"name\"};var n;return" -, -"(n=X.rgb.exec(t))?{r:n[1],g:n[2],b:n[3]}:(n=X.rgba.exec(t))?{r:n[1],g:n[2],b:n[3],a:n[4]}:(n=X.hsl.exec(t))?{h:n[1],s:n[2],l:n[3]}:(n=X.hsla.exec(t))?{h:n[1],s:n[2],l:n[3],a:n[4]}:(n=X.hsv.exec(t))?{h:n[1],s:n[2],v:n[3]}:(n=X.hsva.exec(t))?{h:n[1],s:n[2],v:n[3],a:n[4]}:(n=X.hex8.exec(t))?{a:N(n[1]),r:z(n[2]),g:z(n[3]),b:z(n[4]),format:e?\"name\":\"hex8\"}:(n=X.hex6.exec(t))?{r:z(n[1]),g:z(n[2]),b:z(n[3]),format:e?\"name\":\"hex\"}:(n=X.hex3.exec(t))?{r:z(n[1]+\"\"+n[1]),g:z(n[2]+\"\"+n[2]),b:z(n[3]+\"\"+n[3]),format:e?\"name\":\"hex\"}:!1}function I(t){var e,n;return t=t||{level:\"AA\",size:\"small\"},e=(t.level||\"AA\").toUpperCase(),n=(t.size||\"small\").toLowerCase(),\"AA\"!==e&&\"AAA\"!==e&&(e=\"AA\"),\"small\"!==n&&\"large\"!==n&&(n=\"small\"),{level:e,size:n}}var R=/^\\s+/,j=/\\s+$/,q=0,F=Math,B=F.round,H=F.min,V=F.max,Z=F.random;e.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var t=this.toRgb();return(299*t.r+587*t.g+114*t.b)/1e3},getLuminance:function(){var t,e,n,r,a,o,i=this.toRgb();return t=i.r/255,e=i.g/255,n=i.b/255,r=.03928>=t?t/12.92:Math.pow((t+.055)/1.055,2.4),a=.03928>=e?e/12.92:Math.pow((e+.055)/1.055,2.4),o=.03928>=n?n/12.92:Math.pow((n+.055)/1.055,2.4),.2126*r+.7152*a+.0722*o},setAlpha:function(t){return this._a=A(t),this._roundA=B(100*this._a)/100,this},toHsv:function(){var t=l(this._r,this._g,this._b);return{h:360*t.h,s:t.s,v:t.v,a:this._a}},toHsvString:function(){var t=l(this._r,this._g,this._b),e=B(360*t.h),n=B(100*t.s),r=B(100*t.v);return 1==this._a?\"hsv(\"+e+\", \"+n+\"%, \"+r+\"%)\":\"hsva(\"+e+\", \"+n+\"%, \"+r+\"%, \"+this._roundA+\")\"},toHsl:function(){var t=o(this._r,this._g,this._b);return{h:360*t.h,s:t.s,l:t.l,a:this._a}},toHslString:function(){var t=o(this._r,this._g,this._b),e=B(360*t.h),n=B(100*t.s),r=B(100*t.l);return 1==this._a?\"hsl(\"+e+\", \"+n+\"%, \"+r+\"%)\":\"hsla(\"+e+\", \"+n+\"%, \"+r+\"%, \"+this._roundA+\")\"},toHex:function(t){return c(this._r,this._g,this._b,t)},toHexString:function(t){return\"#\"+this.toHex(t)},toHex8:function(){return u(this._r,this._g,this._b,this._a)},toHex8String:function(){return\"#\"+this.toHex8()},toRgb:function(){return{r:B(this._r),g:B(this._g),b:B(this._b),a:this._a}},toRgbString:function(){return 1==this._a?\"rgb(\"+B(this._r)+\", \"+B(this._g)+\", \"+B(this._b)+\")\":\"rgba(\"+B(this._r)+\", \"+B(this._g)+\", \"+B(this._b)+\", \"+this._roundA+\")\"},toPercentageRgb:function(){return{r:B(100*L(this._r,255))+\"%\",g:B(100*L(this._g,255))+\"%\",b:B(100*L(this._b,255))+\"%\",a:this._a}},toPercentageRgbString:function(){return 1==this._a?\"rgb(\"+B(100*L(this._r,255))+\"%, \"+B(100*L(this._g,255))+\"%, \"+B(100*L(this._b,255))+\"%)\":\"rgba(\"+B(100*L(this._r,255))+\"%, \"+B(100*L(this._g,255))+\"%, \"+B(100*L(this._b,255))+\"%, \"+this._roundA+\")\"},toName:function(){return 0===this._a?\"transparent\":this._a<1?!1:U[c(this._r,this._g,this._b,!0)]||!1},toFilter:function(t){var n=\"#\"+u(this._r,this._g,this._b,this._a),r=n,a=this._gradientType?\"GradientType = 1, \":\"\";if(t){var o=e(t);r=o.toHex8String()}return\"progid:DXImageTransform.Microsoft.gradient(\"+a+\"startColorstr=\"+n+\",endColorstr=\"+r+\")\"},toString:function(t){var e=!!t;t=t||this._format;var n=!1,r=this._a<1&&this._a>=0,a=!e&&r&&(\"hex\"===t||\"hex6\"===t||\"hex3\"===t||\"name\"===t);return a?\"name\"===t&&0===this._a?this.toName():this.toRgbString():(\"rgb\"===t&&(n=this.toRgbString()),\"prgb\"===t&&(n=this.toPercentageRgbString()),\"hex\"!==t&&\"hex6\"!==t||(n=this.toHexString()),\"hex3\"===t&&(n=this.toHexString(!0)),\"hex8\"===t&&(n=this.toHex8String()),\"name\"===t&&(n=this.toName()),\"hsl\"===t&&(n=this.toHslString()),\"hsv\"===t&&(n=this.toHsvString()),n||this.toHexString())},clone:function(){return e(this.toString())},_applyModification:function(t,e){var n=t.apply(null,[this].concat([].slice.call(e)));return this._r=n._r,this._g=n._g,this._b=n._b,this.setAlpha(n._a),this},lighten:function(){return this._applyModification(p,arguments)},brighten:function(){return this._applyModification(g,arguments)},darken:function(){return this._applyModification(v,arguments)},desaturate:function(){return this._applyModification(f,arguments)},saturate:function(){return this._applyModification(d,arguments)},greyscale:function(){return this._applyModification(h,arguments)},spin:function(){return this._applyModification(m,arguments)},_applyCombination:function(t,e){return t.apply(null,[this].concat([].slice.call(e)))},analogous:function(){return this._applyCombination(w,arguments)},complement:function(){return this._applyCombination(y,arguments)},monochromatic:function(){return this._applyCombination(k,arguments)},splitcomplement:function(){return this._applyCombination(_,arguments)},triad:function(){return this._applyCombination(x,arguments)},tetrad:function(){return this._applyCombination(b,arguments)}},e.fromRatio=function(t,n){if(\"object\"==typeof t){var r={};for(var a in t)t.hasOwnProperty(a)&&(\"a\"===a?r[a]=t[a]:r[a]=O(t[a]));t=r}return e(t,n)},e.equals=function(t,n){return t&&n?e(t).toRgbString()==e(n).toRgbString():!1},e.random=function(){return e.fromRatio({r:Z(),g:Z(),b:Z()})},e.mix=function(t,n,r){r=0===r?0:r||50;var a,o=e(t).toRgb(),i=e(n).toRgb(),l=r/100,s=2*l-1,c=i.a-o.a;a=s*c==-1?s:(s+c)/(1+s*c),a=(a+1)/2;var u=1-a,f={r:i.r*a+o.r*u,g:i.g*a+o.g*u,b:i.b*a+o.b*u,a:i.a*l+o.a*(1-l)};return e(f)},e.readability=function(t,n){var r=e(t),a=e(n);return(Math.max(r.getLuminance(),a.getLuminance())+.05)/(Math.min(r.getLuminance(),a.getLuminance())+.05)},e.isReadable=function(t,n,r){var a,o,i=e.readability(t,n);switch(o=!1,a=I(r),a.level+a.size){case\"AAsmall\":case\"AAAlarge\":o=i>=4.5;break;case\"AAlarge\":o=i>=3;break;case\"AAAsmall\":o=i>=7}return o},e.mostReadable=function(t,n,r){var a,o,i,l,s=null,c=0;r=r||{},o=r.includeFallbackColors,i=r.level,l=r.size;for(var u=0;u<n.length;u++)a=e.readability(t,n[u]),a>c&&(c=a,s=e(n[u]));return e.isReadable(t,s,{level:i,size:l})||!o?s:(r.includeFallbackColors=!1,e.mostReadable(t,[\"#fff\",\"#000\"],r))};var Y=e.names={aliceblue:\"f0f8ff\",antiquewhite:\"faebd7\",aqua:\"0ff\",aquamarine:\"7fffd4\",azure:\"f0ffff\",beige:\"f5f5dc\",bisque:\"ffe4c4\",black:\"000\",blanchedalmond:\"ffebcd\",blue:\"00f\",blueviolet:\"8a2be2\",brown:\"a52a2a\",burlywood:\"deb887\",burntsienna:\"ea7e5d\",cadetblue:\"5f9ea0\",chartreuse:\"7fff00\",chocolate:\"d2691e\",coral:\"ff7f50\",cornflowerblue:\"6495ed\",cornsilk:\"fff8dc\",crimson:\"dc143c\",cyan:\"0ff\",darkblue:\"00008b\",darkcyan:\"008b8b\",darkgoldenrod:\"b8860b\",darkgray:\"a9a9a9\",darkgreen:\"006400\",darkgrey:\"a9a9a9\",darkkhaki:\"bdb76b\",darkmagenta:\"8b008b\",darkolivegreen:\"556b2f\",darkorange:\"ff8c00\",darkorchid:\"9932cc\",darkred:\"8b0000\",darksalmon:\"e9967a\",darkseagreen:\"8fbc8f\",darkslateblue:\"483d8b\",darkslategray:\"2f4f4f\",darkslategrey:\"2f4f4f\",darkturquoise:\"00ced1\",darkviolet:\"9400d3\",deeppink:\"ff1493\",deepskyblue:\"00bfff\",dimgray:\"696969\",dimgrey:\"696969\",dodgerblue:\"1e90ff\",firebrick:\"b22222\",floralwhite:\"fffaf0\",forestgreen:\"228b22\",fuchsia:\"f0f\",gainsboro:\"dcdcdc\",ghostwhite:\"f8f8ff\",gold:\"ffd700\",goldenrod:\"daa520\",gray:\"808080\",green:\"008000\",greenyellow:\"adff2f\",grey:\"808080\",honeydew:\"f0fff0\",hotpink:\"ff69b4\",indianred:\"cd5c5c\",indigo:\"4b0082\",ivory:\"fffff0\",khaki:\"f0e68c\",lavender:\"e6e6fa\",lavenderblush:\"fff0f5\",lawngreen:\"7cfc00\",lemonchiffon:\"fffacd\",lightblue:\"add8e6\",lightcoral:\"f08080\",lightcyan:\"e0ffff\",lightgoldenrodyellow:\"fafad2\",lightgray:\"d3d3d3\",lightgreen:\"90ee90\",lightgrey:\"d3d3d3\",lightpink:\"ffb6c1\",lightsalmon:\"ffa07a\",lightseagreen:\"20b2aa\",lightskyblue:\"87cefa\",lightslategray:\"789\",lightslategrey:\"789\",lightsteelblue:\"b0c4de\",lightyellow:\"ffffe0\",lime:\"0f0\",limegreen:\"32cd32\",linen:\"faf0e6\",magenta:\"f0f\",maroon:\"800000\",mediumaquamarine:\"66cdaa\",mediumblue:\"0000cd\",mediumorchid:\"ba55d3\",mediumpurple:\"9370db\",mediumseagreen:\"3cb371\",mediumslateblue:\"7b68ee\",mediumspringgreen:\"00fa9a\",mediumturquoise:\"48d1cc\",mediumvioletred:\"c71585\",midnightblue:\"191970\",mintcream:\"f5fffa\",mistyrose:\"ffe4e1\",moccasin:\"ffe4b5\",navajowhite:\"ffdead\",navy:\"000080\",oldlace:\"fdf5e6\",olive:\"808000\",olivedrab:\"6b8e23\",orange:\"ffa500\",orangered:\"ff4500\",orchid:\"da70d6\",palegoldenrod:\"eee8aa\",palegreen:\"98fb98\",paleturquoise:\"afeeee\",palevioletred:\"db7093\",papayawhip:\"ffefd5\",peachpuff:\"ffdab9\",peru:\"cd853f\",pink:\"ffc0cb\",plum:\"dda0dd\",powderblue:\"b0e0e6\",purple:\"800080\",rebeccapurple:\"663399\",red:\"f00\",rosybrown:\"bc8f8f\",royalblue:\"4169e1\",saddlebrown:\"8b4513\",salmon:\"fa8072\",sandybrown:\"f4a460\",seagreen:\"2e8b57\",seashell:\"fff5ee\",sienna:\"a0522d\",silver:\"c0c0c0\",skyblue:\"87ceeb\",slateblue:\"6a5acd\",slategray:\"708090\",slategrey:\"708090\",snow:\"fffafa\",springgreen:\"00ff7f\",steelblue:\"4682b4\",tan:\"d2b48c\",teal:\"008080\",thistle:\"d8bfd8\",tomato:\"ff6347\",turquoise:\"40e0d0\",violet:\"ee82ee\",wheat:\"f5deb3\",white:\"fff\",whitesmoke:\"f5f5f5\",yellow:\"ff0\",yellowgreen:\"9acd32\"},U=e.hexNames=M(Y),X=function(){var t=\"[-\\\\+]?\\\\d+%?\",e=\"[-\\\\+]?\\\\d*\\\\.\\\\d+%?\",n=\"(?:\"+e+\")|(?:\"+t+\")\",r=\"[\\\\s|\\\\(]+(\"+n+\")[,|\\\\s]+(\"+n+\")[,|\\\\s]+(\"+n+\")\\\\s*\\\\)?\",a=\"[\\\\s|\\\\(]+(\"+n+\")[,|\\\\s]+(\"+n+\")[,|\\\\s]+(\"+n+\")[,|\\\\s]+(\"+n+\")\\\\s*\\\\)?\";return{rgb:new RegExp(\"rgb\"+r),rgba:new RegExp(\"rgba\"+a),hsl:new RegExp(\"hsl\"+r),hsla:new RegExp(\"hsla\"+a),hsv:new RegExp(\"hsv\"+r),hsva:new RegExp(\"hsva\"+a),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/}}();\"undefined\"!=typeof n&&n.exports?n.exports=e:\"function\"==typeof t&&t.amd?t(function(){return e}):window.tinycolor=e}()},{}],14:[function(t,e,n){\"use strict\";e.exports=[\"\",{path:\"M-2.4,-3V3L0.6,0Z\",backoff:.6},{path:\"M-3.7,-2.5V2.5L1.3,0Z\",backoff:1.3},{path:\"M-4.45,-3L-1.65,-0.2V0.2L-4.45,3L1.55,0Z\",backoff:1.55},{path:\"M-2.2,-2.2L-0.2,-0.2V0.2L-2.2,2.2L-1.4,3L1.6,0L-1.4,-3Z\",backoff:1.6},{path:\"M-4.4,-2.1L-0.6,-0.2V0.2L-4.4,2.1L-4,3L2,0L-4,-3Z\",backoff:2},{path:\"M2,0A2,2 0 1,1 0,-2A2,2 0 0,1 2,0Z\",backoff:0},{path:\"M2,2V-2H-2V2Z" -, -"\",backoff:0}]},{}],15:[function(t,e,n){\"use strict\";var r=t(\"./arrow_paths\"),a=t(\"../../plots/font_attributes\"),o=t(\"../../plots/cartesian/constants\"),i=t(\"../../lib/extend\").extendFlat;e.exports={_isLinkedToArray:!0,text:{valType:\"string\"},textangle:{valType:\"angle\",dflt:0},font:i({},a,{}),opacity:{valType:\"number\",min:0,max:1,dflt:1},align:{valType:\"enumerated\",values:[\"left\",\"center\",\"right\"],dflt:\"center\"},bgcolor:{valType:\"color\",dflt:\"rgba(0,0,0,0)\"},bordercolor:{valType:\"color\",dflt:\"rgba(0,0,0,0)\"},borderpad:{valType:\"number\",min:0,dflt:1},borderwidth:{valType:\"number\",min:0,dflt:1},showarrow:{valType:\"boolean\",dflt:!0},arrowcolor:{valType:\"color\"},arrowhead:{valType:\"integer\",min:0,max:r.length,dflt:1},arrowsize:{valType:\"number\",min:.3,dflt:1},arrowwidth:{valType:\"number\",min:.1},ax:{valType:\"number\",dflt:-10},ay:{valType:\"number\",dflt:-30},axref:{valType:\"enumerated\",dflt:\"pixel\",values:[\"pixel\",o.idRegex.x.toString()]},ayref:{valType:\"enumerated\",dflt:\"pixel\",values:[\"pixel\",o.idRegex.y.toString()]},xref:{valType:\"enumerated\",values:[\"paper\",o.idRegex.x.toString()]},x:{valType:\"number\"},xanchor:{valType:\"enumerated\",values:[\"auto\",\"left\",\"center\",\"right\"],dflt:\"auto\"},yref:{valType:\"enumerated\",values:[\"paper\",o.idRegex.y.toString()]},y:{valType:\"number\"},yanchor:{valType:\"enumerated\",values:[\"auto\",\"top\",\"middle\",\"bottom\"],dflt:\"auto\"},_deprecated:{ref:{valType:\"string\"}}}},{\"../../lib/extend\":88,\"../../plots/cartesian/constants\":115,\"../../plots/font_attributes\":128,\"./arrow_paths\":14}],16:[function(t,e,n){\"use strict\";function r(t,e){function n(e,n){return c.coerce(t,r,v.layoutAttributes,e,n)}var r={};n(\"opacity\"),n(\"align\"),n(\"bgcolor\");var a=n(\"bordercolor\"),o=f.opacity(a);n(\"borderpad\");var i=n(\"borderwidth\"),l=n(\"showarrow\");l&&(n(\"arrowcolor\",o?r.bordercolor:f.defaultLine),n(\"arrowhead\"),n(\"arrowsize\"),n(\"arrowwidth\",2*(o&&i||1)),n(\"ax\"),n(\"ay\"),n(\"axref\"),n(\"ayref\"),c.noneOrAll(t,r,[\"ax\",\"ay\"])),n(\"text\",l?\" \":\"new text\"),n(\"textangle\"),c.coerceFont(n,\"font\",e.font);\n" -, -"for(var s=[\"x\",\"y\"],d=0;2>d;d++){var h=s[d],p={_fullLayout:e},g=u.coerceRef(t,r,p,h),m=u.coerceARef(t,r,p,h),y=.5;if(\"paper\"!==g){var x=u.getFromId(p,g);if(y=x.range[0]+y*(x.range[1]-x.range[0]),-1!==[\"date\",\"category\"].indexOf(x.type)&&\"string\"==typeof t[h]){var b;if(\"date\"===x.type){if(b=c.dateTime2ms(t[h]),b!==!1&&(t[h]=b),m===g){var _=c.dateTime2ms(t[\"a\"+h]);_!==!1&&(t[\"a\"+h]=_)}}else(x._categories||[]).length&&(b=x._categories.indexOf(t[h]),-1!==b&&(t[h]=b))}}n(h,y),l||n(h+\"anchor\")}return c.noneOrAll(t,r,[\"x\",\"y\"]),r}function a(t){var e=t._fullLayout;e.annotations.forEach(function(e){var n=u.getFromId(t,e.xref),r=u.getFromId(t,e.yref);if(n||r){var a=(e._xsize||0)/2,o=e._xshift||0,i=(e._ysize||0)/2,l=e._yshift||0,s=a-o,c=a+o,f=i-l,d=i+l;if(e.showarrow){var h=3*e.arrowsize*e.arrowwidth;s=Math.max(s,h),c=Math.max(c,h),f=Math.max(f,h),d=Math.max(d,h)}n&&n.autorange&&u.expand(n,[n.l2c(e.x)],{ppadplus:c,ppadminus:s}),r&&r.autorange&&u.expand(r,[r.l2c(e.y)],{ppadplus:d,ppadminus:f})}})}function o(t,e,n,r,a,o,i,l){var s=n-t,c=a-t,u=i-a,f=r-e,d=o-e,h=l-o,p=s*h-u*f;if(0===p)return null;var g=(c*h-u*d)/p,v=(c*f-s*d)/p;return 0>v||v>1||0>g||g>1?null:{x:t+s*g,y:e+f*g}}var i=t(\"d3\"),l=t(\"fast-isnumeric\"),s=t(\"../../plotly\"),c=t(\"../../lib\"),u=t(\"../../plots/cartesian/axes\"),f=t(\"../color\"),d=t(\"../drawing\"),h=t(\"../../lib/svg_text_utils\"),p=t(\"../../lib/setcursor\"),g=t(\"../dragelement\"),v=e.exports={};v.ARROWPATHS=t(\"./arrow_paths\"),v.layoutAttributes=t(\"./attributes\"),v.supplyLayoutDefaults=function(t,e){for(var n=t.annotations||[],a=e.annotations=[],o=0;o<n.length;o++)a.push(r(n[o]||{},e))},v.drawAll=function(t){var e=t._fullLayout;e._infolayer.selectAll(\".annotation\").remove();for(var n=0;n<e.annotations.length;n++)v.draw(t,n);return s.Plots.previousPromises(t)},v.add=function(t){var e=t._fullLayout.annotations.length;s.relayout(t,\"annotations[\"+e+\"]\",\"add\")},v.draw=function(t,e,n,a){function m(t){return t.call(d.font,K).attr({\"text-anchor\":{left:\"start\",right:\"end\"}[B.align]||\"middle\"}),h.convertToTspans(t,y),t}function y(){function n(t,e){return\"auto\"===e&&(e=1/3>t?\"left\":t>2/3?\"right\":\"center\"),{center:0,middle:0,left:.5,bottom:-.5,right:-.5,top:.5}[e]}tt.selectAll(\"tspan.line\").attr({y:0,x:0});var r=G.select(\".annotation-math-group\"),a=!r.empty(),l=d.bBox((a?r:tt).node()),h=l.width,m=l.height,y=Math.round(h+2*W),x=Math.round(m+2*W);B._w=h,B._h=m;var b=!1;if([\"x\",\"y\"].forEach(function(e){var r,a=B[e+\"ref\"]||e,o=u.getFromId(t,a),i=(Y+(\"x\"===e?0:90))*Math.PI/180,l=y*Math.abs(Math.cos(i))+x*Math.abs(Math.sin(i)),s=B[e+\"anchor\"];if(o){if(!o.autorange&&(B[e]-o.range[0])*(B[e]-o.range[1])>0&&(B[\"a\"+e+\"ref\"]===a?(B[\"a\"+e]-o.range[0])*(B[\"a\"+e]-o.range[1])>0&&(b=!0):b=!0,b))return;Z[e]=o._offset+o.l2p(B[e]),r=.5}else r=B[e],\"y\"===e&&(r=1-r),Z[e]=\"x\"===e?S.l+S.w*r:S.t+S.h*r;var c=0;B[\"a\"+e+\"ref\"]===a?Z[\"aa\"+e]=o._offset+o.l2p(B[\"a\"+e]):(c=B.showarrow?B[\"a\"+e]:l*n(r,s),Z[e]+=c),B[\"_\"+e+\"type\"]=o&&o.type,B[\"_\"+e+\"size\"]=l,B[\"_\"+e+\"shift\"]=c}),b)return void G.remove();var w,k;B.showarrow&&(w=B.axref===B.xref?Z.x:c.constrain(Z.x-B.ax,1,_.width-1),k=B.ayref===B.yref?Z.y:c.constrain(Z.y-B.ay,1,_.height-1)),Z.x=c.constrain(Z.x,1,_.width-1),Z.y=c.constrain(Z.y,1,_.height-1);var M=W-l.top,A=W-l.left;a?r.select(\"svg\").attr({x:W-1,y:W}):(tt.attr({x:A,y:M}),tt.selectAll(\"tspan.line\").attr({y:M,x:A})),J.call(d.setRect,$/2,$/2,y-$,x-$);var L=0,T=0;L=B.axref===B.xref?Math.round(Z.aax-y/2):Math.round(Z.x-y/2),T=B.ayref===B.yref?Math.round(Z.aay-x/2):Math.round(Z.y-x/2),G.call(c.setTranslate,L,T);var z=\"annotations[\"+e+\"]\",E=function(n,r){i.select(t).selectAll('.annotation-arrow-g[data-index=\"'+e+'\"]').remove();var a,l;a=B.axref===B.xref?Z.aax+n:Z.x+n,l=B.ayref===B.yref?Z.aay+r:Z.y+r;var u=c.rotationXYMatrix(Y,a,l),d=c.apply2DTransform(u),h=c.apply2DTransform2(u),p=J.attr(\"width\")/2,m=J.attr(\"height\")/2,y=[[a-p,l-m,a-p,l+m],[a-p,l+m,a+p,l+m],[a+p,l+m,a+p,l-m],[a+p,l-m,a-p,l-m]].map(h);if(!y.reduce(function(t,e){return t^!!o(w,k,w+1e6,k+1e6,e[0],e[1],e[2],e[3])},!1)){y.forEach(function(t){var e=o(a,l,w,k,t[0],t[1],t[2],t[3]);e&&(a=e.x,l=e.y)});var x=B.arrowwidth,b=B.arrowcolor,_=U.append(\"g\").style({opacity:f.opacity(b)}).classed(\"annotation-arrow-g\",!0).attr(\"data-index\",String(e)),M=_.append(\"path\").attr(\"d\",\"M\"+a+\",\"+l+\"L\"+w+\",\"+k).style(\"stroke-width\",x+\"px\").call(f.stroke,f.rgb(b));v.arrowhead(M,B.arrowhead,\"end\",B.arrowsize);var A=_.append(\"path\").classed(\"annotation\",!0).classed(\"anndrag\",!0).attr({\"data-index\":String(e),d:\"M3,3H-3V-3H3ZM0,0L\"+(a-w)+\",\"+(l-k),transform:\"translate(\"+w+\",\"+k+\")\"}).style(\"stroke-width\",x+6+\"px\").call(f.stroke,\"rgba(0,0,0,0)\").call(f.fill,\"rgba(0,0,0,0)\");if(t._context.editable){var L,T,E;g.init({element:A.node(),prepFn:function(){var t=c.getTranslate(G);T=t.x,E=t.y,L={},H&&H.autorange&&(L[H._name+\".autorange\"]=!0),V&&V.autorange&&(L[V._name+\".autorange\"]=!0)},moveFn:function(t,e){_.attr(\"transform\",\"translate(\"+t+\",\"+e+\")\");var n=d(T,E),r=n[0]+t,a=n[1]+e;G.call(c.setTranslate,r,a),L[z+\".x\"]=H?B.x+t/H._m:(w+t-S.l)/S.w,L[z+\".y\"]=V?B.y+e/V._m:1-(k+e-S.t)/S.h,B.axref===B.xref&&(L[z+\".ax\"]=H?B.ax+t/H._m:(w+t-S.l)/S.w),B.ayref===B.yref&&(L[z+\".ay\"]=V?B.ay+e/V._m:1-(k+e-S.t)/S.h),X.attr({transform:\"rotate(\"+Y+\",\"+r+\",\"+a+\")\"})},doneFn:function(e){if(e){s.relayout(t,L);var n=document.querySelector(\".js-notes-box-panel\");n&&n.redraw(n.selectedObj)}}})}}};B.showarrow&&E(0,0);var C=c.rotationXYMatrix(Y,Z.x,Z.y),O=c.apply2DTransform(C);if(t._context.editable){var P,N,D;g.init({element:G.node(),prepFn:function(){var t=c.getTranslate(G);P=t.x,N=t.y,D={}},moveFn:function(t,e){G.call(c.setTranslate,P+t,N+e);var n=\"pointer\";if(B.showarrow)B.axref===B.xref?D[z+\".ax\"]=H.p2l(H.l2p(B.ax)+t):D[z+\".ax\"]=B.ax+t,B.ayref===B.yref?D[z+\".ay\"]=V.p2l(V.l2p(B.ay)+e):D[z+\".ay\"]=B.ay+e,E(t,e);else{if(H)D[z+\".x\"]=B.x+t/H._m;else{var r=B._xsize/S.w,a=B.x+B._xshift/S.w-r/2;D[z+\".x\"]=g.align(a+t/S.w,r,0,1,B.xanchor)}if(V)D[z+\".y\"]=B.y+e/V._m;else{var o=B._ysize/S.h,i=B.y-B._yshift/S.h-o/2;D[z+\".y\"]=g.align(i-e/S.h,o,0,1,B.yanchor)}H&&V||(n=g.getCursor(H?.5:D[z+\".x\"],V?.5:D[z+\".y\"],B.xanchor,B.yanchor))}var l=O(P,N),s=l[0]+t,u=l[1]+e;G.call(c.setTranslate,P+t,N+e),X.attr({transform:\"rotate(\"+Y+\",\"+s+\",\"+u+\")\"}),p(G,n)},doneFn:function(e){if(p(G),e){s.relayout(t,D);var n=document.querySelector(\".js-notes-box-panel\");n&&n.redraw(n.selectedObj)}}})}}var x,b=t.layout,_=t._fullLayout;if(!l(e)||-1===e){if(!e&&Array.isArray(a))return b.annotations=a,v.supplyLayoutDefaults(b,_),void v.drawAll(t);if(\"remove\"===a)return delete b.annotations,_.annotations=[],void v.drawAll(t);if(n&&\"add\"!==a){for(x=0;x<_.annotations.length;x++)v.draw(t,x,n,a);return}e=_.annotations.length,_.annotations.push({})}if(!n&&a){if(\"remove\"===a){for(_._infolayer.selectAll('.annotation[data-index=\"'+e+'\"]').remove(),_.annotations.splice(e,1),b.annotations.splice(e,1),x=e;x<_.annotations.length;x++)_._infolayer.selectAll('.annotation[data-index=\"'+(x+1)+'\"]').attr(\"data-index\",String(x)),v.draw(t,x);return}if(\"add\"===a||c.isPlainObject(a)){_.annotations.splice(e,0,{});var w=c.isPlainObject(a)?c.extendFlat({},a):{text:\"New text\"};for(b.annotations?b.annotations.splice(e,0,w):b.annotations=[w],x=_.annotations.length-1;x>e;x--)_._infolayer.selectAll('.annotation[data-index=\"'+(x-1)+'\"]').attr(\"data-index\",String(x)),v.draw(t,x)}}_._infolayer.selectAll('.annotation[data-index=\"'+e+'\"]').remove();var k=b.annotations[e],M=_.annotations[e];if(k){var A={xref:k.xref,yref:k.yref},L={};\"string\"==typeof n&&n?L[n]=a:c.isPlainObject(n)&&(L=n);var T=Object.keys(L);for(x=0;x<T.length;x++){var z=T[x];c.nestedProperty(k,z).set(L[z])}var S=_._size,E=[\"x\",\"y\"];for(x=0;2>x;x++){var C=E[x];if(void 0===L[C]&&void 0!==k[C]){var O=u.getFromId(t,u.coerceRef(A,{},t,C)),P=u.getFromId(t,u.coerceRef(k,{},t,C)),N=k[C],D=M[\"_\"+C+\"type\"];if(void 0!==L[C+\"ref\"]){var I=\"auto\"===k[C+\"anchor\"],R=\"x\"===C?S.w:S.h,j=(M[\"_\"+C+\"size\"]||0)/(2*R);if(O&&P)N=(N-O.range[0])/(O.range[1]-O.range[0]),N=P.range[0]+N*(P.range[1]-P.range[0]);else if(O){if(N=(N-O.range[0])/(O.range[1]-O.range[0]),N=O.domain[0]+N*(O.domain[1]-O.domain[0]),I){var q=N+j,F=N-j;2/3>N+F?N=F:N+q>4/3&&(N=q)}}else P&&(I&&(1/3>N?N+=j:N>2/3&&(N-=j)),N=(N-P.domain[0])/(P.domain[1]-P.domain[0]),N=P.range[0]+N*(P.range[1]-P.range[0]))}P&&P===O&&D&&(\"log\"===D&&\"log\"!==P.type?N=Math.pow(10,N):\"log\"!==D&&\"log\"===P.type&&(N=N>0?Math.log(N)/Math.LN10:void 0)),k[C]=N}}var B=r(k,_);_.annotations[e]=B;var H=u.getFromId(t,B.xref),V=u.getFromId(t,B.yref),Z={x:0,y:0},Y=+B.textangle||0,U=_._infolayer.append(\"g\").classed(\"annotation\",!0).attr(\"data-index\",String(e)).style(\"opacity\",B.opacity).on(\"click\",function(){t._dragging=!1,t.emit(\"plotly_clickannotation\",{index:e,annotation:k,fullAnnotation:B})}),X=U.append(\"g\").classed(\"annotation-text-g\",!0).attr(\"data-index\",String(e)),G=X.append(\"g\"),$=B.borderwidth,Q=B.borderpad,W=$+Q,J=G.append(\"rect\").attr(\"class\",\"bg\").style(\"stroke-width\",$+\"px\").call(f.stroke,B.bordercolor).call(f.fill,B.bgcolor),K=B.font,tt=G.append(\"text\").classed(\"annotation\",!0).attr(\"data-unformatted\",B.text).text(B.text);t._context.editable?tt.call(h.makeEditable,G).call(m).on(\"edit\",function(n){B.text=n,this.attr({\"data-unformatted\":B.text}),this.call(m);var r={};r[\"annotations[\"+e+\"].text\"]=B.text,H&&H.autorange&&(r[H._name+\".autorange\"]=!0),V&&V.autorange&&(r[V._name+\".autorange\"]=!0),s.relayout(t,r)}):tt.call(m),X.attr({transform:\"rotate(\"+Y+\",\"+Z.x+\",\"+Z.y+\")\"}).call(d.setPosition,Z.x,Z.y)}},v.arrowhead=function(t,e,n,r){l(r)||(r=1);var a=t.node(),o=v.ARROWPATHS[e||0];if(o){\"string\"==typeof n&&n||(n=\"end\");var s,c,u,h,p=(d.getPx(t,\"stroke-width\")||1)*r,g=t.style(\"stroke\")||f.defaultLine,m=t.style(\"stroke-opacity\")||1,y=n.indexOf(\"start\")>=0,x=n.indexOf(\"end\")>=0,b=o.backoff*p;if(\"line\"===a.nodeName){if(s={x:+t.attr(\"x1\"),y:+t.attr(\"y1\")},c={x:+t.attr(\"x2\"),y:+t.attr(\"y2\")},u=Math.atan2(s.y-c.y,s.x-c.x),h=u+Math.PI,b){var _=b*Math.cos(u),w=b*Math.sin(u);y&&(s.x-=_,s.y-=w,t.attr({x1:s.x,y1:s.y})),x&&(c.x+=_,c.y+=w,t.attr({x2:c.x,y2:c.y}))}}else i" -, -"f(\"path\"===a.nodeName){var k=a.getTotalLength(),M=\"\";if(y){var A=a.getPointAtLength(0),L=a.getPointAtLength(.1);u=Math.atan2(A.y-L.y,A.x-L.x),s=a.getPointAtLength(Math.min(b,k)),b&&(M=\"0px,\"+b+\"px,\")}if(x){var T=a.getPointAtLength(k),z=a.getPointAtLength(k-.1);if(h=Math.atan2(T.y-z.y,T.x-z.x),c=a.getPointAtLength(Math.max(0,k-b)),b){var S=M?2*b:b;M+=k-S+\"px,\"+k+\"px\"}}else M&&(M+=k+\"px\");M&&t.style(\"stroke-dasharray\",M)}var E=function(n,r){e>5&&(r=0),i.select(a.parentElement).append(\"path\").attr({\"class\":t.attr(\"class\"),d:o.path,transform:\"translate(\"+n.x+\",\"+n.y+\")rotate(\"+180*r/Math.PI+\")scale(\"+p+\")\"}).style({fill:g,opacity:m,\"stroke-width\":0})};y&&E(s,u),x&&E(c,h)}},v.calcAutorange=function(t){var e=t._fullLayout,n=e.annotations;if(n.length&&t._fullData.length){var r={};n.forEach(function(t){r[t.xref]=!0,r[t.yref]=!0});var o=u.list(t).filter(function(t){return t.autorange&&r[t._id]});if(o.length)return c.syncOrAsync([v.drawAll,a],t)}}},{\"../../lib\":89,\"../../lib/setcursor\":98,\"../../lib/svg_text_utils\":100,\"../../plotly\":107,\"../../plots/cartesian/axes\":110,\"../color\":18,\"../dragelement\":39,\"../drawing\":41,\"./arrow_paths\":14,\"./attributes\":15,d3:9,\"fast-isnumeric\":11}],17:[function(t,e,n){\"use strict\";n.defaults=[\"#1f77b4\",\"#ff7f0e\",\"#2ca02c\",\"#d62728\",\"#9467bd\",\"#8c564b\",\"#e377c2\",\"#7f7f7f\",\"#bcbd22\",\"#17becf\"],n.defaultLine=\"#444\",n.lightLine=\"#eee\",n.background=\"#fff\",n.lightFraction=1e3/11},{}],18:[function(t,e,n){\"use strict\";function r(t){if(o(t)||\"string\"!=typeof t)return t;var e=t.trim();if(\"rgb\"!==e.substr(0,3))return t;var n=e.match(/^rgba?\\s*\\(([^()]*)\\)$/);if(!n)return t;var r=n[1].trim().split(/\\s*[\\s,]\\s*/),a=\"a\"===e.charAt(3)&&4===r.length;if(!a&&3!==r.length)return t;for(var i=0;i<r.length;i++){if(!r[i].length)return t;if(r[i]=Number(r[i]),!(r[i]>=0))return t;if(3===i)r[i]>1&&(r[i]=1);else if(r[i]>=1)return t}var l=Math.round(255*r[0])+\", \"+Math.round(255*r[1])+\", \"+Math.round(255*r[2]);return a?\"rgba(\"+l+\", \"+r[3]+\")\":\"rgb(\"+l+\")\"}var a=t(\"tinycolor2\"),o=t(\"fast-isnumeric\"),i=e.exports={},l=t(\"./attributes\");i.defaults=l.defaults,i.defaultLine=l.defaultLine,i.lightLine=l.lightLine,i.background=l.background,i.tinyRGB=function(t){var e=t.toRgb();return\"rgb(\"+Math.round(e.r)+\", \"+Math.round(e.g)+\", \"+Math.round(e.b)+\")\"},i.rgb=function(t){return i.tinyRGB(a(t))},i.opacity=function(t){return t?a(t).getAlpha():0},i.addOpacity=function(t,e){var n=a(t).toRgb();return\"rgba(\"+Math.round(n.r)+\", \"+Math.round(n.g)+\", \"+Math.round(n.b)+\", \"+e+\")\"},i.combine=function(t,e){var n=a(t).toRgb();if(1===n.a)return a(t).toRgbString();var r=a(e||i.background).toRgb(),o=1===r.a?r:{r:255*(1-r.a)+r.r*r.a,g:255*(1-r.a)+r.g*r.a,b:255*(1-r.a)+r.b*r.a},l={r:o.r*(1-n.a)+n.r*n.a,g:o.g*(1-n.a)+n.g*n.a,b:o.b*(1-n.a)+n.b*n.a};return a(l).toRgbString()},i.stroke=function(t,e){var n=a(e);t.style({stroke:i.tinyRGB(n),\"stroke-opacity\":n.getAlpha()})},i.fill=function(t,e){var n=a(e);t.style({fill:i.tinyRGB(n),\"fill-opacity\":n.getAlpha()})},i.clean=function(t){if(t&&\"object\"==typeof t){var e,n,a,o,l=Object.keys(t);for(e=0;e<l.length;e++)if(a=l[e],o=t[a],\"color\"===a.substr(a.length-5))if(Array.isArray(o))for(n=0;n<o.length;n++)o[n]=r(o[n]);else t[a]=r(o);else if(\"colorscale\"===a.substr(a.length-10)&&Array.isArray(o))for(n=0;n<o.length;n++)Array.isArray(o[n])&&(o[n][1]=r(o[n][1]));else if(Array.isArray(o)){var s=o[0];if(!Array.isArray(s)&&s&&\"object\"==typeof s)for(n=0;n<o.length;n++)i.clean(o[n])}else o&&\"object\"==typeof o&&i.clean(o)}}},{\"./attributes\":17,\"fast-isnumeric\":11,tinycolor2:13}],19:[function(t,e,n){\"use strict\";var r=t(\"../../plots/cartesian/layout_attributes\"),a=t(\"../../plots/font_attributes\"),o=t(\"../../lib/extend\").extendFlat;e.exports={thicknessmode:{valType:\"enumerated\",values:[\"fraction\",\"pixels\"],dflt:\"pixels\"},thickness:{valType:\"number\",min:0,dflt:30},lenmode:{valType:\"enumerated\",values:[\"fraction\",\"pixels\"],dflt:\"fraction\"},len:{valType:\"number\",min:0,dflt:1},x:{valType:\"number\",dflt:1.02,min:-2,max:3},xanchor:{valType:\"enumerated\",values:[\"left\",\"center\",\"right\"],dflt:\"left\"},xpad:{valType:\"number\",min:0,dflt:10},y:{valType:\"number\",dflt:.5,min:-2,max:3},yanchor:{valType:\"enumerated\",values:[\"top\",\"middle\",\"bottom\"],dflt:\"middle\"},ypad:{valType:\"number\",min:0,dflt:10},outlinecolor:r.linecolor,outlinewidth:r.linewidth,bordercolor:r.linecolor,borderwidth:{valType:\"number\",min:0,dflt:0},bgcolor:{valType:\"color\",dflt:\"rgba(0,0,0,0)\"},tickmode:r.tickmode,nticks:r.nticks,tick0:r.tick0,dtick:r.dtick,tickvals:r.tickvals,ticktext:r.ticktext,ticks:o({},r.ticks,{dflt:\"\"}),ticklen:r.ticklen,tickwidth:r.tickwidth,tickcolor:r.tickcolor,showticklabels:r.showticklabels,tickfont:r.tickfont,tickangle:r.tickangle,tickformat:r.tickformat,tickprefix:r.tickprefix,showtickprefix:r.showtickprefix,ticksuffix:r.ticksuffix,showticksuffix:r.showticksuffix,exponentformat:r.exponentformat,showexponent:r.showexponent,title:{valType:\"string\",dflt:\"Click to enter colorscale title\"},titlefont:o({},a,{}),titleside:{valType:\"enumerated\",values:[\"right\",\"top\",\"bottom\"],dflt:\"top\"}}},{\"../../lib/extend\":88,\"../../plots/cartesian/layout_attributes\":119,\"../../plots/font_attributes\":128}],20:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"../../plots/cartesian/tick_value_defaults\"),o=t(\"../../plots/cartesian/tick_mark_defaults\"),i=t(\"../../plots/cartesian/tick_label_defaults\"),l=t(\"./attributes\");e.exports=function(t,e,n){function s(t,e){return r.coerce(u,c,l,t,e)}var c=e.colorbar={},u=t.colorbar||{},f=s(\"thicknessmode\");s(\"thickness\",\"fraction\"===f?30/(n.width-n.margin.l-n.margin.r):30);var d=s(\"lenmode\");s(\"len\",\"fraction\"===d?1:n.height-n.margin.t-n.margin.b),s(\"x\"),s(\"xanchor\"),s(\"xpad\"),s(\"y\"),s(\"yanchor\"),s(\"ypad\"),r.noneOrAll(u,c,[\"x\",\"y\"]),s(\"outlinecolor\"),s(\"outlinewidth\"),s(\"bordercolor\"),s(\"borderwidth\"),s(\"bgcolor\"),a(u,c,s,\"linear\"),i(u,c,s,\"linear\",{outerTicks:!1,font:n.font,noHover:!0}),o(u,c,s,\"linear\",{outerTicks:!1,font:n.font,noHover:!0}),s(\"title\"),r.coerceFont(s,\"titlefont\",n.font),s(\"titleside\")}},{\"../../lib\":89,\"../../plots/cartesian/tick_label_defaults\":125,\"../../plots/cartesian/tick_mark_defaults\":126,\"../../plots/cartesian/tick_value_defaults\":127,\"./attributes\":19}],21:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"tinycolor2\"),o=t(\"../../plotly\"),i=t(\"../../plots/plots\"),l=t(\"../../plots/cartesian/axes\"),s=t(\"../dragelement\"),c=t(\"../../lib\"),u=t(\"../../lib/extend\").extendFlat,f=t(\"../../lib/setcursor\"),d=t(\"../drawing\"),h=t(\"../color\"),p=t(\"../titles\"),g=t(\"../../plots/cartesian/axis_defaults\"),v=t(\"../../plots/cartesian/position_defaults\"),m=t(\"../../plots/cartesian/layout_attributes\"),y=t(\"./attributes\");e.exports=function(t,e){function n(){function y(t,e){return c.coerce(W,J,m,t,e)}function _(){if(-1!==[\"top\",\"bottom\"].indexOf(b.titleside)){var e=at.select(\".cbtitle\"),n=e.select(\"text\"),o=[-b.outlinewidth/2,b.outlinewidth/2],i=e.select(\".h\"+J._id+\"title-math-group\").node(),s=15.6;if(n.node()&&(s=1.3*parseInt(n.style(\"font-size\"),10)),i?(it=d.bBox(i).height,it>s&&(o[1]-=(it-s)/2)):n.node()&&!n.classed(\"js-placeholder\")&&(it=d.bBox(e.node()).height),it){if(it+=5,\"top\"===b.titleside)J.domain[1]-=it/A.h,o[1]*=-1;else{J.domain[0]+=it/A.h;var u=Math.max(1,n.selectAll(\"tspan.line\").size());o[1]+=(1-u)*s}e.attr(\"transform\",\"translate(\"+o+\")\"),J.setScale()}}at.selectAll(\".cbfills,.cblines,.cbaxis\").attr(\"transform\",\"translate(0,\"+Math.round(A.h*(1-J.domain[1]))+\")\");var f=at.select(\".cbfills\").selectAll(\"rect.cbfill\").data(S);f.enter().append(\"rect\").classed(\"cbfill\",!0).style(\"stroke\",\"none\"),f.exit().remove(),f.each(function(t,e){var n=[0===e?T[0]:(S[e]+S[e-1])/2,e===S.length-1?T[1]:(S[e]+S[e+1])/2].map(J.c2p).map(Math.round);e!==S.length-1&&(n[1]+=n[1]>n[0]?1:-1);var o=C(t).replace(\"e-\",\"\"),i=a(o).toHexString();r.select(this).attr({x:U,width:Math.max(q,2),y:r.min(n),height:Math.max(r.max(n)-r.min(n),2),fill:i})});var h=at.select(\".cblines\").selectAll(\"path.cbline\").data(b.line.color&&b.line.width?z:[]);return h.enter().append(\"path\").classed(\"cbline\",!0),h.exit().remove(),h.each(function(t){r.select(this).attr(\"d\",\"M\"+U+\",\"+(Math.round(J.c2p(t))+b.line.width/2%1)+\"h\"+q).call(d.lineGroupStyle,b.line.width,E(t),b.line.dash)}),J._axislayer.selectAll(\"g.\"+J._id+\"tick,path\").remove(),J._pos=U+q+(b.outlinewidth||0)/2-(\"outside\"===b.ticks?1:0),J.side=\"right\",c.syncOrAsync([function(){return l.doTicks(t,J,!0)},function(){if(-1===[\"top\",\"bottom\"].indexOf(b.titleside)){var e=J.titlefont.size,n=J._offset+J._length/2,a=A.l+(J.position||0)*A.w+(\"right\"===J.side?10+e*(J.showticklabels?1:.5):-10-e*(J.showticklabels?.5:0));w(\"h\"+J._id+\"title\",{avoid:{selection:r.select(t).selectAll(\"g.\"+J._id+\"tick\"),side:b.titleside,offsetLeft:A.l,offsetTop:A.t,maxShift:M.width},attributes:{x:a,y:n,\"text-anchor\":\"middle\"},transform:{rotate:\"-90\",offset:0}})}}])}function w(e,n){var r,a=x();r=i.traceIs(a,\"markerColorscale\")?\"marker.colorbar.title\":\"colorbar.title\";var o={propContainer:J,propName:r,traceIndex:a.index,dfltName:\"colorscale\",containerGroup:at.select(\".cbtitle\")},l=\"h\"===e.charAt(0)?e.substr(1):\"h\"+e;at.selectAll(\".\"+l+\",.\"+l+\"-math-group\").remove(),p.draw(t,e,u(o,n||{}))}function k(){var n=q+b.outlinewidth/2+d.bBox(J._axislayer.node()).width;if(I=ot.select(\"text\"),I.node()&&!I.classed(\"js-placeholder\")){var r,a=ot.select(\".h\"+J._id+\"title-math-group\").node();r=a&&-1!==[\"top\",\"bottom\"].indexOf(b.titleside)?d.bBox(a).width:d.bBox(ot.node()).right-U-A.l,n=Math.max(n,r)}var o=2*b.xpad+n+b.borderwidth+b.outlinewidth/2,l=$-Q;at.select(\".cbbg\").attr({x:U-b.xpad-(b.borderwidth+b.outlinewidth)/2,y:Q-Z,width:Math.max(o,2),height:Math.max(l+2*Z,2)}).call(h.fill,b.bgcolor).call(h.stroke,b.bordercolor).style({\"stroke-width\":b.borderwidth}),at.selectAll(\".cboutline\").attr({x:U,y:Q+b.ypad+(\"top\"===b.titleside?it:0),width:Math.max(q,2),height:Math.max(l-2*b.ypad-it,2)}).call(h.stroke,b.outlinecolor).style({fill:\"None\",\"stroke-width\":b.outlinewidth});var s=({center:.5,right:1}[b.xanchor]||0)*o;at.attr(\"transform\",\"translate(\"+(A.l-s)+\",\"+A.t+" -, -"\")\"),i.autoMargin(t,e,{x:b.x,y:b.y,l:o*({right:1,center:.5}[b.xanchor]||0),r:o*({left:1,center:.5}[b.xanchor]||0),t:l*({bottom:1,middle:.5}[b.yanchor]||0),b:l*({top:1,middle:.5}[b.yanchor]||0)})}var M=t._fullLayout,A=M._size;if(\"function\"!=typeof b.fillcolor&&\"function\"!=typeof b.line.color)return void M._infolayer.selectAll(\"g.\"+e).remove();var L,T=r.extent((\"function\"==typeof b.fillcolor?b.fillcolor:b.line.color).domain()),z=[],S=[],E=\"function\"==typeof b.line.color?b.line.color:function(){return b.line.color},C=\"function\"==typeof b.fillcolor?b.fillcolor:function(){return b.fillcolor},O=b.levels.end+b.levels.size/100,P=b.levels.size,N=1.001*T[0]-.001*T[1],D=1.001*T[1]-.001*T[0];for(L=b.levels.start;0>(L-O)*P;L+=P)L>N&&D>L&&z.push(L);if(\"function\"==typeof b.fillcolor)if(b.filllevels)for(O=b.filllevels.end+b.filllevels.size/100,P=b.filllevels.size,L=b.filllevels.start;0>(L-O)*P;L+=P)L>T[0]&&L<T[1]&&S.push(L);else S=z.map(function(t){return t-b.levels.size/2}),S.push(S[S.length-1]+b.levels.size);else b.fillcolor&&\"string\"==typeof b.fillcolor&&(S=[0]);b.levels.size<0&&(z.reverse(),S.reverse());var I,R=M.height-M.margin.t-M.margin.b,j=M.width-M.margin.l-M.margin.r,q=Math.round(b.thickness*(\"fraction\"===b.thicknessmode?j:1)),F=q/A.w,B=Math.round(b.len*(\"fraction\"===b.lenmode?R:1)),H=B/A.h,V=b.xpad/A.w,Z=(b.borderwidth+b.outlinewidth)/2,Y=b.ypad/A.h,U=Math.round(b.x*A.w+b.xpad),X=b.x-F*({middle:.5,right:1}[b.xanchor]||0),G=b.y+H*(({top:-.5,bottom:.5}[b.yanchor]||0)-.5),$=Math.round(A.h*(1-G)),Q=$-B,W={type:\"linear\",range:T,tickmode:b.tickmode,nticks:b.nticks,tick0:b.tick0,dtick:b.dtick,tickvals:b.tickvals,ticktext:b.ticktext,ticks:b.ticks,ticklen:b.ticklen,tickwidth:b.tickwidth,tickcolor:b.tickcolor,showticklabels:b.showticklabels,tickfont:b.tickfont,tickangle:b.tickangle,tickformat:b.tickformat,exponentformat:b.exponentformat,showexponent:b.showexponent,showtickprefix:b.showtickprefix,tickprefix:b.tickprefix,showticksuffix:b.showticksuffix,ticksuffix:b.ticksuffix,title:b.title,titlefont:b.titlefont,anchor:\"free\",position:1},J={},K={letter:\"y\",font:M.font,noHover:!0};if(g(W,J,y,K),v(W,J,y,K),J._id=\"y\"+e,J._gd=t,J.position=b.x+V+F,n.axis=J,-1!==[\"top\",\"bottom\"].indexOf(b.titleside)&&(J.titleside=b.titleside,J.titlex=b.x+V,J.titley=G+(\"top\"===b.titleside?H-Y:Y)),b.line.color&&\"auto\"===b.tickmode){J.tickmode=\"linear\",J.tick0=b.levels.start;var tt=b.levels.size,et=c.constrain(($-Q)/50,4,15)+1,nt=(T[1]-T[0])/((b.nticks||et)*tt);if(nt>1){var rt=Math.pow(10,Math.floor(Math.log(nt)/Math.LN10));tt*=rt*c.roundUp(nt/rt,[2,5,10]),(Math.abs(b.levels.start)/b.levels.size+1e-6)%1<2e-6&&(J.tick0=0)}J.dtick=tt}J.domain=[G+Y,G+H-Y],J.setScale();var at=M._infolayer.selectAll(\"g.\"+e).data([0]);at.enter().append(\"g\").classed(e,!0).each(function(){var t=r.select(this);t.append(\"rect\").classed(\"cbbg\",!0),t.append(\"g\").classed(\"cbfills\",!0),t.append(\"g\").classed(\"cblines\",!0),t.append(\"g\").classed(\"cbaxis\",!0).classed(\"crisp\",!0),t.append(\"g\").classed(\"cbtitleunshift\",!0).append(\"g\").classed(\"cbtitle\",!0),t.append(\"rect\").classed(\"cboutline\",!0),t.select(\".cbtitle\").datum(0)}),at.attr(\"transform\",\"translate(\"+Math.round(A.l)+\",\"+Math.round(A.t)+\")\");var ot=at.select(\".cbtitleunshift\").attr(\"transform\",\"translate(-\"+Math.round(A.l)+\",-\"+Math.round(A.t)+\")\");J._axislayer=at.select(\".cbaxis\");var it=0;if(-1!==[\"top\",\"bottom\"].indexOf(b.titleside)){var lt,st=A.l+(b.x+V)*A.w,ct=J.titlefont.size;lt=\"top\"===b.titleside?(1-(G+H-Y))*A.h+A.t+3+.75*ct:(1-(G+Y))*A.h+A.t-3-.25*ct,w(J._id+\"title\",{attributes:{x:st,y:lt,\"text-anchor\":\"start\"}})}var ut=c.syncOrAsync([i.previousPromises,_,i.previousPromises,k],t);if(ut&&ut.then&&(t._promises||[]).push(ut),t._context.editable){var ft,dt,ht;s.init({element:at.node(),prepFn:function(){ft=at.attr(\"transform\"),f(at)},moveFn:function(t,e){at.attr(\"transform\",ft+\" translate(\"+t+\",\"+e+\")\"),dt=s.align(X+t/A.w,F,0,1,b.xanchor),ht=s.align(G-e/A.h,H,0,1,b.yanchor);var n=s.getCursor(dt,ht,b.xanchor,b.yanchor);f(at,n)},doneFn:function(e){f(at),e&&void 0!==dt&&void 0!==ht&&o.restyle(t,{\"colorbar.x\":dt,\"colorbar.y\":ht},x().index)}})}return ut}function x(){var n,r,a=e.substr(2);for(n=0;n<t._fullData.length;n++)if(r=t._fullData[n],r.uid===a)return r}var b={};return Object.keys(y).forEach(function(t){b[t]=null}),b.fillcolor=null,b.line={color:null,width:null,dash:null},b.levels={start:null,end:null,size:null},b.filllevels=null,Object.keys(b).forEach(function(t){n[t]=function(e){return arguments.length?(b[t]=c.isPlainObject(b[t])?c.extendFlat(b[t],e):e,n):b[t]}}),n.options=function(t){return Object.keys(t).forEach(function(e){\"function\"==typeof n[e]&&n[e](t[e])}),n},n._opts=b,n}},{\"../../lib\":89,\"../../lib/extend\":88,\"../../lib/setcursor\":98,\"../../plotly\":107,\"../../plots/cartesian/axes\":110,\"../../plots/cartesian/axis_defaults\":111,\"../../plots/cartesian/layout_attributes\":119,\"../../plots/cartesian/position_defaults\":122,\"../../plots/plots\":130,\"../color\":18,\"../dragelement\":39,\"../drawing\":41,\"../titles\":81,\"./attributes\":19,d3:9,tinycolor2:13}],22:[function(t,e,n){\"use strict\";e.exports=function(t){return\"object\"==typeof t.colorbar&&null!==t.colorbar}},{}],23:[function(t,e,n){\"use strict\";n.attributes=t(\"./attributes\"),n.supplyDefaults=t(\"./defaults\"),n.draw=t(\"./draw\"),n.hasColorbar=t(\"./has_colorbar\")},{\"./attributes\":19,\"./defaults\":20,\"./draw\":21,\"./has_colorbar\":22}],24:[function(t,e,n){\"use strict\";e.exports={zauto:{valType:\"boolean\",dflt:!0},zmin:{valType:\"number\",dflt:null},zmax:{valType:\"number\",dflt:null},colorscale:{valType:\"colorscale\"},autocolorscale:{valType:\"boolean\",dflt:!0},reversescale:{valType:\"boolean\",dflt:!1},showscale:{valType:\"boolean\",dflt:!0}}},{}],25:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"./scales\"),o=t(\"./flip_scale\");e.exports=function(t,e,n,i){var l,s;n?(l=r.nestedProperty(t,n).get(),s=r.nestedProperty(t._input,n).get()):(l=t,s=t._input);var c=l[i+\"auto\"],u=l[i+\"min\"],f=l[i+\"max\"],d=l.colorscale;c===!1&&void 0!==u||(u=r.aggNums(Math.min,null,e)),c===!1&&void 0!==f||(f=r.aggNums(Math.max,null,e)),u===f&&(u-=.5,f+=.5),l[i+\"min\"]=u,l[i+\"max\"]=f,s[i+\"min\"]=u,s[i+\"max\"]=f,l.autocolorscale&&(d=0>u*f?a.RdBu:u>=0?a.Reds:a.Blues,s.colorscale=d,l.reversescale&&(d=o(d)),l.colorscale=d)}},{\"../../lib\":89,\"./flip_scale\":29,\"./scales\":36}],26:[function(t,e,n){\"use strict\";var r=t(\"./attributes\"),a=t(\"../../lib/extend\").extendDeep;t(\"./scales.js\");e.exports=function(t){return{color:{valType:\"color\",arrayOk:!0},colorscale:a({},r.colorscale,{}),cauto:a({},r.zauto,{}),cmax:a({},r.zmax,{}),cmin:a({},r.zmin,{}),autocolorscale:a({},r.autocolorscale,{}),reversescale:a({},r.reversescale,{})}}},{\"../../lib/extend\":88,\"./attributes\":24,\"./scales.js\":36}],27:[function(t,e,n){\"use strict\";var r=t(\"./scales\");e.exports=r.RdBu},{\"./scales\":36}],28:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\"),a=t(\"../../lib\"),o=t(\"../colorbar/has_colorbar\"),i=t(\"../colorbar/defaults\"),l=t(\"./is_valid_scale\"),s=t(\"./flip_scale\");e.exports=function(t,e,n,c,u){var f=u.prefix,d=u.cLetter,h=f.slice(0,f.length-1),p=f?a.nestedProperty(t,h).get()||{}:t,g=f?a.nestedProperty(e,h).get()||{}:e,v=p[d+\"min\"],m=p[d+\"max\"],y=p.colorscale,x=r(v)&&r(m)&&m>v;c(f+d+\"auto\",!x),c(f+d+\"min\"),c(f+d+\"max\");var b;void 0!==y&&(b=!l(y)),c(f+\"autocolorscale\",b);var _=c(f+\"colorscale\"),w=c(f+\"reversescale\");if(w&&(g.colorscale=s(_)),\"marker.line.\"!==f){var k;f&&(k=o(p));var M=c(f+\"showscale\",k);M&&i(p,g,n)}}},{\"../../lib\":89,\"../colorbar/defaults\":20,\"../colorbar/has_colorbar\":22,\"./flip_scale\":29,\"./is_valid_scale\":33,\"fast-isnumeric\":11}],29:[function(t,e,n){\"use strict\";e.exports=function(t){for(var e,n=t.length,r=new Array(n),a=n-1,o=0;a>=0;a--,o++)e=t[a],r[o]=[1-e[0],e[1]];return r}},{}],30:[function(t,e,n){\"use strict\";var r=t(\"./scales\"),a=t(\"./default_scale\"),o=t(\"./is_valid_scale_array\");e.exports=function(t,e){function n(){try{t=r[t]||JSON.parse(t)}catch(n){t=e}}return e||(e=a),t?(\"string\"==typeof t&&(n(),\"string\"==typeof t&&n()),o(t)?t:e):e}},{\"./default_scale\":27,\"./is_valid_scale_array\":34,\"./scales\":36}],31:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\"),a=t(\"../../lib\"),o=t(\"./is_valid_scale\");e.exports=function(t,e){var n=e?a.nestedProperty(t,e).get()||{}:t,i=n.color,l=!1;if(Array.isArray(i))for(var s=0;s<i.length;s++)if(r(i[s])){l=!0;break}return\"object\"==typeof n&&null!==n&&(l||n.showscale===!0||r(n.cmin)&&r(n.cmax)||o(n.colorscale)||\"object\"==typeof n.colorbar&&null!==n.colorbar)}},{\"../../lib\":89,\"./is_valid_scale\":33,\"fast-isnumeric\":11}],32:[function(t,e,n){\"use strict\";n.scales=t(\"./scales\"),n.defaultScale=t(\"./default_scale\"),n.attributes=t(\"./attributes\"),n.handleDefaults=t(\"./defaults\"),n.calc=t(\"./calc\"),n.hasColorscale=t(\"./has_colorscale\"),n.isValidScale=t(\"./is_valid_scale\"),n.getScale=t(\"./get_scale\"),n.flipScale=t(\"./flip_scale\"),n.makeScaleFunction=t(\"./make_scale_function\")},{\"./attributes\":24,\"./calc\":25,\"./default_scale\":27,\"./defaults\":28,\"./flip_scale\":29,\"./get_scale\":30,\"./has_colorscale\":31,\"./is_valid_scale\":33,\"./make_scale_function\":35,\"./scales\":36}],33:[function(t,e,n){\"use strict\";var r=t(\"./scales\"),a=t(\"./is_valid_scale_array\");e.exports=function(t){return void 0!==r[t]?!0:a(t)}},{\"./is_valid_scale_array\":34,\"./scales\":36}],34:[function(t,e,n){\"use strict\";var r=t(\"tinycolor2\");e.exports=function(t){var e=0;if(!Array.isArray(t)||t.length<2)return!1;if(!t[0]||!t[t.length-1])return!1;if(0!==+t[0][0]||1!==+t[t.length-1][0])return!1;for(var n=0;n<t.length;n++){var a=t[n];if(2!==a.length||+a[0]<e||!r(a[1]).isValid())return!1;e=+a[0]}return!0}},{tinycolor2:13}],35:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"tinycolor2\"),o=t(\"fast-isnumeric\"),i=t(\"../../lib\"),l=t(\"../color\");e.exports=function(t,e,n){for(var s,c=t.length,u=new Array(c),f=new Array(c),d=0;c>d;d++)s=t[d],u[d]=e+s[0]*(n-e),f[d]=a(s[1]).toRgb();var h=r.scale.linear().domain(u).interpolate(r.interpolateObject).range(f);return function(t){if(o(t)){var r=i.constrain(t,e,n),s=h(r);return a(s).toRgbString()}return a(t).isVali" -, -"d()?t:l.defaultLine}}},{\"../../lib\":89,\"../color\":18,d3:9,\"fast-isnumeric\":11,tinycolor2:13}],36:[function(t,e,n){\"use strict\";e.exports={Greys:[[0,\"rgb(0,0,0)\"],[1,\"rgb(255,255,255)\"]],YlGnBu:[[0,\"rgb(8,29,88)\"],[.125,\"rgb(37,52,148)\"],[.25,\"rgb(34,94,168)\"],[.375,\"rgb(29,145,192)\"],[.5,\"rgb(65,182,196)\"],[.625,\"rgb(127,205,187)\"],[.75,\"rgb(199,233,180)\"],[.875,\"rgb(237,248,217)\"],[1,\"rgb(255,255,217)\"]],Greens:[[0,\"rgb(0,68,27)\"],[.125,\"rgb(0,109,44)\"],[.25,\"rgb(35,139,69)\"],[.375,\"rgb(65,171,93)\"],[.5,\"rgb(116,196,118)\"],[.625,\"rgb(161,217,155)\"],[.75,\"rgb(199,233,192)\"],[.875,\"rgb(229,245,224)\"],[1,\"rgb(247,252,245)\"]],YlOrRd:[[0,\"rgb(128,0,38)\"],[.125,\"rgb(189,0,38)\"],[.25,\"rgb(227,26,28)\"],[.375,\"rgb(252,78,42)\"],[.5,\"rgb(253,141,60)\"],[.625,\"rgb(254,178,76)\"],[.75,\"rgb(254,217,118)\"],[.875,\"rgb(255,237,160)\"],[1,\"rgb(255,255,204)\"]],Bluered:[[0,\"rgb(0,0,255)\"],[1,\"rgb(255,0,0)\"]],RdBu:[[0,\"rgb(5,10,172)\"],[.35,\"rgb(106,137,247)\"],[.5,\"rgb(190,190,190)\"],[.6,\"rgb(220,170,132)\"],[.7,\"rgb(230,145,90)\"],[1,\"rgb(178,10,28)\"]],Reds:[[0,\"rgb(220,220,220)\"],[.2,\"rgb(245,195,157)\"],[.4,\"rgb(245,160,105)\"],[1,\"rgb(178,10,28)\"]],Blues:[[0,\"rgb(5,10,172)\"],[.35,\"rgb(40,60,190)\"],[.5,\"rgb(70,100,245)\"],[.6,\"rgb(90,120,245)\"],[.7,\"rgb(106,137,247)\"],[1,\"rgb(220,220,220)\"]],Picnic:[[0,\"rgb(0,0,255)\"],[.1,\"rgb(51,153,255)\"],[.2,\"rgb(102,204,255)\"],[.3,\"rgb(153,204,255)\"],[.4,\"rgb(204,204,255)\"],[.5,\"rgb(255,255,255)\"],[.6,\"rgb(255,204,255)\"],[.7,\"rgb(255,153,255)\"],[.8,\"rgb(255,102,204)\"],[.9,\"rgb(255,102,102)\"],[1,\"rgb(255,0,0)\"]],Rainbow:[[0,\"rgb(150,0,90)\"],[.125,\"rgb(0,0,200)\"],[.25,\"rgb(0,25,255)\"],[.375,\"rgb(0,152,255)\"],[.5,\"rgb(44,255,150)\"],[.625,\"rgb(151,255,0)\"],[.75,\"rgb(255,234,0)\"],[.875,\"rgb(255,111,0)\"],[1,\"rgb(255,0,0)\"]],Portland:[[0,\"rgb(12,51,131)\"],[.25,\"rgb(10,136,186)\"],[.5,\"rgb(242,211,56)\"],[.75,\"rgb(242,143,56)\"],[1,\"rgb(217,30,30)\"]],Jet:[[0,\"rgb(0,0,131)\"],[.125,\"rgb(0,60,170)\"],[.375,\"rgb(5,255,255)\"],[.625,\"rgb(255,255,0)\"],[.875,\"rgb(250,0,0)\"],[1,\"rgb(128,0,0)\"]],\n" -, -"Hot:[[0,\"rgb(0,0,0)\"],[.3,\"rgb(230,0,0)\"],[.6,\"rgb(255,210,0)\"],[1,\"rgb(255,255,255)\"]],Blackbody:[[0,\"rgb(0,0,0)\"],[.2,\"rgb(230,0,0)\"],[.4,\"rgb(230,210,0)\"],[.7,\"rgb(255,255,255)\"],[1,\"rgb(160,200,255)\"]],Earth:[[0,\"rgb(0,0,130)\"],[.1,\"rgb(0,180,180)\"],[.2,\"rgb(40,210,40)\"],[.4,\"rgb(230,230,50)\"],[.6,\"rgb(120,70,20)\"],[1,\"rgb(255,255,255)\"]],Electric:[[0,\"rgb(0,0,0)\"],[.15,\"rgb(30,0,100)\"],[.4,\"rgb(120,0,100)\"],[.6,\"rgb(160,90,0)\"],[.8,\"rgb(230,200,0)\"],[1,\"rgb(255,250,220)\"]],Viridis:[[0,\"#440154\"],[.06274509803921569,\"#48186a\"],[.12549019607843137,\"#472d7b\"],[.18823529411764706,\"#424086\"],[.25098039215686274,\"#3b528b\"],[.3137254901960784,\"#33638d\"],[.3764705882352941,\"#2c728e\"],[.4392156862745098,\"#26828e\"],[.5019607843137255,\"#21918c\"],[.5647058823529412,\"#1fa088\"],[.6274509803921569,\"#28ae80\"],[.6901960784313725,\"#3fbc73\"],[.7529411764705882,\"#5ec962\"],[.8156862745098039,\"#84d44b\"],[.8784313725490196,\"#addc30\"],[.9411764705882353,\"#d8e219\"],[1,\"#fde725\"]]}},{}],37:[function(t,e,n){\"use strict\";e.exports=function(t,e,n,r,a){var o=(t-n)/(r-n),i=o+e/(r-n),l=(o+i)/2;return\"left\"===a||\"bottom\"===a?o:\"center\"===a||\"middle\"===a?l:\"right\"===a||\"top\"===a?i:2/3-l>o?o:i>4/3-l?i:l}},{}],38:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=[[\"sw-resize\",\"s-resize\",\"se-resize\"],[\"w-resize\",\"move\",\"e-resize\"],[\"nw-resize\",\"n-resize\",\"ne-resize\"]];e.exports=function(t,e,n,o){return t=\"left\"===n?0:\"center\"===n?1:\"right\"===n?2:r.constrain(Math.floor(3*t),0,2),e=\"bottom\"===o?0:\"middle\"===o?1:\"top\"===o?2:r.constrain(Math.floor(3*e),0,2),a[e][t]}},{\"../../lib\":89}],39:[function(t,e,n){\"use strict\";function r(){var t=document.createElement(\"div\");t.className=\"dragcover\";var e=t.style;return e.position=\"fixed\",e.left=0,e.right=0,e.top=0,e.bottom=0,e.zIndex=999999999,e.background=\"none\",document.body.appendChild(t),t}function a(t){t._dragging=!1,t._replotPending&&o.plot(t)}var o=t(\"../../plotly\"),i=t(\"../../lib\"),l=t(\"../../plots/cartesian/constants\"),s=e.exports={};s.align=t(\"./align\"),s.getCursor=t(\"./cursor\");var c=t(\"./unhover\");s.unhover=c.wrapped,s.unhoverRaw=c.raw,s.init=function(t){function e(e){return t.element.onmousemove=p,g._dragged=!1,g._dragging=!0,c=e.clientX,u=e.clientY,h=e.target,f=(new Date).getTime(),f-g._mouseDownTime<m?v+=1:(v=1,g._mouseDownTime=f),t.prepFn&&t.prepFn(e,c,u),d=r(),d.onmousemove=n,d.onmouseup=o,d.onmouseout=o,d.style.cursor=window.getComputedStyle(t.element).cursor,i.pauseEvent(e)}function n(e){var n=e.clientX-c,r=e.clientY-u,a=t.minDrag||l.MINDRAG;return Math.abs(n)<a&&(n=0),Math.abs(r)<a&&(r=0),(n||r)&&(g._dragged=!0,s.unhover(g)),t.moveFn&&t.moveFn(n,r,g._dragged),i.pauseEvent(e)}function o(e){if(p=t.element.onmousemove,t.setCursor&&(t.element.onmousemove=t.setCursor),d.onmousemove=null,d.onmouseup=null,d.onmouseout=null,i.removeElement(d),!g._dragging)return void(g._dragged=!1);if(g._dragging=!1,(new Date).getTime()-g._mouseDownTime>m&&(v=Math.max(v-1,1)),t.doneFn&&t.doneFn(g._dragged,v),!g._dragged){var n=document.createEvent(\"MouseEvents\");n.initEvent(\"click\",!0,!0),h.dispatchEvent(n)}return a(g),g._dragged=!1,i.pauseEvent(e)}var c,u,f,d,h,p,g=i.getPlotDiv(t.element)||{},v=1,m=l.DBLCLICKDELAY;g._mouseDownTime||(g._mouseDownTime=0),p=t.element.onmousemove,t.setCursor&&(t.element.onmousemove=t.setCursor),t.element.onmousedown=e,t.element.style.pointerEvents=\"all\"}},{\"../../lib\":89,\"../../plotly\":107,\"../../plots/cartesian/constants\":115,\"./align\":37,\"./cursor\":38,\"./unhover\":40}],40:[function(t,e,n){\"use strict\";var r=t(\"../../lib/events\"),a=e.exports={};a.wrapped=function(t,e,n){\"string\"==typeof t&&(t=document.getElementById(t)),t._hoverTimer&&(clearTimeout(t._hoverTimer),t._hoverTimer=void 0),a.raw(t,e,n)},a.raw=function(t,e){var n=t._fullLayout;e||(e={}),e.target&&r.triggerHandler(t,\"plotly_beforehover\",e)===!1||(n._hoverlayer.selectAll(\"g\").remove(),e.target&&t._hoverdata&&t.emit(\"plotly_unhover\",{points:t._hoverdata}),t._hoverdata=void 0)}},{\"../../lib/events\":87}],41:[function(t,e,n){\"use strict\";function r(t,e,n,r){var o=t[0]-e[0],i=t[1]-e[1],l=n[0]-e[0],s=n[1]-e[1],c=Math.pow(o*o+i*i,b/2),u=Math.pow(l*l+s*s,b/2),f=(u*u*o-c*c*l)*r,d=(u*u*i-c*c*s)*r,h=3*u*(c+u),p=3*c*(c+u);return[[a.round(e[0]+(h&&f/h),2),a.round(e[1]+(h&&d/h),2)],[a.round(e[0]-(p&&f/p),2),a.round(e[1]-(p&&d/p),2)]]}var a=t(\"d3\"),o=t(\"fast-isnumeric\"),i=t(\"../../plots/plots\"),l=t(\"../color\"),s=t(\"../colorscale\"),c=t(\"../../lib\"),u=t(\"../../lib/svg_text_utils\"),f=t(\"../../constants/xmlns_namespaces\"),d=t(\"../../traces/scatter/subtypes\"),h=t(\"../../traces/scatter/make_bubble_size_func\"),p=e.exports={};p.font=function(t,e,n,r){e&&e.family&&(r=e.color,n=e.size,e=e.family),e&&t.style(\"font-family\",e),n+1&&t.style(\"font-size\",n+\"px\"),r&&t.call(l.fill,r)},p.setPosition=function(t,e,n){t.attr(\"x\",e).attr(\"y\",n)},p.setSize=function(t,e,n){t.attr(\"width\",e).attr(\"height\",n)},p.setRect=function(t,e,n,r,a){t.call(p.setPosition,e,n).call(p.setSize,r,a)},p.translatePoints=function(t,e,n){t.each(function(t){var r=t.xp||e.c2p(t.x),i=t.yp||n.c2p(t.y),l=a.select(this);o(r)&&o(i)?\"text\"===this.nodeName?l.attr(\"x\",r).attr(\"y\",i):l.attr(\"transform\",\"translate(\"+r+\",\"+i+\")\"):l.remove()})},p.getPx=function(t,e){return Number(t.style(e).replace(/px$/,\"\"))},p.crispRound=function(t,e,n){return e&&o(e)?t._context.staticPlot?e:1>e?1:Math.round(e):n||0},p.lineGroupStyle=function(t,e,n,r){t.style(\"fill\",\"none\").each(function(t){var o=(((t||[])[0]||{}).trace||{}).line||{},i=e||o.width||0,s=r||o.dash||\"\";a.select(this).call(l.stroke,n||o.color).call(p.dashLine,s,i)})},p.dashLine=function(t,e,n){var r=Math.max(n,3);\"solid\"===e?e=\"\":\"dot\"===e?e=r+\"px,\"+r+\"px\":\"dash\"===e?e=3*r+\"px,\"+3*r+\"px\":\"longdash\"===e?e=5*r+\"px,\"+5*r+\"px\":\"dashdot\"===e?e=3*r+\"px,\"+r+\"px,\"+r+\"px,\"+r+\"px\":\"longdashdot\"===e&&(e=5*r+\"px,\"+2*r+\"px,\"+r+\"px,\"+2*r+\"px\"),t.style({\"stroke-dasharray\":e,\"stroke-width\":n+\"px\"})},p.fillGroupStyle=function(t){t.style(\"stroke-width\",0).each(function(e){var n=a.select(this);try{n.call(l.fill,e[0].trace.fillcolor)}catch(r){c.error(r,t),n.remove()}})};var g=t(\"./symbol_defs\");p.symbolNames=[],p.symbolFuncs=[],p.symbolNeedLines={},p.symbolNoDot={},p.symbolList=[],Object.keys(g).forEach(function(t){var e=g[t];p.symbolList=p.symbolList.concat([e.n,t,e.n+100,t+\"-open\"]),p.symbolNames[e.n]=t,p.symbolFuncs[e.n]=e.f,e.needLine&&(p.symbolNeedLines[e.n]=!0),e.noDot?p.symbolNoDot[e.n]=!0:p.symbolList=p.symbolList.concat([e.n+200,t+\"-dot\",e.n+300,t+\"-open-dot\"])});var v=p.symbolNames.length,m=\"M0,0.5L0.5,0L0,-0.5L-0.5,0Z\";p.symbolNumber=function(t){if(\"string\"==typeof t){var e=0;t.indexOf(\"-open\")>0&&(e=100,t=t.replace(\"-open\",\"\")),t.indexOf(\"-dot\")>0&&(e+=200,t=t.replace(\"-dot\",\"\")),t=p.symbolNames.indexOf(t),t>=0&&(t+=e)}return t%100>=v||t>=400?0:Math.floor(Math.max(t,0))},p.pointStyle=function(t,e){if(t.size()){var n=e.marker,r=n.line;if(i.traceIs(e,\"symbols\")){var o=h(e);t.attr(\"d\",function(t){var r;r=\"various\"===t.ms||\"various\"===n.size?3:d.isBubble(e)?o(t.ms):(n.size||6)/2,t.mrc=r;var a=p.symbolNumber(t.mx||n.symbol)||0,i=a%100;return t.om=a%200>=100,p.symbolFuncs[i](r)+(a>=200?m:\"\")}).style(\"opacity\",function(t){return(t.mo+1||n.opacity+1)-1})}var s=(e._input||{}).marker||{},c=p.tryColorscale(n,s,\"\"),u=p.tryColorscale(n,s,\"line.\");t.each(function(t){var e,o,i;t.so?(i=r.outlierwidth,o=r.outliercolor,e=n.outliercolor):(i=(t.mlw+1||r.width+1||(t.trace?t.trace.marker.line.width:0)+1)-1,o=\"mlc\"in t?t.mlcc=u(t.mlc):Array.isArray(r.color)?l.defaultLine:r.color,e=\"mc\"in t?t.mcc=c(t.mc):Array.isArray(n.color)?l.defaultLine:n.color||\"rgba(0,0,0,0)\");var s=a.select(this);t.om?s.call(l.stroke,e).style({\"stroke-width\":(i||1)+\"px\",fill:\"none\"}):(s.style(\"stroke-width\",i+\"px\").call(l.fill,e),i&&s.call(l.stroke,o))})}},p.tryColorscale=function(t,e,n){var r=c.nestedProperty(t,n+\"color\").get(),a=c.nestedProperty(t,n+\"colorscale\").get(),i=c.nestedProperty(t,n+\"cauto\").get(),l=c.nestedProperty(t,n+\"cmin\"),u=c.nestedProperty(t,n+\"cmax\"),f=l.get(),d=u.get();return a&&Array.isArray(r)?(!i&&o(f)&&o(d)||(f=1/0,d=-(1/0),r.forEach(function(t){o(t)&&(f>t&&(f=+t),t>d&&(d=+t))}),f>d&&(f=0,d=1),l.set(f),u.set(d),c.nestedProperty(e,n+\"cmin\").set(f),c.nestedProperty(e,n+\"cmax\").set(d)),s.makeScaleFunction(a,f,d)):c.identity};var y={start:1,end:-1,middle:0,bottom:1,top:-1},x=1.3;p.textPointStyle=function(t,e){t.each(function(t){var n=a.select(this),r=t.tx||e.text;if(!r||Array.isArray(r))return void n.remove();var i=t.tp||e.textposition,l=-1!==i.indexOf(\"top\")?\"top\":-1!==i.indexOf(\"bottom\")?\"bottom\":\"middle\",s=-1!==i.indexOf(\"left\")?\"end\":-1!==i.indexOf(\"right\")?\"start\":\"middle\",c=t.ts||e.textfont.size,f=t.mrc?t.mrc/.8+1:0;c=o(c)&&c>0?c:0,n.call(p.font,t.tf||e.textfont.family,c,t.tc||e.textfont.color).attr(\"text-anchor\",s).text(r).call(u.convertToTspans);var d=a.select(this.parentNode),h=n.selectAll(\"tspan.line\"),g=((h[0].length||1)-1)*x+1,v=y[s]*f,m=.75*c+y[l]*f+(y[l]-1)*g*c/2;d.attr(\"transform\",\"translate(\"+v+\",\"+m+\")\"),g>1&&h.attr({x:n.attr(\"x\"),y:n.attr(\"y\")})})};var b=.5;p.smoothopen=function(t,e){if(t.length<3)return\"M\"+t.join(\"L\");var n,a=\"M\"+t[0],o=[];for(n=1;n<t.length-1;n++)o.push(r(t[n-1],t[n],t[n+1],e));for(a+=\"Q\"+o[0][0]+\" \"+t[1],n=2;n<t.length-1;n++)a+=\"C\"+o[n-2][1]+\" \"+o[n-1][0]+\" \"+t[n];return a+=\"Q\"+o[t.length-3][1]+\" \"+t[t.length-1]},p.smoothclosed=function(t,e){if(t.length<3)return\"M\"+t.join(\"L\")+\"Z\";var n,a=\"M\"+t[0],o=t.length-1,i=[r(t[o],t[0],t[1],e)];for(n=1;o>n;n++)i.push(r(t[n-1],t[n],t[n+1],e));for(i.push(r(t[o-1],t[o],t[0],e)),n=1;o>=n;n++)a+=\"C\"+i[n-1][1]+\" \"+i[n][0]+\" \"+t[n];return a+=\"C\"+i[o][1]+\" \"+i[0][0]+\" \"+t[0]+\"Z\"};var _={hv:function(t,e){return\"H\"+a.round(e[0],2)+\"V\"+a.round(e[1],2)},vh:function(t,e){return\"V\"+a.round(e[1],2)+\"H\"+a.round(e[0],2)},hvh:function(t,e){return\"H\"+a.round((t[0]+e[0])/2,2)+\"V\"+a.round(e[1],2)+\"H\"+a.round(e[0],2)},vhv:function(t,e){return\"V\"+a.round((t[1]+e[1])/2,2)+\"H\"+a.round(e[0],2)+\"V\"+a.round(e[1],2)}},w=function(t,e){return\"L\"+a.round(e[0],2)+\",\"+a.round(e[1],2)};p.steps=function(t){var e=_[t]||w;return function(t){f" -, -"or(var n=\"M\"+a.round(t[0][0],2)+\",\"+a.round(t[0][1],2),r=1;r<t.length;r++)n+=e(t[r-1],t[r]);return n}},p.makeTester=function(t){var e=a.select(\"body\").selectAll(\"#js-plotly-tester\").data([0]);e.enter().append(\"svg\").attr(\"id\",\"js-plotly-tester\").attr(f.svgAttrs).style({position:\"absolute\",left:\"-10000px\",top:\"-10000px\",width:\"9000px\",height:\"9000px\",\"z-index\":\"1\"});var n=e.selectAll(\".js-reference-point\").data([0]);n.enter().append(\"path\").classed(\"js-reference-point\",!0).attr(\"d\",\"M0,0H1V1H0Z\").style({\"stroke-width\":0,fill:\"black\"}),e.node()._cache||(e.node()._cache={}),t._tester=e,t._testref=n};var k=[],M=1e4;p.bBox=function(t){var e=t.attributes[\"data-bb\"];if(e&&e.value)return c.extendFlat({},k[e.value]);var n=a.select(\"#js-plotly-tester\"),r=n.node(),o=t.cloneNode(!0);r.appendChild(o),a.select(o).attr({x:0,y:0,transform:\"\"});var i=o.getBoundingClientRect(),l=n.select(\".js-reference-point\").node().getBoundingClientRect();r.removeChild(o);var s={height:i.height,width:i.width,left:i.left-l.left,top:i.top-l.top,right:i.right-l.left,bottom:i.bottom-l.top};return k.length>=M&&(a.selectAll(\"[data-bb]\").attr(\"data-bb\",null),k=[]),t.setAttribute(\"data-bb\",k.length),k.push(s),c.extendFlat({},s)},p.setClipUrl=function(t,e){if(!e)return void t.attr(\"clip-path\",null);var n=\"#\"+e,r=a.select(\"base\");r.size()&&r.attr(\"href\")&&(n=window.location.href+n),t.attr(\"clip-path\",\"url(\"+n+\")\")}},{\"../../constants/xmlns_namespaces\":82,\"../../lib\":89,\"../../lib/svg_text_utils\":100,\"../../plots/plots\":130,\"../../traces/scatter/make_bubble_size_func\":181,\"../../traces/scatter/subtypes\":186,\"../color\":18,\"../colorscale\":32,\"./symbol_defs\":42,d3:9,\"fast-isnumeric\":11}],42:[function(t,e,n){\"use strict\";var r=t(\"d3\");e.exports={circle:{n:0,f:function(t){var e=r.round(t,2);return\"M\"+e+\",0A\"+e+\",\"+e+\" 0 1,1 0,-\"+e+\"A\"+e+\",\"+e+\" 0 0,1 \"+e+\",0Z\"}},square:{n:1,f:function(t){var e=r.round(t,2);return\"M\"+e+\",\"+e+\"H-\"+e+\"V-\"+e+\"H\"+e+\"Z\"}},diamond:{n:2,f:function(t){var e=r.round(1.3*t,2);return\"M\"+e+\",0L0,\"+e+\"L-\"+e+\",0L0,-\"+e+\"Z\"}},cross:{n:3,f:function(t){var e=r.round(.4*t,2),n=r.round(1.2*t,2);return\"M\"+n+\",\"+e+\"H\"+e+\"V\"+n+\"H-\"+e+\"V\"+e+\"H-\"+n+\"V-\"+e+\"H-\"+e+\"V-\"+n+\"H\"+e+\"V-\"+e+\"H\"+n+\"Z\"}},x:{n:4,f:function(t){var e=r.round(.8*t/Math.sqrt(2),2),n=\"l\"+e+\",\"+e,a=\"l\"+e+\",-\"+e,o=\"l-\"+e+\",-\"+e,i=\"l-\"+e+\",\"+e;return\"M0,\"+e+n+a+o+a+o+i+o+i+n+i+n+\"Z\"}},\"triangle-up\":{n:5,f:function(t){var e=r.round(2*t/Math.sqrt(3),2),n=r.round(t/2,2),a=r.round(t,2);return\"M-\"+e+\",\"+n+\"H\"+e+\"L0,-\"+a+\"Z\"}},\"triangle-down\":{n:6,f:function(t){var e=r.round(2*t/Math.sqrt(3),2),n=r.round(t/2,2),a=r.round(t,2);return\"M-\"+e+\",-\"+n+\"H\"+e+\"L0,\"+a+\"Z\"}},\"triangle-left\":{n:7,f:function(t){var e=r.round(2*t/Math.sqrt(3),2),n=r.round(t/2,2),a=r.round(t,2);return\"M\"+n+\",-\"+e+\"V\"+e+\"L-\"+a+\",0Z\"}},\"triangle-right\":{n:8,f:function(t){var e=r.round(2*t/Math.sqrt(3),2),n=r.round(t/2,2),a=r.round(t,2);return\"M-\"+n+\",-\"+e+\"V\"+e+\"L\"+a+\",0Z\"}},\"triangle-ne\":{n:9,f:function(t){var e=r.round(.6*t,2),n=r.round(1.2*t,2);return\"M-\"+n+\",-\"+e+\"H\"+e+\"V\"+n+\"Z\"}},\"triangle-se\":{n:10,f:function(t){var e=r.round(.6*t,2),n=r.round(1.2*t,2);return\"M\"+e+\",-\"+n+\"V\"+e+\"H-\"+n+\"Z\"}},\"triangle-sw\":{n:11,f:function(t){var e=r.round(.6*t,2),n=r.round(1.2*t,2);return\"M\"+n+\",\"+e+\"H-\"+e+\"V-\"+n+\"Z\"}},\"triangle-nw\":{n:12,f:function(t){var e=r.round(.6*t,2),n=r.round(1.2*t,2);return\"M-\"+e+\",\"+n+\"V-\"+e+\"H\"+n+\"Z\"}},pentagon:{n:13,f:function(t){var e=r.round(.951*t,2),n=r.round(.588*t,2),a=r.round(-t,2),o=r.round(t*-.309,2),i=r.round(.809*t,2);return\"M\"+e+\",\"+o+\"L\"+n+\",\"+i+\"H-\"+n+\"L-\"+e+\",\"+o+\"L0,\"+a+\"Z\"}},hexagon:{n:14,f:function(t){var e=r.round(t,2),n=r.round(t/2,2),a=r.round(t*Math.sqrt(3)/2,2);return\"M\"+a+\",-\"+n+\"V\"+n+\"L0,\"+e+\"L-\"+a+\",\"+n+\"V-\"+n+\"L0,-\"+e+\"Z\"}},hexagon2:{n:15,f:function(t){var e=r.round(t,2),n=r.round(t/2,2),a=r.round(t*Math.sqrt(3)/2,2);return\"M-\"+n+\",\"+a+\"H\"+n+\"L\"+e+\",0L\"+n+\",-\"+a+\"H-\"+n+\"L-\"+e+\",0Z\"}},octagon:{n:16,f:function(t){var e=r.round(.924*t,2),n=r.round(.383*t,2);return\"M-\"+n+\",-\"+e+\"H\"+n+\"L\"+e+\",-\"+n+\"V\"+n+\"L\"+n+\",\"+e+\"H-\"+n+\"L-\"+e+\",\"+n+\"V-\"+n+\"Z\"}},star:{n:17,f:function(t){var e=1.4*t,n=r.round(.225*e,2),a=r.round(.951*e,2),o=r.round(.363*e,2),i=r.round(.588*e,2),l=r.round(-e,2),s=r.round(e*-.309,2),c=r.round(.118*e,2),u=r.round(.809*e,2),f=r.round(.382*e,2);return\"M\"+n+\",\"+s+\"H\"+a+\"L\"+o+\",\"+c+\"L\"+i+\",\"+u+\"L0,\"+f+\"L-\"+i+\",\"+u+\"L-\"+o+\",\"+c+\"L-\"+a+\",\"+s+\"H-\"+n+\"L0,\"+l+\"Z\"}},hexagram:{n:18,f:function(t){var e=r.round(.66*t,2),n=r.round(.38*t,2),a=r.round(.76*t,2);return\"M-\"+a+\",0l-\"+n+\",-\"+e+\"h\"+a+\"l\"+n+\",-\"+e+\"l\"+n+\",\"+e+\"h\"+a+\"l-\"+n+\",\"+e+\"l\"+n+\",\"+e+\"h-\"+a+\"l-\"+n+\",\"+e+\"l-\"+n+\",-\"+e+\"h-\"+a+\"Z\"}},\"star-triangle-up\":{n:19,f:function(t){var e=r.round(t*Math.sqrt(3)*.8,2),n=r.round(.8*t,2),a=r.round(1.6*t,2),o=r.round(4*t,2),i=\"A \"+o+\",\"+o+\" 0 0 1 \";return\"M-\"+e+\",\"+n+i+e+\",\"+n+i+\"0,-\"+a+i+\"-\"+e+\",\"+n+\"Z\"}},\"star-triangle-down\":{n:20,f:function(t){var e=r.round(t*Math.sqrt(3)*.8,2),n=r.round(.8*t,2),a=r.round(1.6*t,2),o=r.round(4*t,2),i=\"A \"+o+\",\"+o+\" 0 0 1 \";return\"M\"+e+\",-\"+n+i+\"-\"+e+\",-\"+n+i+\"0,\"+a+i+e+\",-\"+n+\"Z\"}},\"star-square\":{n:21,f:function(t){var e=r.round(1.1*t,2),n=r.round(2*t,2),a=\"A \"+n+\",\"+n+\" 0 0 1 \";return\"M-\"+e+\",-\"+e+a+\"-\"+e+\",\"+e+a+e+\",\"+e+a+e+\",-\"+e+a+\"-\"+e+\",-\"+e+\"Z\"}},\"star-diamond\":{n:22,f:function(t){var e=r.round(1.4*t,2),n=r.round(1.9*t,2),a=\"A \"+n+\",\"+n+\" 0 0 1 \";return\"M-\"+e+\",0\"+a+\"0,\"+e+a+e+\",0\"+a+\"0,-\"+e+a+\"-\"+e+\",0Z\"}},\"diamond-tall\":{n:23,f:function(t){var e=r.round(.7*t,2),n=r.round(1.4*t,2);return\"M0,\"+n+\"L\"+e+\",0L0,-\"+n+\"L-\"+e+\",0Z\"}},\"diamond-wide\":{n:24,f:function(t){var e=r.round(1.4*t,2),n=r.round(.7*t,2);return\"M0,\"+n+\"L\"+e+\",0L0,-\"+n+\"L-\"+e+\",0Z\"}},hourglass:{n:25,f:function(t){var e=r.round(t,2);return\"M\"+e+\",\"+e+\"H-\"+e+\"L\"+e+\",-\"+e+\"H-\"+e+\"Z\"},noDot:!0},bowtie:{n:26,f:function(t){var e=r.round(t,2);return\"M\"+e+\",\"+e+\"V-\"+e+\"L-\"+e+\",\"+e+\"V-\"+e+\"Z\"},noDot:!0},\"circle-cross\":{n:27,f:function(t){var e=r.round(t,2);return\"M0,\"+e+\"V-\"+e+\"M\"+e+\",0H-\"+e+\"M\"+e+\",0A\"+e+\",\"+e+\" 0 1,1 0,-\"+e+\"A\"+e+\",\"+e+\" 0 0,1 \"+e+\",0Z\"},needLine:!0,noDot:!0},\"circle-x\":{n:28,f:function(t){var e=r.round(t,2),n=r.round(t/Math.sqrt(2),2);return\"M\"+n+\",\"+n+\"L-\"+n+\",-\"+n+\"M\"+n+\",-\"+n+\"L-\"+n+\",\"+n+\"M\"+e+\",0A\"+e+\",\"+e+\" 0 1,1 0,-\"+e+\"A\"+e+\",\"+e+\" 0 0,1 \"+e+\",0Z\"},needLine:!0,noDot:!0},\"square-cross\":{n:29,f:function(t){var e=r.round(t,2);return\"M0,\"+e+\"V-\"+e+\"M\"+e+\",0H-\"+e+\"M\"+e+\",\"+e+\"H-\"+e+\"V-\"+e+\"H\"+e+\"Z\"},needLine:!0,noDot:!0},\"square-x\":{n:30,f:function(t){var e=r.round(t,2);return\"M\"+e+\",\"+e+\"L-\"+e+\",-\"+e+\"M\"+e+\",-\"+e+\"L-\"+e+\",\"+e+\"M\"+e+\",\"+e+\"H-\"+e+\"V-\"+e+\"H\"+e+\"Z\"},needLine:!0,noDot:!0},\"diamond-cross\":{n:31,f:function(t){var e=r.round(1.3*t,2);return\"M\"+e+\",0L0,\"+e+\"L-\"+e+\",0L0,-\"+e+\"ZM0,-\"+e+\"V\"+e+\"M-\"+e+\",0H\"+e},needLine:!0,noDot:!0},\"diamond-x\":{n:32,f:function(t){var e=r.round(1.3*t,2),n=r.round(.65*t,2);return\"M\"+e+\",0L0,\"+e+\"L-\"+e+\",0L0,-\"+e+\"ZM-\"+n+\",-\"+n+\"L\"+n+\",\"+n+\"M-\"+n+\",\"+n+\"L\"+n+\",-\"+n},needLine:!0,noDot:!0},\"cross-thin\":{n:33,f:function(t){var e=r.round(1.4*t,2);return\"M0,\"+e+\"V-\"+e+\"M\"+e+\",0H-\"+e},needLine:!0,noDot:!0},\"x-thin\":{n:34,f:function(t){var e=r.round(t,2);return\"M\"+e+\",\"+e+\"L-\"+e+\",-\"+e+\"M\"+e+\",-\"+e+\"L-\"+e+\",\"+e},needLine:!0,noDot:!0},asterisk:{n:35,f:function(t){var e=r.round(1.2*t,2),n=r.round(.85*t,2);return\"M0,\"+e+\"V-\"+e+\"M\"+e+\",0H-\"+e+\"M\"+n+\",\"+n+\"L-\"+n+\",-\"+n+\"M\"+n+\",-\"+n+\"L-\"+n+\",\"+n},needLine:!0,noDot:!0},hash:{n:36,f:function(t){var e=r.round(t/2,2),n=r.round(t,2);return\"M\"+e+\",\"+n+\"V-\"+n+\"m-\"+n+\",0V\"+n+\"M\"+n+\",\"+e+\"H-\"+n+\"m0,-\"+n+\"H\"+n},needLine:!0},\"y-up\":{n:37,f:function(t){var e=r.round(1.2*t,2),n=r.round(1.6*t,2),a=r.round(.8*t,2);return\"M-\"+e+\",\"+a+\"L0,0M\"+e+\",\"+a+\"L0,0M0,-\"+n+\"L0,0\"},needLine:!0,noDot:!0},\"y-down\":{n:38,f:function(t){var e=r.round(1.2*t,2),n=r.round(1.6*t,2),a=r.round(.8*t,2);return\"M-\"+e+\",-\"+a+\"L0,0M\"+e+\",-\"+a+\"L0,0M0,\"+n+\"L0,0\"},needLine:!0,noDot:!0},\"y-left\":{n:39,f:function(t){var e=r.round(1.2*t,2),n=r.round(1.6*t,2),a=r.round(.8*t,2);return\"M\"+a+\",\"+e+\"L0,0M\"+a+\",-\"+e+\"L0,0M-\"+n+\",0L0,0\"},needLine:!0,noDot:!0},\"y-right\":{n:40,f:function(t){var e=r.round(1.2*t,2),n=r.round(1.6*t,2),a=r.round(.8*t,2);return\"M-\"+a+\",\"+e+\"L0,0M-\"+a+\",-\"+e+\"L0,0M\"+n+\",0L0,0\"},needLine:!0,noDot:!0},\"line-ew\":{n:41,f:function(t){var e=r.round(1.4*t,2);return\"M\"+e+\",0H-\"+e},needLine:!0,noDot:!0},\"line-ns\":{n:42,f:function(t){var e=r.round(1.4*t,2);return\"M0,\"+e+\"V-\"+e},needLine:!0,noDot:!0},\"line-ne\":{n:43,f:function(t){var e=r.round(t,2);return\"M\"+e+\",-\"+e+\"L-\"+e+\",\"+e},needLine:!0,noDot:!0},\"line-nw\":{n:44,f:function(t){var e=r.round(t,2);return\"M\"+e+\",\"+e+\"L-\"+e+\",-\"+e},needLine:!0,noDot:!0}}},{d3:9}],43:[function(t,e,n){\"use strict\";e.exports={visible:{valType:\"boolean\"},type:{valType:\"enumerated\",values:[\"percent\",\"constant\",\"sqrt\",\"data\"]},symmetric:{valType:\"boolean\"},array:{valType:\"data_array\"},arrayminus:{valType:\"data_array\"},value:{valType:\"number\",min:0,dflt:10},valueminus:{valType:\"number\",min:0,dflt:10},traceref:{valType:\"integer\",min:0,dflt:0},tracerefminus:{valType:\"integer\",min:0,dflt:0},copy_ystyle:{valType:\"boolean\"},copy_zstyle:{valType:\"boolean\"},color:{valType:\"color\"},thickness:{valType:\"number\",min:0,dflt:2},width:{valType:\"number\",min:0},_deprecated:{opacity:{valType:\"number\"}}}},{}],44:[function(t,e,n){\"use strict\";function r(t,e,n,r){var o=e[\"error_\"+r]||{},s=o.visible&&-1!==[\"linear\",\"log\"].indexOf(n.type),c=[];if(s){for(var u=l(o),f=0;f<t.length;f++){var d=t[f],h=d[r];if(a(n.c2l(h))){var p=u(h,f);if(a(p[0])&&a(p[1])){var g=d[r+\"s\"]=h-p[0],v=d[r+\"h\"]=h+p[1];c.push(g,v)}}}i.expand(n,c,{padded:!0})}}var a=t(\"fast-isnumeric\"),o=t(\"../../plots/plots\"),i=t(\"../../plots/cartesian/axes\"),l=t(\"./compute_error\");e.exports=function(t){for(var e=t.calcdata,n=0;n<e.length;n++){var a=e[n],l=a[0].trace;if(o.traceIs(l,\"errorBarsOK\")){var s=i.getFromId(t,l.xaxis),c=i.getFromId(t,l.yaxis);r(a,l,s,\"x\"),r(a,l,c,\"y\")}}}},{\"../../plots/cartesian/axes\":110,\"../../plots/plots\":130,\"./compute_error\":45,\"fast-isnumeric\":11}],45:[function(t,e,n){\"use strict\";function r(t,e){return\"percent\"===t?function(t){return Math.abs(t*e/10" -, -"0)}:\"constant\"===t?function(){return Math.abs(e)}:\"sqrt\"===t?function(t){return Math.sqrt(Math.abs(t))}:void 0}e.exports=function(t){var e=t.type,n=t.symmetric;if(\"data\"===e){var a=t.array,o=t.arrayminus;return n||void 0===o?function(t,e){var n=+a[e];return[n,n]}:function(t,e){return[+o[e],+a[e]]}}var i=r(e,t.value),l=r(e,t.valueminus);return n||void 0===t.valueminus?function(t){var e=i(t);return[e,e]}:function(t){return[l(t),i(t)]}}},{}],46:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\"),a=t(\"../../plots/plots\"),o=t(\"../../lib\"),i=t(\"./attributes\");e.exports=function(t,e,n,l){function s(t,e){return o.coerce(f,u,i,t,e)}var c=\"error_\"+l.axis,u=e[c]={},f=t[c]||{},d=void 0!==f.array||void 0!==f.value||\"sqrt\"===f.type,h=s(\"visible\",d);if(h!==!1){var p=s(\"type\",\"array\"in f?\"data\":\"percent\"),g=!0;if(\"sqrt\"!==p&&(g=s(\"symmetric\",!((\"data\"===p?\"arrayminus\":\"valueminus\")in f))),\"data\"===p){var v=s(\"array\");if(v||(u.array=[]),s(\"traceref\"),!g){var m=s(\"arrayminus\");m||(u.arrayminus=[]),s(\"tracerefminus\")}}else\"percent\"!==p&&\"constant\"!==p||(s(\"value\"),g||s(\"valueminus\"));var y=\"copy_\"+l.inherit+\"style\";if(l.inherit){var x=e[\"error_\"+l.inherit];(x||{}).visible&&s(y,!(f.color||r(f.thickness)||r(f.width)))}l.inherit&&u[y]||(s(\"color\",n),s(\"thickness\"),s(\"width\",a.traceIs(e,\"gl3d\")?0:4))}}},{\"../../lib\":89,\"../../plots/plots\":130,\"./attributes\":43,\"fast-isnumeric\":11}],47:[function(t,e,n){\"use strict\";var r=e.exports={};r.attributes=t(\"./attributes\"),r.supplyDefaults=t(\"./defaults\"),r.calc=t(\"./calc\"),r.calcFromTrace=function(t,e){for(var n=t.x||[],a=t.y,o=n.length||a.length,i=new Array(o),l=0;o>l;l++)i[l]={x:n[l],y:a[l]};return i[0].trace=t,r.calc({calcdata:[i],_fullLayout:e}),i},r.plot=t(\"./plot\"),r.style=t(\"./style\"),r.hoverInfo=function(t,e,n){(e.error_y||{}).visible&&(n.yerr=t.yh-t.y,e.error_y.symmetric||(n.yerrneg=t.y-t.ys)),(e.error_x||{}).visible&&(n.xerr=t.xh-t.x,e.error_x.symmetric||(n.xerrneg=t.x-t.xs))}},{\"./attributes\":43,\"./calc\":44,\"./defaults\":46,\"./plot\":48,\"./style\":49}],48:[function(t,e,n){\"use strict\";function r(t,e,n){var r={x:e.c2p(t.x),y:n.c2p(t.y)};return void 0!==t.yh&&(r.yh=n.c2p(t.yh),r.ys=n.c2p(t.ys),o(r.ys)||(r.noYS=!0,r.ys=n.c2p(t.ys,!0))),void 0!==t.xh&&(r.xh=e.c2p(t.xh),r.xs=e.c2p(t.xs),o(r.xs)||(r.noXS=!0,r.xs=e.c2p(t.xs,!0))),r}var a=t(\"d3\"),o=t(\"fast-isnumeric\"),i=t(\"../../lib\"),l=t(\"../../traces/scatter/subtypes\");e.exports=function(t,e){var n=e.x(),s=e.y();t.each(function(t){var e=t[0].trace,c=e.error_x||{},u=e.error_y||{},f=l.hasMarkers(e)&&e.marker.maxdisplayed>0;if(u.visible||c.visible){var d=a.select(this).selectAll(\"g.errorbar\").data(i.identity);d.enter().append(\"g\").classed(\"errorbar\",!0),d.each(function(t){var e=a.select(this),i=r(t,n,s);if(!f||t.vis){var l;if(u.visible&&o(i.x)&&o(i.yh)&&o(i.ys)){var d=u.width;l=\"M\"+(i.x-d)+\",\"+i.yh+\"h\"+2*d+\"m-\"+d+\",0V\"+i.ys,i.noYS||(l+=\"m-\"+d+\",0h\"+2*d),e.append(\"path\").classed(\"yerror\",!0).attr(\"d\",l)}if(c.visible&&o(i.y)&&o(i.xh)&&o(i.xs)){var h=(c.copy_ystyle?u:c).width;l=\"M\"+i.xh+\",\"+(i.y-h)+\"v\"+2*h+\"m0,-\"+h+\"H\"+i.xs,i.noXS||(l+=\"m0,-\"+h+\"v\"+2*h),e.append(\"path\").classed(\"xerror\",!0).attr(\"d\",l)}}})}})}},{\"../../lib\":89,\"../../traces/scatter/subtypes\":186,d3:9,\"fast-isnumeric\":11}],49:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"../color\");e.exports=function(t){t.each(function(t){var e=t[0].trace,n=e.error_y||{},o=e.error_x||{},i=r.select(this);i.selectAll(\"path.yerror\").style(\"stroke-width\",n.thickness+\"px\").call(a.stroke,n.color),o.copy_ystyle&&(o=n),i.selectAll(\"path.xerror\").style(\"stroke-width\",o.thickness+\"px\").call(a.stroke,o.color)})}},{\"../color\":18,d3:9}],50:[function(t,e,n){\"use strict\";var r=t(\"../../plots/cartesian/constants\");e.exports={_isLinkedToArray:!0,source:{valType:\"string\"},layer:{valType:\"enumerated\",values:[\"below\",\"above\"],dflt:\"above\"},sizex:{valType:\"number\",dflt:0},sizey:{valType:\"number\",dflt:0},sizing:{valType:\"enumerated\",values:[\"fill\",\"contain\",\"stretch\"],dflt:\"contain\"},opacity:{valType:\"number\",min:0,max:1,dflt:1},x:{valType:\"number\",dflt:0},y:{valType:\"number\",dflt:0},xanchor:{valType:\"enumerated\",values:[\"left\",\"center\",\"right\"],dflt:\"left\"},yanchor:{valType:\"enumerated\",values:[\"top\",\"middle\",\"bottom\"],dflt:\"top\"},xref:{valType:\"enumerated\",values:[\"paper\",r.idRegex.x.toString()],dflt:\"paper\"},yref:{valType:\"enumerated\",values:[\"paper\",r.idRegex.y.toString()],dflt:\"paper\"}}},{\"../../plots/cartesian/constants\":115}],51:[function(t,e,n){\"use strict\";function r(t,e,n){function r(n,r){return o.coerce(t,e,i,n,r)}e=e||{},r(\"source\"),r(\"layer\"),r(\"x\"),r(\"y\"),r(\"xanchor\"),r(\"yanchor\"),r(\"sizex\"),r(\"sizey\"),r(\"sizing\"),r(\"opacity\");for(var l=0;2>l;l++){var s={_fullLayout:n},c=[\"x\",\"y\"][l];a.coerceRef(t,e,s,c,\"paper\")}return e}var a=t(\"../../plots/cartesian/axes\"),o=t(\"../../lib\"),i=t(\"./attributes\");e.exports=function(t,e){if(t.images&&Array.isArray(t.images))for(var n=t.images,a=e.images=[],o=0;o<n.length;o++){var i=n[o];if(i.source){var l=r(n[o]||{},a[o]||{},e);a.push(l)}}}},{\"../../lib\":89,\"../../plots/cartesian/axes\":110,\"./attributes\":50}],52:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"../drawing\"),o=t(\"../../plots/cartesian/axes\");e.exports=function(t){function e(e){var n=r.select(this),a=new Promise(function(t){function r(){n.remove(),t()}var a=new Image;a.setAttribute(\"crossOrigin\",\"anonymous\"),a.onerror=r,a.onload=function(){var t=document.createElement(\"canvas\");t.width=this.width,t.height=this.height;var e=t.getContext(\"2d\");e.drawImage(this,0,0);var r=t.toDataURL(\"image/png\");n.attr(\"xlink:href\",r)},n.on(\"error\",r),n.on(\"load\",t),a.src=e.source});t._promises.push(a)}function n(e){var n=r.select(this),i=o.getFromId(t,e.xref),s=o.getFromId(t,e.yref),c=l._size,u=i?Math.abs(i.l2p(e.sizex)-i.l2p(0)):e.sizex*c.w,f=s?Math.abs(s.l2p(e.sizey)-s.l2p(0)):e.sizey*c.h,d=u*h.x[e.xanchor].offset+c.l,p=f*h.y[e.yanchor].offset+c.t,g=h.x[e.xanchor].sizing+h.y[e.yanchor].sizing,v=(i?i.l2p(e.x):e.x*c.w)+d,m=(s?s.l2p(e.y):c.h-e.y*c.h)+p;switch(e.sizing){case\"fill\":g+=\" slice\";break;case\"stretch\":g=\"none\"}n.attr({x:v,y:m,width:u,height:f,preserveAspectRatio:g,opacity:e.opacity});var y=i?i._id:\"\",x=s?s._id:\"\",b=y+x;n.call(a.setClipUrl,\"clip\"+l._uid+b)}function i(t,e){return t.source+e}var l=t._fullLayout,s=[],c=[],u=[];if(l.images){for(var f=0;f<l.images.length;f++){var d=l.images[f];\"below\"===d.layer&&\"paper\"!==d.xref&&\"paper\"!==d.yref?c.push(d):\"above\"===d.layer?s.push(d):u.push(d)}var h={x:{left:{sizing:\"xMin\",offset:0},center:{sizing:\"xMid\",offset:-0.5},right:{sizing:\"xMax\",offset:-1}},y:{top:{sizing:\"YMin\",offset:0},middle:{sizing:\"YMid\",offset:-0.5},bottom:{sizing:\"YMax\",offset:-1}}},p=l._imageLowerLayer.selectAll(\"image\").data(u,i),g=l._imageSubplotLayer.selectAll(\"image\").data(c,i),v=l._imageUpperLayer.selectAll(\"image\").data(s,i);p.enter().append(\"image\").each(e),g.enter().append(\"image\").each(e),v.enter().append(\"image\").each(e),p.exit().remove(),g.exit().remove(),v.exit().remove(),p.each(n),g.each(n),v.each(n)}}},{\"../../plots/cartesian/axes\":110,\"../drawing\":41,d3:9}],53:[function(t,e,n){\"use strict\";var r=t(\"./draw\"),a=t(\"./defaults\"),o=t(\"./attributes\");e.exports={draw:r,layoutAttributes:o,supplyLayoutDefaults:a}},{\"./attributes\":50,\"./defaults\":51,\"./draw\":52}],54:[function(t,e,n){\"use strict\";n.isRightAnchor=function(t){return\"right\"===t.xanchor||\"auto\"===t.xanchor&&t.x>=2/3},n.isCenterAnchor=function(t){return\"center\"===t.xanchor||\"auto\"===t.xanchor&&t.x>1/3&&t.x<2/3},n.isBottomAnchor=function(t){return\"bottom\"===t.yanchor||\"auto\"===t.yanchor&&t.y<=1/3},n.isMiddleAnchor=function(t){return\"middle\"===t.yanchor||\"auto\"===t.yanchor&&t.y>1/3&&t.y<2/3}},{}],55:[function(t,e,n){\"use strict\";var r=t(\"../../plots/font_attributes\"),a=t(\"../color/attributes\"),o=t(\"../../lib/extend\").extendFlat;e.exports={bgcolor:{valType:\"color\"},bordercolor:{valType:\"color\",dflt:a.defaultLine},borderwidth:{valType:\"number\",min:0,dflt:0},font:o({},r,{}),orientation:{valType:\"enumerated\",values:[\"v\",\"h\"],dflt:\"v\"},traceorder:{valType:\"flaglist\",flags:[\"reversed\",\"grouped\"],extras:[\"normal\"]},tracegroupgap:{valType:\"number\",min:0,dflt:10},x:{valType:\"number\",min:-2,max:3,dflt:1.02},xanchor:{valType:\"enumerated\",values:[\"auto\",\"left\",\"center\",\"right\"],dflt:\"left\"},y:{valType:\"number\",min:-2,max:3,dflt:1},yanchor:{valType:\"enumerated\",values:[\"auto\",\"top\",\"middle\",\"bottom\"],dflt:\"auto\"}}},{\"../../lib/extend\":88,\"../../plots/font_attributes\":128,\"../color/attributes\":17}],56:[function(t,e,n){\"use strict\";e.exports={scrollBarWidth:4,scrollBarHeight:20,scrollBarColor:\"#808BA4\",scrollBarMargin:4}},{}],57:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"../../plots/plots\"),o=t(\"./attributes\"),i=t(\"./helpers\");e.exports=function(t,e,n){function l(t,e){return r.coerce(d,h,o,t,e)}for(var s,c,u,f,d=t.legend||{},h=e.legend={},p=0,g=\"normal\",v=0;v<n.length;v++){var m=n[v];i.legendGetsTrace(m)&&(p++,a.traceIs(m,\"pie\")&&p++),(a.traceIs(m,\"bar\")&&\"stack\"===e.barmode||-1!==[\"tonextx\",\"tonexty\"].indexOf(m.fill))&&(g=i.isGrouped({traceorder:g})?\"grouped+reversed\":\"reversed\"),void 0!==m.legendgroup&&\"\"!==m.legendgroup&&(g=i.isReversed({traceorder:g})?\"reversed+grouped\":\"grouped\")}var y=r.coerce(t,e,a.layoutAttributes,\"showlegend\",p>1);if(y!==!1){if(l(\"bgcolor\",e.paper_bgcolor),l(\"bordercolor\"),l(\"borderwidth\"),r.coerceFont(l,\"font\",e.font),l(\"orientation\"),\"h\"===h.orientation){var x=t.xaxis;x&&x.rangeslider&&x.rangeslider.visible?(s=0,u=\"left\",c=1.1,f=\"bottom\"):(s=0,u=\"left\",c=-.1,f=\"top\")}l(\"traceorder\",g),i.isGrouped(e.legend)&&l(\"tracegroupgap\"),l(\"x\",s),l(\"xanchor\",u),l(\"y\",c),l(\"yanchor\",f),r.noneOrAll(d,h,[\"x\",\"y\"])}}},{\"../../lib\":89,\"../../plots/plots\":130,\"./attributes\":55,\"./helpers\":60}],58:[function(t,e,n){\"use strict\";function r(t,e){function n(n){u.util.convertToTspans(n,function(){n.selectAll(\"tspan.line\").attr({x:n.attr(\"x\")}),t.call(o,e)})}var r=t.data()[0][0],a=e._fullLayout,i=r.trace,l=d.traceIs(i,\"pie\"),s=i.index,c=l?r.label:i.name,f=t.selectAll(\"text.legendtext\").data([0]);f.enter().append(\"text\").classed(\"legen" -, -"dtext\",!0),f.attr({x:40,y:0,\"data-unformatted\":c}).style(\"text-anchor\",\"start\").classed(\"user-select-none\",!0).call(p.font,a.legend.font).text(c),e._context.editable&&!l?f.call(u.util.makeEditable).call(n).on(\"edit\",function(t){this.attr({\"data-unformatted\":t}),this.text(t).call(n),this.text()||(t=\" \"),u.restyle(e,\"name\",t,s)}):f.call(n)}function a(t,e){var n=e._fullLayout.hiddenlabels?e._fullLayout.hiddenlabels.slice():[],r=t.selectAll(\"rect\").data([0]);r.enter().append(\"rect\").classed(\"legendtoggle\",!0).style(\"cursor\",\"pointer\").attr(\"pointer-events\",\"all\").call(g.fill,\"rgba(0,0,0,0)\"),r.on(\"click\",function(){if(!e._dragged){var r,a,o=t.data()[0][0],i=e._fullData,l=o.trace,s=l.legendgroup,c=[];if(d.traceIs(l,\"pie\")){var f=o.label,h=n.indexOf(f);-1===h?n.push(f):n.splice(h,1),u.relayout(e,\"hiddenlabels\",n)}else{if(\"\"===s)c=[l.index];else for(var p=0;p<i.length;p++)r=i[p],r.legendgroup===s&&c.push(r.index);a=l.visible===!0?\"legendonly\":!0,u.restyle(e,\"visible\",a,c)}}})}function o(t,e){var n,r,a=t.data()[0][0],o=t.selectAll(\".legendtoggle\"),i=t.select(\"g[class*=math-group]\"),l=e._fullLayout.legend,s=1.3*l.font.size;if(!a.trace.showlegend)return void t.remove();if(i.node()){var c=p.bBox(i.node());n=c.height,r=c.width,f.setTranslate(i,0,n/4)}else{var u=t.selectAll(\".legendtext\"),d=t.selectAll(\".legendtext>tspan\"),h=d[0].length||1;n=s*h,r=u.node()&&p.bBox(u.node()).width;var g=s*(.3+(1-h)/2);u.attr(\"y\",g),d.attr(\"y\",g)}n=Math.max(n,16)+3,o.attr({x:0,y:-n/2,height:n}),a.height=n,a.width=r}function i(t,e,n){var r=t._fullLayout,a=r.legend,o=a.borderwidth,i=x.isGrouped(a);if(x.isVertical(a))i&&e.each(function(t,e){f.setTranslate(this,0,e*a.tracegroupgap)}),a.width=0,a.height=0,n.each(function(t){var e=t[0],n=e.height,r=e.width;f.setTranslate(this,o,5+o+a.height+n/2),a.height+=n,a.width=Math.max(a.width,r)}),a.width+=45+2*o,a.height+=10+2*o,i&&(a.height+=(a._lgroupsLength-1)*a.tracegroupgap),n.selectAll(\".legendtoggle\").attr(\"width\",(t._context.editable?0:a.width)+40),a.width=Math.ceil(a.width),\n" -, -"a.height=Math.ceil(a.height);else if(i){a.width=0,a.height=0;for(var l=[a.width],s=e.data(),u=0,d=s.length;d>u;u++){var h=s[u].map(function(t){return t[0].width}),p=40+Math.max.apply(null,h);a.width+=a.tracegroupgap+p,l.push(a.width)}e.each(function(t,e){f.setTranslate(this,l[e],0)}),e.each(function(){var t=c.select(this),e=t.selectAll(\"g.traces\"),n=0;e.each(function(t){var e=t[0],r=e.height;f.setTranslate(this,0,5+o+n+r/2),n+=r}),a.height=Math.max(a.height,n)}),a.height+=10+2*o,a.width+=2*o,a.width=Math.ceil(a.width),a.height=Math.ceil(a.height),n.selectAll(\".legendtoggle\").attr(\"width\",t._context.editable?0:a.width)}else a.width=0,a.height=0,n.each(function(t){var e=t[0],n=40+e.width,r=a.tracegroupgap||5;f.setTranslate(this,o+a.width,5+o+e.height/2),a.width+=r+n,a.height=Math.max(a.height,e.height)}),a.width+=2*o,a.height+=10+2*o,a.width=Math.ceil(a.width),a.height=Math.ceil(a.height),n.selectAll(\".legendtoggle\").attr(\"width\",t._context.editable?0:a.width)}function l(t){var e=t._fullLayout,n=e.legend,r=\"left\";b.isRightAnchor(n)?r=\"right\":b.isCenterAnchor(n)&&(r=\"center\");var a=\"top\";b.isBottomAnchor(n)?a=\"bottom\":b.isMiddleAnchor(n)&&(a=\"middle\"),d.autoMargin(t,\"legend\",{x:n.x,y:n.y,l:n.width*({right:1,center:.5}[r]||0),r:n.width*({left:1,center:.5}[r]||0),b:n.height*({top:1,middle:.5}[a]||0),t:n.height*({bottom:1,middle:.5}[a]||0)})}function s(t){var e=t._fullLayout,n=e.legend,r=\"left\";b.isRightAnchor(n)?r=\"right\":b.isCenterAnchor(n)&&(r=\"center\"),d.autoMargin(t,\"legend\",{x:n.x,y:.5,l:n.width*({right:1,center:.5}[r]||0),r:n.width*({left:1,center:.5}[r]||0),b:0,t:0})}var c=t(\"d3\"),u=t(\"../../plotly\"),f=t(\"../../lib\"),d=t(\"../../plots/plots\"),h=t(\"../dragelement\"),p=t(\"../drawing\"),g=t(\"../color\"),v=t(\"./constants\"),m=t(\"./get_legend_data\"),y=t(\"./style\"),x=t(\"./helpers\"),b=t(\"./anchor_utils\");e.exports=function(t){function e(t,e){L.attr(\"data-scroll\",e).call(f.setTranslate,0,e),T.call(p.setRect,j,t,v.scrollBarWidth,v.scrollBarHeight),M.select(\"rect\").attr({y:x.borderwidth-e})}var n=t._fullLayout,o=\"legend\"+n._uid;if(n._infolayer&&t.calcdata){var x=n.legend,_=n.showlegend&&m(t.calcdata,x),w=n.hiddenlabels||[];if(!n.showlegend||!_.length)return n._infolayer.selectAll(\".legend\").remove(),n._topdefs.select(\"#\"+o).remove(),void d.autoMargin(t,\"legend\");var k=n._infolayer.selectAll(\"g.legend\").data([0]);k.enter().append(\"g\").attr({\"class\":\"legend\",\"pointer-events\":\"all\"});var M=n._topdefs.selectAll(\"#\"+o).data([0]);M.enter().append(\"clipPath\").attr(\"id\",o).append(\"rect\");var A=k.selectAll(\"rect.bg\").data([0]);A.enter().append(\"rect\").attr({\"class\":\"bg\",\"shape-rendering\":\"crispEdges\"}),A.call(g.stroke,x.bordercolor),A.call(g.fill,x.bgcolor),A.style(\"stroke-width\",x.borderwidth+\"px\");var L=k.selectAll(\"g.scrollbox\").data([0]);L.enter().append(\"g\").attr(\"class\",\"scrollbox\");var T=k.selectAll(\"rect.scrollbar\").data([0]);T.enter().append(\"rect\").attr({\"class\":\"scrollbar\",rx:20,ry:2,width:0,height:0}).call(g.fill,\"#808BA4\");var z=L.selectAll(\"g.groups\").data(_);z.enter().append(\"g\").attr(\"class\",\"groups\"),z.exit().remove();var S=z.selectAll(\"g.traces\").data(f.identity);S.enter().append(\"g\").attr(\"class\",\"traces\"),S.exit().remove(),S.call(y).style(\"opacity\",function(t){var e=t[0].trace;return d.traceIs(e,\"pie\")?-1!==w.indexOf(t[0].label)?.5:1:\"legendonly\"===e.visible?.5:1}).each(function(){c.select(this).call(r,t).call(a,t)});var E=0!==k.enter().size();E&&(i(t,z,S),l(t));var C=0,O=n.width,P=0,N=n.height;i(t,z,S),x.height>N?s(t):l(t);var D=n._size,I=D.l+D.w*x.x,R=D.t+D.h*(1-x.y);b.isRightAnchor(x)?I-=x.width:b.isCenterAnchor(x)&&(I-=x.width/2),b.isBottomAnchor(x)?R-=x.height:b.isMiddleAnchor(x)&&(R-=x.height/2);var j=x.width,q=D.w;j>q?(I=D.l,j=q):(I+j>O&&(I=O-j),C>I&&(I=C),j=Math.min(O-I,x.width));var F=x.height,B=D.h;F>B?(R=D.t,F=B):(R+F>N&&(R=N-F),P>R&&(R=P),F=Math.min(N-R,x.height)),f.setTranslate(k,I,R);var H,V,Z=F-v.scrollBarHeight-2*v.scrollBarMargin,Y=x.height-F;if(x.height<=F||t._context.staticPlot)A.attr({width:j-x.borderwidth,height:F-x.borderwidth,x:x.borderwidth/2,y:x.borderwidth/2}),f.setTranslate(L,0,0),M.select(\"rect\").attr({width:j-2*x.borderwidth,height:F-2*x.borderwidth,x:x.borderwidth,y:x.borderwidth}),L.call(p.setClipUrl,o);else{H=v.scrollBarMargin,V=L.attr(\"data-scroll\")||0,A.attr({width:j-2*x.borderwidth+v.scrollBarWidth+v.scrollBarMargin,height:F-x.borderwidth,x:x.borderwidth/2,y:x.borderwidth/2}),M.select(\"rect\").attr({width:j-2*x.borderwidth+v.scrollBarWidth+v.scrollBarMargin,height:F-2*x.borderwidth,x:x.borderwidth,y:x.borderwidth-V}),L.call(p.setClipUrl,o),E&&e(H,V),k.on(\"wheel\",null),k.on(\"wheel\",function(){V=f.constrain(L.attr(\"data-scroll\")-c.event.deltaY/Z*Y,-Y,0),H=v.scrollBarMargin-V/Y*Z,e(H,V),c.event.preventDefault()}),T.on(\".drag\",null),L.on(\".drag\",null);var U=c.behavior.drag().on(\"drag\",function(){H=f.constrain(c.event.y-v.scrollBarHeight/2,v.scrollBarMargin,v.scrollBarMargin+Z),V=-(H-v.scrollBarMargin)/Z*Y,e(H,V)});T.call(U),L.call(U)}if(t._context.editable){var X,G,$,Q;k.classed(\"cursor-move\",!0),h.init({element:k.node(),prepFn:function(){var t=f.getTranslate(k);$=t.x,Q=t.y},moveFn:function(t,e){var n=$+t,r=Q+e;f.setTranslate(k,n,r),X=h.align(n,0,D.l,D.l+D.w,x.xanchor),G=h.align(r,0,D.t+D.h,D.t,x.yanchor)},doneFn:function(e){e&&void 0!==X&&void 0!==G&&u.relayout(t,{\"legend.x\":X,\"legend.y\":G})}})}}}},{\"../../lib\":89,\"../../plotly\":107,\"../../plots/plots\":130,\"../color\":18,\"../dragelement\":39,\"../drawing\":41,\"./anchor_utils\":54,\"./constants\":56,\"./get_legend_data\":59,\"./helpers\":60,\"./style\":62,d3:9}],59:[function(t,e,n){\"use strict\";var r=t(\"../../plots/plots\"),a=t(\"./helpers\");e.exports=function(t,e){function n(t,n){if(\"\"!==t&&a.isGrouped(e))-1===s.indexOf(t)?(s.push(t),c=!0,l[t]=[[n]]):l[t].push([n]);else{var r=\"~~i\"+f;s.push(r),l[r]=[[n]],f++}}var o,i,l={},s=[],c=!1,u={},f=0;for(o=0;o<t.length;o++){var d=t[o],h=d[0],p=h.trace,g=p.legendgroup;if(a.legendGetsTrace(p)&&p.showlegend)if(r.traceIs(p,\"pie\"))for(u[g]||(u[g]={}),i=0;i<d.length;i++){var v=d[i].label;u[g][v]||(n(g,{label:v,color:d[i].color,i:d[i].i,trace:p}),u[g][v]=!0)}else n(g,h)}if(!s.length)return[];var m,y,x=s.length;if(c&&a.isGrouped(e))for(y=new Array(x),o=0;x>o;o++)m=l[s[o]],y[o]=a.isReversed(e)?m.reverse():m;else{for(y=[new Array(x)],o=0;x>o;o++)m=l[s[o]][0],y[0][a.isReversed(e)?x-o-1:o]=m;x=1}return e._lgroupsLength=x,y}},{\"../../plots/plots\":130,\"./helpers\":60}],60:[function(t,e,n){\"use strict\";var r=t(\"../../plots/plots\");n.legendGetsTrace=function(t){return t.visible&&r.traceIs(t,\"showLegend\")},n.isGrouped=function(t){return-1!==(t.traceorder||\"\").indexOf(\"grouped\")},n.isVertical=function(t){return\"h\"!==t.orientation},n.isReversed=function(t){return-1!==(t.traceorder||\"\").indexOf(\"reversed\")}},{\"../../plots/plots\":130}],61:[function(t,e,n){\"use strict\";var r=e.exports={};r.layoutAttributes=t(\"./attributes\"),r.supplyLayoutDefaults=t(\"./defaults\"),r.draw=t(\"./draw\"),r.style=t(\"./style\")},{\"./attributes\":55,\"./defaults\":57,\"./draw\":58,\"./style\":62}],62:[function(t,e,n){\"use strict\";function r(t){var e=t[0].trace,n=e.visible&&e.fill&&\"none\"!==e.fill,r=h.hasLines(e),a=s.select(this).select(\".legendfill\").selectAll(\"path\").data(n?[t]:[]);a.enter().append(\"path\").classed(\"js-fill\",!0),a.exit().remove(),a.attr(\"d\",\"M5,0h30v6h-30z\").call(f.fillGroupStyle);var o=s.select(this).select(\".legendlines\").selectAll(\"path\").data(r?[t]:[]);o.enter().append(\"path\").classed(\"js-line\",!0).attr(\"d\",\"M5,0h30\"),o.exit().remove(),o.call(f.lineGroupStyle)}function a(t){function e(t,e,n){var r=c.nestedProperty(i,t).get(),a=Array.isArray(r)&&e?e(r):r;if(n){if(a<n[0])return n[0];if(a>n[1])return n[1]}return a}function n(t){return t[0]}var r,a,o=t[0],i=o.trace,l=h.hasMarkers(i),u=h.hasText(i),d=h.hasLines(i);if(l||u||d){var p={},g={};l&&(p.mc=e(\"marker.color\",n),p.mo=e(\"marker.opacity\",c.mean,[.2,1]),p.ms=e(\"marker.size\",c.mean,[2,16]),p.mlc=e(\"marker.line.color\",n),p.mlw=e(\"marker.line.width\",c.mean,[0,5]),g.marker={sizeref:1,sizemin:1,sizemode:\"diameter\"}),d&&(g.line={width:e(\"line.width\",n,[0,10])}),u&&(p.tx=\"Aa\",p.tp=e(\"textposition\",n),p.ts=10,p.tc=e(\"textfont.color\",n),p.tf=e(\"textfont.family\",n)),r=[c.minExtend(o,p)],a=c.minExtend(i,g)}var v=s.select(this).select(\"g.legendpoints\"),m=v.selectAll(\"path.scatterpts\").data(l?r:[]);m.enter().append(\"path\").classed(\"scatterpts\",!0).attr(\"transform\",\"translate(20,0)\"),m.exit().remove(),m.call(f.pointStyle,a),l&&(r[0].mrc=3);var y=v.selectAll(\"g.pointtext\").data(u?r:[]);y.enter().append(\"g\").classed(\"pointtext\",!0).append(\"text\").attr(\"transform\",\"translate(20,0)\"),y.exit().remove(),y.selectAll(\"text\").call(f.textPointStyle,a)}function o(t){var e=t[0].trace,n=e.marker||{},r=n.line||{},a=s.select(this).select(\"g.legendpoints\").selectAll(\"path.legendbar\").data(u.traceIs(e,\"bar\")?[t]:[]);a.enter().append(\"path\").classed(\"legendbar\",!0).attr(\"d\",\"M6,6H-6V-6H6Z\").attr(\"transform\",\"translate(20,0)\"),a.exit().remove(),a.each(function(t){var e=(t.mlw+1||r.width+1)-1,a=s.select(this);a.style(\"stroke-width\",e+\"px\").call(d.fill,t.mc||n.color),e&&a.call(d.stroke,t.mlc||r.color)})}function i(t){var e=t[0].trace,n=s.select(this).select(\"g.legendpoints\").selectAll(\"path.legendbox\").data(u.traceIs(e,\"box\")&&e.visible?[t]:[]);n.enter().append(\"path\").classed(\"legendbox\",!0).attr(\"d\",\"M6,6H-6V-6H6Z\").attr(\"transform\",\"translate(20,0)\"),n.exit().remove(),n.each(function(t){var n=(t.lw+1||e.line.width+1)-1,r=s.select(this);r.style(\"stroke-width\",n+\"px\").call(d.fill,t.fc||e.fillcolor),n&&r.call(d.stroke,t.lc||e.line.color)})}function l(t){var e=t[0].trace,n=s.select(this).select(\"g.legendpoints\").selectAll(\"path.legendpie\").data(u.traceIs(e,\"pie\")&&e.visible?[t]:[]);n.enter().append(\"path\").classed(\"legendpie\",!0).attr(\"d\",\"M6,6H-6V-6H6Z\").attr(\"transform\",\"translate(20,0)\"),n.exit().remove(),n.size()&&n.call(p,t[0],e)}var s=t(\"d3\"),c=t(\"../../lib\"),u=t(\"../../plots/plots\"),f=t(\"../drawing\"),d=t(\"../color\"),h=t(\"../../traces/scatter/subtypes\"),p=t(\"../../traces/pie/style_one\");e.exports=function(t){t.each(functio" -, -"n(t){var e=s.select(this),n=e.selectAll(\"g.legendfill\").data([t]);n.enter().append(\"g\").classed(\"legendfill\",!0);var r=e.selectAll(\"g.legendlines\").data([t]);r.enter().append(\"g\").classed(\"legendlines\",!0);var a=e.selectAll(\"g.legendsymbols\").data([t]);a.enter().append(\"g\").classed(\"legendsymbols\",!0),a.style(\"opacity\",t[0].trace.opacity),a.selectAll(\"g.legendpoints\").data([t]).enter().append(\"g\").classed(\"legendpoints\",!0)}).each(o).each(i).each(l).each(r).each(a)}},{\"../../lib\":89,\"../../plots/plots\":130,\"../../traces/pie/style_one\":165,\"../../traces/scatter/subtypes\":186,\"../color\":18,\"../drawing\":41,d3:9}],63:[function(t,e,n){\"use strict\";function r(t,e){var n=e.currentTarget,r=n.getAttribute(\"data-attr\"),a=n.getAttribute(\"data-val\")||!0,o=t._fullLayout,i={};if(\"zoom\"===r){for(var l,s,u=\"in\"===a?.5:2,f=(1+u)/2,d=(1-u)/2,h=c.Axes.list(t,null,!0),p=0;p<h.length;p++)if(l=h[p],!l.fixedrange)if(s=l._name,\"auto\"===a)i[s+\".autorange\"]=!0;else if(\"reset\"===a)if(void 0===l._rangeInitial)i[s+\".autorange\"]=!0;else{var g=l._rangeInitial.slice();i[s+\".range[0]\"]=g[0],i[s+\".range[1]\"]=g[1]}else{var v=l.range;i[s+\".range[0]\"]=f*v[0]+d*v[1],i[s+\".range[1]\"]=f*v[1]+d*v[0]}}else\"hovermode\"!==r||\"x\"!==a&&\"y\"!==a||(a=o._isHoriz?\"y\":\"x\",n.setAttribute(\"data-val\",a)),i[r]=a;c.relayout(t,i)}function a(t,e){for(var n=e.currentTarget,r=n.getAttribute(\"data-attr\"),a=n.getAttribute(\"data-val\")||!0,o=t._fullLayout,i=c.Plots.getSubplotIds(o,\"gl3d\"),l={},s=r.split(\".\"),u=0;u<i.length;u++)l[i[u]+\".\"+s[1]]=a;c.relayout(t,l)}function o(t,e){for(var n=e.currentTarget,r=n.getAttribute(\"data-attr\"),a=t._fullLayout,o=c.Plots.getSubplotIds(a,\"gl3d\"),i=0;i<o.length;i++){var l=o[i],s=a[l],u=s._scene;\"resetDefault\"===r?u.setCameraToDefault():\"resetLastSave\"===r&&u.setCamera(s.camera)}}function i(t,e){var n=e.currentTarget,r=n._previousVal||!1,a=t.layout,o=t._fullLayout,i=c.Plots.getSubplotIds(o,\"gl3d\"),l=[\"xaxis\",\"yaxis\",\"zaxis\"],s=[\"showspikes\",\"spikesides\",\"spikethickness\",\"spikecolor\"],f={},d={},h={};if(r)h=u.extendDeep(a,r),n._previousVal=null;else{h={\"allaxes.showspikes\":!1};for(var p=0;p<i.length;p++){var g=i[p],v=o[g],m=f[g]={};m.hovermode=v.hovermode,h[g+\".hovermode\"]=!1;for(var y=0;3>y;y++){var x=l[y];d=m[x]={};for(var b=0;b<s.length;b++){var _=s[b];d[_]=v[x][_]}}}n._previousVal=u.extendDeep({},f)}c.relayout(t,h)}function l(t,e){for(var n=e.currentTarget,r=n.getAttribute(\"data-attr\"),a=n.getAttribute(\"data-val\")||!0,o=t._fullLayout,i=c.Plots.getSubplotIds(o,\"geo\"),l=0;l<i.length;l++){var s=o[i[l]]._geo;if(\"zoom\"===r){var u=s.projection.scale(),f=\"in\"===a?2*u:.5*u;s.projection.scale(f),s.zoom.scale(f),s.render()}else\"reset\"===r&&s.zoomReset()}}function s(t){var e,n=t._fullLayout;e=n._has(\"cartesian\")?n._isHoriz?\"y\":\"x\":\"closest\";var r=t._fullLayout.hovermode?!1:e;c.relayout(t,\"hovermode\",r)}var c=t(\"../../plotly\"),u=t(\"../../lib\"),f=t(\"../../snapshot/download\"),d=t(\"../../../build/ploticon\"),h=e.exports={};h.toImage={name:\"toImage\",title:\"Download plot as a png\",icon:d.camera,click:function(t){var e=\"png\";u.notifier(\"Taking snapshot - this may take a few seconds\",\"long\"),u.isIE()&&(u.notifier(\"IE only supports svg. Changing format to svg.\",\"long\"),e=\"svg\"),f(t,{format:e}).then(function(t){u.notifier(\"Snapshot succeeded - \"+t,\"long\")}).catch(function(){u.notifier(\"Sorry there was a problem downloading your snapshot!\",\"long\")})}},h.sendDataToCloud={name:\"sendDataToCloud\",title:\"Save and edit plot in cloud\",icon:d.disk,click:function(t){c.Plots.sendDataToCloud(t)}},h.zoom2d={name:\"zoom2d\",title:\"Zoom\",attr:\"dragmode\",val:\"zoom\",icon:d.zoombox,click:r},h.pan2d={name:\"pan2d\",title:\"Pan\",attr:\"dragmode\",val:\"pan\",icon:d.pan,click:r},h.select2d={name:\"select2d\",title:\"Box Select\",attr:\"dragmode\",val:\"select\",icon:d.selectbox,click:r},h.lasso2d={name:\"lasso2d\",title:\"Lasso Select\",attr:\"dragmode\",val:\"lasso\",icon:d.lasso,click:r},h.zoomIn2d={name:\"zoomIn2d\",title:\"Zoom in\",attr:\"zoom\",val:\"in\",icon:d.zoom_plus,click:r},h.zoomOut2d={name:\"zoomOut2d\",title:\"Zoom out\",attr:\"zoom\",val:\"out\",icon:d.zoom_minus,click:r},h.autoScale2d={name:\"autoScale2d\",title:\"Autoscale\",attr:\"zoom\",val:\"auto\",icon:d.autoscale,click:r},h.resetScale2d={name:\"resetScale2d\",title:\"Reset axes\",attr:\"zoom\",val:\"reset\",icon:d.home,click:r},h.hoverClosestCartesian={name:\"hoverClosestCartesian\",title:\"Show closest data on hover\",attr:\"hovermode\",val:\"closest\",icon:d.tooltip_basic,gravity:\"ne\",click:r},h.hoverCompareCartesian={name:\"hoverCompareCartesian\",title:\"Compare data on hover\",attr:\"hovermode\",val:function(t){return t._fullLayout._isHoriz?\"y\":\"x\"},icon:d.tooltip_compare,gravity:\"ne\",click:r},h.zoom3d={name:\"zoom3d\",title:\"Zoom\",attr:\"scene.dragmode\",val:\"zoom\",icon:d.zoombox,click:a},h.pan3d={name:\"pan3d\",title:\"Pan\",attr:\"scene.dragmode\",val:\"pan\",icon:d.pan,click:a},h.orbitRotation={name:\"orbitRotation\",title:\"orbital rotation\",attr:\"scene.dragmode\",val:\"orbit\",icon:d[\"3d_rotate\"],click:a},h.tableRotation={name:\"tableRotation\",title:\"turntable rotation\",attr:\"scene.dragmode\",val:\"turntable\",icon:d[\"z-axis\"],click:a},h.resetCameraDefault3d={name:\"resetCameraDefault3d\",title:\"Reset camera to default\",attr:\"resetDefault\",icon:d.home,click:o},h.resetCameraLastSave3d={name:\"resetCameraLastSave3d\",title:\"Reset camera to last save\",attr:\"resetLastSave\",icon:d.movie,click:o},h.hoverClosest3d={name:\"hoverClosest3d\",title:\"Toggle show closest data on hover\",attr:\"hovermode\",val:null,toggle:!0,icon:d.tooltip_basic,gravity:\"ne\",click:i},h.zoomInGeo={name:\"zoomInGeo\",title:\"Zoom in\",attr:\"zoom\",val:\"in\",icon:d.zoom_plus,click:l},h.zoomOutGeo={name:\"zoomOutGeo\",title:\"Zoom out\",attr:\"zoom\",val:\"out\",icon:d.zoom_minus,click:l},h.resetGeo={name:\"resetGeo\",title:\"Reset\",attr:\"reset\",val:null,icon:d.autoscale,click:l},h.hoverClosestGeo={name:\"hoverClosestGeo\",title:\"Toggle show closest data on hover\",attr:\"hovermode\",val:null,toggle:!0,icon:d.tooltip_basic,gravity:\"ne\",click:s},h.hoverClosestGl2d={name:\"hoverClosestGl2d\",title:\"Toggle show closest data on hover\",attr:\"hovermode\",val:null,toggle:!0,icon:d.tooltip_basic,gravity:\"ne\",click:s},h.hoverClosestPie={name:\"hoverClosestPie\",title:\"Toggle show closest data on hover\",attr:\"hovermode\",val:\"closest\",icon:d.tooltip_basic,gravity:\"ne\",click:s},h.toggleHover={name:\"toggleHover\",title:\"Toggle show closest data on hover\",attr:\"hovermode\",val:null,toggle:!0,icon:d.tooltip_basic,gravity:\"ne\",click:function(t,e){s(t),i(t,e)}},h.resetViews={name:\"resetViews\",title:\"Reset views\",icon:d.home,click:function(t,e){var n=e.currentTarget;n.setAttribute(\"data-attr\",\"zoom\"),n.setAttribute(\"data-val\",\"reset\"),r(t,e),n.setAttribute(\"data-attr\",\"resetLastSave\"),o(t,e)}}},{\"../../../build/ploticon\":2,\"../../lib\":89,\"../../plotly\":107,\"../../snapshot/download\":137}],64:[function(t,e,n){\"use strict\";function r(t){this.container=t.container,this.element=document.createElement(\"div\"),this.update(t.graphInfo,t.buttons),this.container.appendChild(this.element)}function a(t,e){var n=t._fullLayout,a=new r({graphInfo:t,container:n._paperdiv.node(),buttons:e});return n._privateplot&&o.select(a.element).append(\"span\").classed(\"badge-private float--left\",!0).text(\"PRIVATE\"),a}var o=t(\"d3\"),i=t(\"../../lib\"),l=t(\"../../../build/ploticon\"),s=r.prototype;s.update=function(t,e){this.graphInfo=t;var n=this.graphInfo._context;\"hover\"===n.displayModeBar?this.element.className=\"modebar modebar--hover\":this.element.className=\"modebar\";var r=!this.hasButtons(e),a=this.hasLogo!==n.displaylogo;(r||a)&&(this.removeAllButtons(),this.updateButtons(e),n.displaylogo&&(this.element.appendChild(this.getLogo()),this.hasLogo=!0)),this.updateActiveButton()},s.updateButtons=function(t){var e=this;this.buttons=t,this.buttonElements=[],this.buttonsNames=[],this.buttons.forEach(function(t){var n=e.createGroup();t.forEach(function(t){var r=t.name;if(!r)throw new Error(\"must provide button 'name' in button config\");if(-1!==e.buttonsNames.indexOf(r))throw new Error(\"button name '\"+r+\"' is taken\");e.buttonsNames.push(r);var a=e.createButton(t);e.buttonElements.push(a),n.appendChild(a)}),e.element.appendChild(n)})},s.createGroup=function(){var t=document.createElement(\"div\");return t.className=\"modebar-group\",t},s.createButton=function(t){var e=this,n=document.createElement(\"a\");n.setAttribute(\"rel\",\"tooltip\"),n.className=\"modebar-btn\";var r=t.title;void 0===r&&(r=t.name),(r||0===r)&&n.setAttribute(\"data-title\",r),void 0!==t.attr&&n.setAttribute(\"data-attr\",t.attr);var a=t.val;void 0!==a&&(\"function\"==typeof a&&(a=a(this.graphInfo)),n.setAttribute(\"data-val\",a));var o=t.click;if(\"function\"!=typeof o)throw new Error(\"must provide button 'click' function in button config\");return n.addEventListener(\"click\",function(n){t.click(e.graphInfo,n),e.updateActiveButton(n.currentTarget)}),n.setAttribute(\"data-toggle\",t.toggle||!1),t.toggle&&n.classList.add(\"active\"),n.appendChild(this.createIcon(t.icon||l.question)),n.setAttribute(\"data-gravity\",t.gravity||\"n\"),n},s.createIcon=function(t){var e=t.ascent-t.descent,n=\"http://www.w3.org/2000/svg\",r=document.createElementNS(n,\"svg\"),a=document.createElementNS(n,\"path\");return r.setAttribute(\"height\",\"1em\"),r.setAttribute(\"width\",t.width/e+\"em\"),r.setAttribute(\"viewBox\",[0,0,t.width,e].join(\" \")),a.setAttribute(\"d\",t.path),a.setAttribute(\"transform\",\"matrix(1 0 0 -1 0 \"+t.ascent+\")\"),r.appendChild(a),r},s.updateActiveButton=function(t){var e=this.graphInfo._fullLayout,n=void 0!==t?t.getAttribute(\"data-attr\"):null;this.buttonElements.forEach(function(t){var r=t.getAttribute(\"data-val\")||!0,a=t.getAttribute(\"data-attr\"),l=\"true\"===t.getAttribute(\"data-toggle\"),s=o.select(t);if(l)a===n&&s.classed(\"active\",!s.classed(\"active\"));else{var c=null===a?a:i.nestedProperty(e,a).get();s.classed(\"active\",c===r)}})},s.hasButtons=function(t){var e=this.buttons;if(!e)return!1;if(t.length!==e.length)return!1;for(var n=0;n<t.length;++n){if(t[n].length!==e[n].length)return!1;for(var r=0;r<t[n].length;r++)if(t[n][r].name!==e[n][r].name)return!1}return!0},s.getLogo=function(){var t=" -, -"this.createGroup(),e=document.createElement(\"a\");return e.href=\"https://plot.ly/\",e.target=\"_blank\",e.setAttribute(\"data-title\",\"Produced with Plotly\"),e.className=\"modebar-btn plotlyjsicon modebar-btn--logo\",e.appendChild(this.createIcon(l.plotlylogo)),t.appendChild(e),t},s.removeAllButtons=function(){for(;this.element.firstChild;)this.element.removeChild(this.element.firstChild);this.hasLogo=!1},s.destroy=function(){i.removeElement(this.container.querySelector(\".modebar\"))},e.exports=a},{\"../../../build/ploticon\":2,\"../../lib\":89,d3:9}],65:[function(t,e,n){\"use strict\";function r(t,e,n){function r(t){for(var n=[],r=0;r<t.length;r++){var a=t[r];-1===e.indexOf(a)&&n.push(f[a])}v.push(n)}var l=t._fullLayout,s=t._fullData,c=l._has(\"cartesian\"),u=l._has(\"gl3d\"),d=l._has(\"geo\"),h=l._has(\"pie\"),p=l._has(\"gl2d\"),g=l._has(\"ternary\"),v=[];if(r([\"toImage\",\"sendDataToCloud\"]),(c||p||h||g)+d+u>1)return r([\"resetViews\",\"toggleHover\"]),i(v,n);u&&(r([\"zoom3d\",\"pan3d\",\"orbitRotation\",\"tableRotation\"]),r([\"resetCameraDefault3d\",\"resetCameraLastSave3d\"]),r([\"hoverClosest3d\"])),d&&(r([\"zoomInGeo\",\"zoomOutGeo\",\"resetGeo\"]),r([\"hoverClosestGeo\"]));var m=a(l),y=[];return((c||p)&&!m||g)&&(y=[\"zoom2d\",\"pan2d\"]),(c||g)&&o(s)&&(y.push(\"select2d\"),y.push(\"lasso2d\")),y.length&&r(y),!c&&!p||m||g||r([\"zoomIn2d\",\"zoomOut2d\",\"autoScale2d\",\"resetScale2d\"]),c&&h?r([\"toggleHover\"]):p?r([\"hoverClosestGl2d\"]):c?r([\"hoverClosestCartesian\",\"hoverCompareCartesian\"]):h&&r([\"hoverClosestPie\"]),i(v,n)}function a(t){for(var e=s.Axes.list({_fullLayout:t},null,!0),n=!0,r=0;r<e.length;r++)if(!e[r].fixedrange){n=!1;break}return n}function o(t){for(var e=!1,n=0;n<t.length&&!e;n++){var r=t[n];r._module&&r._module.selectPoints&&(\"scatter\"===r.type||\"scatterternary\"===r.type?(c.hasMarkers(r)||c.hasText(r))&&(e=!0):e=!0)}return e}function i(t,e){if(e.length)if(Array.isArray(e[0]))for(var n=0;n<e.length;n++)t.push(e[n]);else t.push(e);return t}function l(t){for(var e=0;e<t.length;e++)for(var n=t[e],r=0;r<n.length;r++){var a=n[r];if(\"string\"==typeof a){if(void 0===f[a])throw new Error([\"*modeBarButtons* configuration options\",\"invalid button name\"].join(\" \"));t[e][r]=f[a]}}return t}var s=t(\"../../plotly\"),c=t(\"../../traces/scatter/subtypes\"),u=t(\"./\"),f=t(\"./buttons\");e.exports=function(t){var e=t._fullLayout,n=t._context,a=e._modeBar;if(!n.displayModeBar)return void(a&&(a.destroy(),delete e._modeBar));if(!Array.isArray(n.modeBarButtonsToRemove))throw new Error([\"*modeBarButtonsToRemove* configuration options\",\"must be an array.\"].join(\" \"));if(!Array.isArray(n.modeBarButtonsToAdd))throw new Error([\"*modeBarButtonsToAdd* configuration options\",\"must be an array.\"].join(\" \"));var o,i=n.modeBarButtons;o=Array.isArray(i)&&i.length?l(i):r(t,n.modeBarButtonsToRemove,n.modeBarButtonsToAdd),a?a.update(t,o):e._modeBar=u(t,o)}},{\"../../plotly\":107,\"../../traces/scatter/subtypes\":186,\"./\":64,\"./buttons\":63}],66:[function(t,e,n){\"use strict\";var r=t(\"../../plots/font_attributes\"),a=t(\"../color/attributes\"),o=t(\"../../lib/extend\").extendFlat,i=t(\"./button_attributes\");i=o(i,{_isLinkedToArray:!0}),e.exports={visible:{valType:\"boolean\"},buttons:i,x:{valType:\"number\",min:-2,max:3},xanchor:{valType:\"enumerated\",values:[\"auto\",\"left\",\"center\",\"right\"],dflt:\"left\"},y:{valType:\"number\",min:-2,max:3},yanchor:{valType:\"enumerated\",values:[\"auto\",\"top\",\"middle\",\"bottom\"],dflt:\"bottom\"},font:o({},r,{}),bgcolor:{valType:\"color\",dflt:a.lightLine},bordercolor:{valType:\"color\",dflt:a.defaultLine},borderwidth:{valType:\"number\",min:0,dflt:0}}},{\"../../lib/extend\":88,\"../../plots/font_attributes\":128,\"../color/attributes\":17,\"./button_attributes\":67}],67:[function(t,e,n){\"use strict\";e.exports={step:{valType:\"enumerated\",values:[\"month\",\"year\",\"day\",\"hour\",\"minute\",\"second\",\"all\"],dflt:\"month\"},stepmode:{valType:\"enumerated\",values:[\"backward\",\"todate\"],dflt:\"backward\"},count:{valType:\"number\",min:0,dflt:1},label:{valType:\"string\"}}},{}],68:[function(t,e,n){\"use strict\";e.exports={yPad:.02,minButtonWidth:30,rx:3,ry:3,activeColor:\"#d3d3d3\"}},{}],69:[function(t,e,n){\"use strict\";function r(t,e){function n(t,e){return o.coerce(r,a,l,t,e)}for(var r,a,i=t.buttons||[],s=e.buttons=[],c=0;c<i.length;c++){r=i[c],a={};var u=n(\"step\");\"all\"!==u&&(n(\"stepmode\"),n(\"count\")),n(\"label\"),s.push(a)}return s}function a(t,e,n){for(var r=n.filter(function(n){return e[n].anchor===t._id}),a=0,o=0;o<r.length;o++)a=Math.max(e[r[o]].domain[1],a);return[t.domain[0],a+s.yPad]}var o=t(\"../../lib\"),i=t(\"./attributes\"),l=t(\"./button_attributes\"),s=t(\"./constants\");e.exports=function(t,e,n,l){function s(t,e){return o.coerce(c,u,i,t,e)}var c=t.rangeselector||{},u=e.rangeselector={},f=r(c,u),d=s(\"visible\",f.length>0);if(d){var h=a(e,n,l);s(\"x\",h[0]),s(\"y\",h[1]),o.noneOrAll(t,e,[\"x\",\"y\"]),s(\"xanchor\"),s(\"yanchor\"),o.coerceFont(s,\"font\",n.font),s(\"bgcolor\"),s(\"bordercolor\"),s(\"borderwidth\")}}},{\"../../lib\":89,\"./attributes\":66,\"./button_attributes\":67,\"./constants\":68}],70:[function(t,e,n){\"use strict\";function r(t){for(var e=m.list(t,\"x\",!0),n=[],r=0;r<e.length;r++){var a=e[r];a.rangeselector&&a.rangeselector.visible&&n.push(a)}return n}function a(t){return t._id}function o(t,e,n){if(\"all\"===e.step)return t.autorange===!0;var r=Object.keys(n);return t.range[0]===n[r[0]]&&t.range[1]===n[r[1]]}function i(t,e,n){var r=t.selectAll(\"rect\").data([0]);r.enter().append(\"rect\").classed(\"selector-rect\",!0),r.attr(\"shape-rendering\",\"crispEdges\"),r.attr({rx:x.rx,ry:x.ry}),r.call(p.stroke,e.bordercolor).call(p.fill,l(e,n)).style(\"stroke-width\",e.borderwidth+\"px\")}function l(t,e){return e.isActive||e.isHovered?x.activeColor:t.bgcolor}function s(t,e,n){function r(t){v.convertToTspans(t)}var a=t.selectAll(\"text\").data([0]);a.enter().append(\"text\").classed(\"selector-text\",!0).classed(\"user-select-none\",!0),a.attr(\"text-anchor\",\"middle\"),a.call(g.font,e.font).text(c(n)).call(r)}function c(t){return t.label?t.label:\"all\"===t.step?\"all\":t.count+t.step.charAt(0)}function u(t,e,n,r){n.width=0,n.height=0;var a=n.borderwidth;e.each(function(){var t=f.select(this),e=t.select(\".selector-text\"),r=e.selectAll(\"tspan\"),a=1.3*n.font.size,o=r[0].length||1,i=Math.max(a*o,16)+3;n.height=Math.max(n.height,i)}),e.each(function(){var t=f.select(this),e=t.select(\".selector-rect\"),r=t.select(\".selector-text\"),o=r.selectAll(\"tspan\"),i=r.node()&&g.bBox(r.node()).width,l=1.3*n.font.size,s=o[0].length||1,c=Math.max(i+10,x.minButtonWidth);t.attr(\"transform\",\"translate(\"+(a+n.width)+\",\"+a+\")\"),e.attr({x:0,y:0,width:c,height:n.height});var u={x:c/2,y:n.height/2-(s-1)*l/2+3};r.attr(u),o.attr(u),n.width+=c+5}),e.selectAll(\"rect\").attr(\"height\",n.height);var o=t._fullLayout._size;n.lx=o.l+o.w*n.x,n.ly=o.t+o.h*(1-n.y);var i=\"left\";y.isRightAnchor(n)&&(n.lx-=n.width,i=\"right\"),y.isCenterAnchor(n)&&(n.lx-=n.width/2,i=\"center\");var l=\"top\";y.isBottomAnchor(n)&&(n.ly-=n.height,l=\"bottom\"),y.isMiddleAnchor(n)&&(n.ly-=n.height/2,l=\"middle\"),n.width=Math.ceil(n.width),n.height=Math.ceil(n.height),n.lx=Math.round(n.lx),n.ly=Math.round(n.ly),h.autoMargin(t,r+\"-range-selector\",{x:n.x,y:n.y,l:n.width*({right:1,center:.5}[i]||0),r:n.width*({left:1,center:.5}[i]||0),b:n.height*({top:1,middle:.5}[l]||0),t:n.height*({bottom:1,middle:.5}[l]||0)})}var f=t(\"d3\"),d=t(\"../../plotly\"),h=t(\"../../plots/plots\"),p=t(\"../color\"),g=t(\"../drawing\"),v=t(\"../../lib/svg_text_utils\"),m=t(\"../../plots/cartesian/axis_ids\"),y=t(\"../legend/anchor_utils\"),x=t(\"./constants\"),b=t(\"./get_update_object\");e.exports=function(t){var e=t._fullLayout,n=e._infolayer.selectAll(\".rangeselector\").data(r(t),a);n.enter().append(\"g\").classed(\"rangeselector\",!0),n.exit().remove(),n.style({cursor:\"pointer\",\"pointer-events\":\"all\"}),n.each(function(e){var n=f.select(this),r=e,a=r.rangeselector,l=n.selectAll(\"g.button\").data(a.buttons);l.enter().append(\"g\").classed(\"button\",!0),l.exit().remove(),l.each(function(e){var n=f.select(this),l=b(r,e);e.isActive=o(r,e,l),n.call(i,a,e),n.call(s,a,e),n.on(\"click\",function(){t._dragged||d.relayout(t,l)}),n.on(\"mouseover\",function(){e.isHovered=!0,n.call(i,a,e)}),n.on(\"mouseout\",function(){e.isHovered=!1,n.call(i,a,e)})}),u(t,l,a,r._name),n.attr(\"transform\",\"translate(\"+a.lx+\",\"+a.ly+\")\")})}},{\"../../lib/svg_text_utils\":100,\"../../plotly\":107,\"../../plots/cartesian/axis_ids\":112,\"../../plots/plots\":130,\"../color\":18,\"../drawing\":41,\"../legend/anchor_utils\":54,\"./constants\":68,\"./get_update_object\":71,d3:9}],71:[function(t,e,n){\"use strict\";function r(t,e){var n,r=t.range,o=new Date(r[1]),i=e.step,l=e.count;switch(e.stepmode){case\"backward\":n=a.time[i].offset(o,-l).getTime();break;case\"todate\":var s=a.time[i].offset(o,-(l-1));n=a.time[i].floor(s).getTime()}var c=r[1];return[n,c]}var a=t(\"d3\");e.exports=function(t,e){var n=t._name,a={};if(\"all\"===e.step)a[n+\".autorange\"]=!0;else{var o=r(t,e);a[n+\".range[0]\"]=o[0],a[n+\".range[1]\"]=o[1]}return a}},{d3:9}],72:[function(t,e,n){\"use strict\";n.attributes=t(\"./attributes\"),n.supplyLayoutDefaults=t(\"./defaults\"),n.draw=t(\"./draw\")},{\"./attributes\":66,\"./defaults\":69,\"./draw\":70}],73:[function(t,e,n){\"use strict\";var r=t(\"../color/attributes\");e.exports={bgcolor:{valType:\"color\",dflt:r.background},bordercolor:{valType:\"color\",dflt:r.defaultLine},borderwidth:{valType:\"integer\",dflt:0,min:0},range:{valType:\"info_array\",items:[{valType:\"number\"},{valType:\"number\"}]},thickness:{valType:\"number\",dflt:.15,min:0,max:1},visible:{valType:\"boolean\",dflt:!0}}},{\"../color/attributes\":17}],74:[function(t,e,n){\"use strict\";var r=t(\"../../plotly\"),a=t(\"../../plots/cartesian/axes\"),o=t(\"../../lib\"),i=t(\"../../constants/xmlns_namespaces\").svg,l=t(\"./helpers\"),s=t(\"./range_plot\");e.exports=function(t){function e(t){var e=h.range[0],n=h.range[1],r=n-e,a=t/p*r+e;return a=o.constrain(a,e,n)}function n(t,e){t=t||-(1/0),e=e||1/0;var n=h.range[0],r=h.range[1],a=r-n,o=(t-n)/a*p,i=(e-n)/a*p;u(o,i)}function c(e,n){window.requestAnimationFrame?window.requestAnimationFrame(function(){r.relayout(t,\"xaxis.range\",[e,n])}):setTimeout(function(){r.relayout(t,\"xaxis.range\",[e,n])},16)}" -, -"function u(t,e){if(t=o.constrain(t,0,p),e=o.constrain(e,0,p),t>e){var n=e;e=t,t=n}l.setAttributes(w,{\"data-min\":t,\"data-max\":e}),l.setAttributes(P,{x:t,width:e-t}),l.setAttributes(A,{width:t}),l.setAttributes(L,{x:e,width:p-e}),l.setAttributes(T,{transform:\"translate(\"+(t-v-1)+\")\"}),l.setAttributes(E,{transform:\"translate(\"+e+\")\"})}var f=t._fullLayout,d=f._infolayer.selectAll(\"g.range-slider\"),h=f.xaxis.rangeslider,p=f._size.w,g=(f.height-f.margin.b-f.margin.t)*h.thickness,v=2,m=Math.floor(h.borderwidth/2),y=f.margin.l,x=f.height-g-f.margin.b,b=0,_=p,w=document.createElementNS(i,\"g\");l.setAttributes(w,{\"class\":\"range-slider\",\"data-min\":b,\"data-max\":_,\"pointer-events\":\"all\",transform:\"translate(\"+y+\",\"+x+\")\"});var k=document.createElementNS(i,\"rect\"),M=h.borderwidth%2===0?h.borderwidth:h.borderwidth-1;l.setAttributes(k,{fill:h.bgcolor,stroke:h.bordercolor,\"stroke-width\":h.borderwidth,height:g+M,width:p+M,transform:\"translate(-\"+m+\", -\"+m+\")\",\"shape-rendering\":\"crispEdges\"});var A=document.createElementNS(i,\"rect\");l.setAttributes(A,{x:0,width:b,height:g,fill:\"rgba(0,0,0,0.4)\"});var L=document.createElementNS(i,\"rect\");l.setAttributes(L,{x:_,width:p-_,height:g,fill:\"rgba(0,0,0,0.4)\"});var T=document.createElementNS(i,\"g\"),z=document.createElementNS(i,\"rect\"),S=document.createElementNS(i,\"rect\");l.setAttributes(T,{transform:\"translate(\"+(b-v-1)+\")\"}),l.setAttributes(z,{width:10,height:g,x:-6,fill:\"transparent\",cursor:\"col-resize\"}),l.setAttributes(S,{width:v,height:g/2,y:g/4,rx:1,fill:\"white\",stroke:\"#666\",\"shape-rendering\":\"crispEdges\"}),l.appendChildren(T,[S,z]);var E=document.createElementNS(i,\"g\"),C=document.createElementNS(i,\"rect\"),O=document.createElementNS(i,\"rect\");l.setAttributes(E,{transform:\"translate(\"+_+\")\"}),l.setAttributes(C,{width:10,height:g,x:-2,fill:\"transparent\",cursor:\"col-resize\"}),l.setAttributes(O,{width:v,height:g/2,y:g/4,rx:1,fill:\"white\",stroke:\"#666\",\"shape-rendering\":\"crispEdges\"}),l.appendChildren(E,[O,C]);var P=document.createElementNS(i,\"rect\");\n" -, -"l.setAttributes(P,{x:b,width:_-b,height:g,cursor:\"ew-resize\",fill:\"transparent\"}),w.addEventListener(\"mousedown\",function(t){function n(t){var n,r,f=+t.clientX-o;switch(a){case P:w.style.cursor=\"ew-resize\",n=+l+f,r=+s+f,u(n,r),c(e(n),e(r));break;case z:w.style.cursor=\"col-resize\",n=+l+f,r=+s,u(n,r),c(e(n),e(r));break;case C:w.style.cursor=\"col-resize\",n=+l,r=+s+f,u(n,r),c(e(n),e(r));break;default:w.style.cursor=\"ew-resize\",n=i,r=i+f,u(n,r),c(e(n),e(r))}}function r(){window.removeEventListener(\"mousemove\",n),window.removeEventListener(\"mouseup\",r),w.style.cursor=\"auto\"}var a=t.target,o=t.clientX,i=o-w.getBoundingClientRect().left,l=w.getAttribute(\"data-min\"),s=w.getAttribute(\"data-max\");window.addEventListener(\"mousemove\",n),window.addEventListener(\"mouseup\",r)}),h.range||(h.range=a.getAutoRange(f.xaxis));var N=s(t,p,g);l.appendChildren(w,[k,N,A,L,P,T,E]),n(f.xaxis.range[0],f.xaxis.range[1]),d.data([0]).enter().append(function(){return h.setRange=n,w})}},{\"../../constants/xmlns_namespaces\":82,\"../../lib\":89,\"../../plotly\":107,\"../../plots/cartesian/axes\":110,\"./helpers\":76,\"./range_plot\":78}],75:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"./attributes\");e.exports=function(t,e,n,o){function i(t,e){return r.coerce(l,s,a,t,e)}if(t[n].rangeslider){var l=\"object\"==typeof t[n].rangeslider?t[n].rangeslider:{},s=e[n].rangeslider={};if(i(\"bgcolor\"),i(\"bordercolor\"),i(\"borderwidth\"),i(\"thickness\"),i(\"visible\"),i(\"range\"),s.range&&!e[n].autorange){var c=s.range,u=e[n].range;c[0]=Math.min(c[0],u[0]),c[1]=Math.max(c[1],u[1])}else e[n]._needsExpand=!0;s.visible&&o.forEach(function(t){var n=e[t]||{};n.fixedrange=!0,e[t]=n})}}},{\"../../lib\":89,\"./attributes\":73}],76:[function(t,e,n){\"use strict\";n.setAttributes=function(t,e){for(var n in e)t.setAttribute(n,e[n])},n.appendChildren=function(t,e){for(var n=0;n<e.length;n++)e[n]&&t.appendChild(e[n])}},{}],77:[function(t,e,n){\"use strict\";function r(t){if(t._fullLayout.xaxis){var e=t._fullLayout,n=e._infolayer.selectAll(\"g.range-slider\"),r=e.xaxis.rangeslider;if(!r||!r.visible)return n.data([]).exit().remove(),void a.autoMargin(t,\"range-slider\");var i=(e.height-e.margin.b-e.margin.t)*r.thickness,l=Math.floor(r.borderwidth/2);0!==n[0].length||e._has(\"gl2d\")||o(t);var s=e.xaxis._boundingBox?e.xaxis._boundingBox.height:0;a.autoMargin(t,\"range-slider\",{x:0,y:0,l:0,r:0,t:0,b:i+e.margin.b+s,pad:15+2*l})}}var a=t(\"../../plots/plots\"),o=t(\"./create_slider\"),i=t(\"./defaults\");e.exports={draw:r,supplyLayoutDefaults:i}},{\"../../plots/plots\":130,\"./create_slider\":74,\"./defaults\":75}],78:[function(t,e,n){\"use strict\";function r(t,e){for(var n=e.makeCalcdata(t||[],e._id[0]),r=0;r<n.length;r++)n[r]=e.c2l(n[r]);return n}function a(t,e,n,r){var a,o,f;if(t.line){a=document.createElementNS(u,\"path\");var d=s.smoothopen(e,t.line.smoothing||0);c.setAttributes(a,{d:d,fill:\"none\",stroke:t.line?t.line.color:\"transparent\",\"stroke-width\":t.line.width/2||1,opacity:1})}if(t.marker){o=document.createElementNS(u,\"g\");var h=e.map(function(e,n){var r,a=document.createElementNS(u,\"g\"),o=document.createElementNS(u,\"path\");return r=Array.isArray(t.marker.size)?\"number\"==typeof t.marker.size[n]?Math.max(t.marker.size[n]/(t.marker.sizeref||1)/15,0):0:Math.max(t.marker.size/15,2),c.setAttributes(o,{d:l[t.marker.symbol].f(r),fill:t.marker.color,stroke:t.marker.line.color,\"stroke-width\":t.marker.line.width,opacity:t.marker.opacity}),c.setAttributes(a,{transform:\"translate(\"+e[0]+\",\"+e[1]+\")\"}),a.appendChild(o),a});c.appendChildren(o,h)}if(\"none\"!==t.fill){switch(f=document.createElementNS(u,\"path\"),t.fill){case\"tozeroy\":e.unshift([e[0][0],r]),e.push([e[e.length-1][0],r]);break;case\"tozerox\":e.unshift([0,e[e.length-1][1]]);break;default:i.warn(\"Fill type \"+t.fill+\" not supported for range slider! (yet...)\")}var p=s.smoothopen(e,t.line.smoothing||0);c.setAttributes(f,{d:p,fill:t.fillcolor||\"transparent\"})}return[a,o,f]}var o=t(\"d3\"),i=t(\"../../lib\"),l=t(\"../drawing/symbol_defs\"),s=t(\"../drawing\"),c=t(\"./helpers\"),u=t(\"../../constants/xmlns_namespaces\").svg;e.exports=function f(t,e,n){var l=t._fullLayout,d=t._fullData,h=l.xaxis,p=l.yaxis,g=h.rangeslider.range[0],v=h.rangeslider.range[1],m=p.range[0],y=p.range[1],x=document.createElementNS(u,\"path\");x.setAttribute(\"d\",[\"M0,0\",e+\",0\",e+\",\"+n,\"0,\"+n,\"Z\"].join(\" \"));var b=document.createElementNS(u,\"clipPath\");b.setAttribute(\"id\",\"range-clip-path\"),b.appendChild(x);var _=document.createElementNS(u,\"defs\");_.appendChild(b);var f=document.createElementNS(u,\"g\");o.select(f).call(s.setClipUrl,\"range-clip-path\"),f.appendChild(_);for(var w=[\"scatter\"],k=0;k<d.length;k++){var M=d[k],A=[];if(w.indexOf(M.type)<0)i.warn(\"Trace type \"+M.type+\" not supported for range slider!\");else{for(var L=r(M,h),T=r(M,p),z=0;z<L.length;z++){var S=e*(L[z]-g)/(v-g),E=n*(1-(T[z]-m)/(y-m));isNaN(S)||isNaN(E)||A.push([S,E])}c.appendChildren(f,a(M,A,e,n))}}return f}},{\"../../constants/xmlns_namespaces\":82,\"../../lib\":89,\"../drawing\":41,\"../drawing/symbol_defs\":42,\"./helpers\":76,d3:9}],79:[function(t,e,n){\"use strict\";var r=t(\"../annotations/attributes\"),a=t(\"../../traces/scatter/attributes\"),o=t(\"../../lib/extend\").extendFlat,i=a.line;e.exports={_isLinkedToArray:!0,type:{valType:\"enumerated\",values:[\"circle\",\"rect\",\"path\",\"line\"]},layer:{valType:\"enumerated\",values:[\"below\",\"above\"],dflt:\"above\"},xref:o({},r.xref,{}),x0:{valType:\"any\"},x1:{valType:\"any\"},yref:o({},r.yref,{}),y0:{valType:\"any\"},y1:{valType:\"any\"},path:{valType:\"string\"},opacity:{valType:\"number\",min:0,max:1,dflt:1},line:{color:i.color,width:i.width,dash:i.dash},fillcolor:{valType:\"color\",dflt:\"rgba(0,0,0,0)\"}}},{\"../../lib/extend\":88,\"../../traces/scatter/attributes\":167,\"../annotations/attributes\":15}],80:[function(t,e,n){\"use strict\";function r(t,e){function n(e,n){return M.coerce(t,r,E.layoutAttributes,e,n)}var r={};n(\"layer\"),n(\"opacity\"),n(\"fillcolor\"),n(\"line.color\"),n(\"line.width\"),n(\"line.dash\");for(var a=t.path?\"path\":\"rect\",i=n(\"type\",a),l=[\"x\",\"y\"],s=0;2>s;s++){var c=l[s],u={_fullLayout:e},f=A.coerceRef(t,r,u,c);if(\"path\"!==i){var d=.25,h=.75;if(\"paper\"!==f){var p=A.getFromId(u,f),g=o(p);d=g(p.range[0]+d*(p.range[1]-p.range[0])),h=g(p.range[0]+h*(p.range[1]-p.range[0]))}n(c+\"0\",d),n(c+\"1\",h)}}return\"path\"===i?n(\"path\"):M.noneOrAll(t,r,[\"x0\",\"x1\",\"y0\",\"y1\"]),r}function a(t){return\"category\"===t.type?t.c2l:t.d2l}function o(t){return\"category\"===t.type?t.l2c:t.l2d}function i(t,e){t.layout.shapes=e,E.supplyLayoutDefaults(t.layout,t._fullLayout),E.drawAll(t)}function l(t){delete t.layout.shapes,t._fullLayout.shapes=[],E.drawAll(t)}function s(t,e,n){for(var r=0;r<t._fullLayout.shapes.length;r++)E.draw(t,r,e,n)}function c(t,e){h(t,e).selectAll('[data-index=\"'+e+'\"]').remove(),t._fullLayout.shapes.splice(e,1),t.layout.shapes.splice(e,1);for(var n=e;n<t._fullLayout.shapes.length;n++)h(t,n).selectAll('[data-index=\"'+(n+1)+'\"]').attr(\"data-index\",n),E.draw(t,n)}function u(t,e,n){t._fullLayout.shapes.splice(e,0,{});var r=M.isPlainObject(n)?M.extendFlat({},n):{text:\"New text\"};t.layout.shapes?t.layout.shapes.splice(e,0,r):t.layout.shapes=[r];for(var a=t._fullLayout.shapes.length-1;a>e;a--)h(t,a).selectAll('[data-index=\"'+(a-1)+'\"]').attr(\"data-index\",a),E.draw(t,a)}function f(t,e,n,i){function l(n){var r={\"data-index\":e,\"fill-rule\":\"evenodd\",d:x(t,E)},a=E.line.width?E.line.color:\"rgba(0,0,0,0)\",o=n.append(\"path\").attr(r).style(\"opacity\",E.opacity).call(L.stroke,a).call(L.fill,E.fillcolor).call(T.dashLine,E.line.dash,E.line.width);C&&o.call(T.setClipUrl,\"clip\"+t._fullLayout._uid+C),t._context.editable&&d(t,o,E,e)}var s,c;h(t,e).selectAll('[data-index=\"'+e+'\"]').remove();var u=t.layout.shapes[e];if(u){var f={xref:u.xref,yref:u.yref},g={};\"string\"==typeof n&&n?g[n]=i:M.isPlainObject(n)&&(g=n);var v=Object.keys(g);for(s=0;s<v.length;s++){var m=v[s];M.nestedProperty(u,m).set(g[m])}var y=[\"x0\",\"x1\",\"y0\",\"y1\"];for(s=0;4>s;s++){var b=y[s];if(void 0===g[b]&&void 0!==u[b]){var _,w=b.charAt(0),k=A.getFromId(t,A.coerceRef(f,{},t,w)),z=A.getFromId(t,A.coerceRef(u,{},t,w)),S=u[b];void 0!==g[w+\"ref\"]&&(k?(_=a(k)(S),S=(_-k.range[0])/(k.range[1]-k.range[0])):S=(S-z.domain[0])/(z.domain[1]-z.domain[0]),z?(_=z.range[0]+S*(z.range[1]-z.range[0]),S=o(z)(_)):S=k.domain[0]+S*(k.domain[1]-k.domain[0])),u[b]=S}}var E=r(u,t._fullLayout);t._fullLayout.shapes[e]=E;var C;if(\"below\"!==E.layer)C=(E.xref+E.yref).replace(/paper/g,\"\"),l(t._fullLayout._shapeUpperLayer);else if(\"paper\"===E.xref&&\"paper\"===E.yref)C=\"\",l(t._fullLayout._shapeLowerLayer);else{var O,P=t._fullLayout._plots||{},N=Object.keys(P);for(s=0,c=N.length;c>s;s++)O=P[N[s]],C=N[s],p(t,E,O)&&l(O.shapelayer)}}}function d(t,e,n,r){function a(t){var n=W.right-W.left,r=W.bottom-W.top,a=t.clientX-W.left,o=t.clientY-W.top,i=n>G&&r>$&&!t.shiftKey?z.getCursor(a/n,1-o/r):\"move\";S(e,i),X=i.split(\"-\")[0]}function o(e){B=A.getFromId(t,n.xref),H=A.getFromId(t,n.yref),V=m(t,B),Z=m(t,H,!0),Y=y(t,B),U=y(t,H,!0);var o=\"shapes[\"+r+\"]\";\"path\"===n.type?(q=n.path,F=o+\".path\"):(u=V(n.x0),f=Z(n.y0),d=V(n.x1),h=Z(n.y1),p=o+\".x0\",g=o+\".y0\",_=o+\".x1\",w=o+\".y1\"),d>u?(T=u,P=o+\".x0\",R=\"x0\",E=d,N=o+\".x1\",j=\"x1\"):(T=d,P=o+\".x1\",R=\"x1\",E=u,N=o+\".x0\",j=\"x0\"),h>f?(M=f,C=o+\".y0\",D=\"y0\",L=h,O=o+\".y1\",I=\"y1\"):(M=h,C=o+\".y1\",D=\"y1\",L=f,O=o+\".y0\",I=\"y0\"),c={},a(e),Q.moveFn=\"move\"===X?l:s}function i(n){S(e),n&&k.relayout(t,c)}function l(r,a){if(\"path\"===n.type){var o=function(t){return Y(V(t)+r)};B&&\"date\"===B.type&&(o=v(o));var i=function(t){return U(Z(t)+a)};H&&\"date\"===H.type&&(i=v(i)),n.path=b(q,o,i),c[F]=n.path}else c[p]=n.x0=Y(u+r),c[g]=n.y0=U(f+a),c[_]=n.x1=Y(d+r),c[w]=n.y1=U(h+a);e.attr(\"d\",x(t,n))}function s(r,a){if(\"path\"===n.type){var o=function(t){return Y(V(t)+r)};B&&\"date\"===B.type&&(o=v(o));var i=function(t){return U(Z(t)+a)};H&&\"date\"===H.type&&(i=v(i)),n.path=b(q,o,i),c[F]=n.path}else{var l=~X.indexOf(\"n\")?M+a:M,s=~X.indexOf(\"s\")?L+a:L,u=~X.indexOf(\"w\")?T+r:T,f=~X.indexOf(\"e\")?E+r:E;s-l>$&&(c[C]=n[D]=U(l),c[O]=n[I]=U(s)),f-u>G&&(c[P]=n[R]=Y(u),c[N]=n[j]=Y(f))}e.attr(\"d\",x(t,n))}var c,u,f,d,h,p,g,_,w,M,L,T,E,C,O,P,N,D,I,R,j,q" -, -",F,B,H,V,Z,Y,U,X,G=10,$=10,Q={setCursor:a,element:e.node(),prepFn:o,doneFn:i},W=Q.element.getBoundingClientRect();z.init(Q)}function h(t,e){var n=t._fullLayout.shapes[e],r=t._fullLayout._shapeUpperLayer;return n?\"below\"===n.layer&&(r=\"paper\"===n.xref&&\"paper\"===n.yref?t._fullLayout._shapeLowerLayer:t._fullLayout._shapeSubplotLayer):M.log(\"getShapeLayer: undefined shape: index\",e),r}function p(t,e,n){var r=k.Axes.getFromId(t,n.id,\"x\")._id,a=k.Axes.getFromId(t,n.id,\"y\")._id,o=\"below\"===e.layer,i=r===e.xref||a===e.yref,l=!!n.shapelayer;return o&&i&&l}function g(t){return function(e){return e.replace&&(e=e.replace(\"_\",\" \")),t(e)}}function v(t){return function(e){return t(e).replace(\" \",\"_\")}}function m(t,e,n){var r,o=t._fullLayout._size;if(e){var i=a(e);r=function(t){return e._offset+e.l2p(i(t,!0))},\"date\"===e.type&&(r=g(r))}else r=n?function(t){return o.t+o.h*(1-t)}:function(t){return o.l+o.w*t};return r}function y(t,e,n){var r,a=t._fullLayout._size;if(e){var i=o(e);r=function(t){return i(e.p2l(t-e._offset))}}else r=n?function(t){return 1-(t-a.t)/a.h}:function(t){return(t-a.l)/a.w};return r}function x(t,e){var n,r,o,i,l=e.type,s=A.getFromId(t,e.xref),c=A.getFromId(t,e.yref),u=t._fullLayout._size;if(s?(n=a(s),r=function(t){return s._offset+s.l2p(n(t,!0))}):r=function(t){return u.l+u.w*t},c?(o=a(c),i=function(t){return c._offset+c.l2p(o(t,!0))}):i=function(t){return u.t+u.h*(1-t)},\"path\"===l)return s&&\"date\"===s.type&&(r=g(r)),c&&\"date\"===c.type&&(i=g(i)),E.convertPath(e.path,r,i);var f=r(e.x0),d=r(e.x1),h=i(e.y0),p=i(e.y1);if(\"line\"===l)return\"M\"+f+\",\"+h+\"L\"+d+\",\"+p;if(\"rect\"===l)return\"M\"+f+\",\"+h+\"H\"+d+\"V\"+p+\"H\"+f+\"Z\";var v=(f+d)/2,m=(h+p)/2,y=Math.abs(v-f),x=Math.abs(m-h),b=\"A\"+y+\",\"+x,_=v+y+\",\"+m,w=v+\",\"+(m-x);return\"M\"+_+b+\" 0 1,1 \"+w+b+\" 0 0,1 \"+_+\"Z\"}function b(t,e,n){return t.replace(C,function(t){var r=0,a=t.charAt(0),o=P[a],i=N[a],l=D[a],s=t.substr(1).replace(O,function(t){return r>=l?t:(o[r]?t=e(t):i[r]&&(t=n(t)),r++,t)});return a+s})}function _(t,e,n,r,a){var o=\"category\"===t.type?Number:t.d2c;if(void 0!==e)return[o(e),o(n)];if(r){var i,l,s,c,u,f=1/0,d=-(1/0),h=r.match(C);for(\"date\"===t.type&&(o=g(o)),i=0;i<h.length;i++)l=h[i],s=a[l.charAt(0)].drawn,void 0!==s&&(c=h[i].substr(1).match(O),!c||c.length<s||(u=o(c[s]),f>u&&(f=u),u>d&&(d=u)));return d>=f?[f,d]:void 0}}var w=t(\"fast-isnumeric\"),k=t(\"../../plotly\"),M=t(\"../../lib\"),A=t(\"../../plots/cartesian/axes\"),L=t(\"../color\"),T=t(\"../drawing\"),z=t(\"../dragelement\"),S=t(\"../../lib/setcursor\"),E=e.exports={};E.layoutAttributes=t(\"./attributes\"),E.supplyLayoutDefaults=function(t,e){for(var n=t.shapes||[],a=e.shapes=[],o=0;o<n.length;o++)a.push(r(n[o]||{},e))},E.drawAll=function(t){var e=t._fullLayout;e._shapeUpperLayer.selectAll(\"path\").remove(),e._shapeLowerLayer.selectAll(\"path\").remove(),e._shapeSubplotLayer.selectAll(\"path\").remove();for(var n=0;n<e.shapes.length;n++)E.draw(t,n)},E.add=function(t){var e=t._fullLayout.shapes.length;k.relayout(t,\"shapes[\"+e+\"]\",\"add\")},E.draw=function(t,e,n,r){if(!w(e)||-1===e){if(!e&&Array.isArray(r))return void i(t,r);if(\"remove\"===r)return void l(t);if(n&&\"add\"!==r)return void s(t,n,r);e=t._fullLayout.shapes.length,t._fullLayout.shapes.push({})}if(!n&&r){if(\"remove\"===r)return void c(t,e);(\"add\"===r||M.isPlainObject(r))&&u(t,e,r)}f(t,e,n,r)};var C=/[MLHVQCTSZ][^MLHVQCTSZ]*/g,O=/[^\\s,]+/g,P={M:{0:!0,drawn:0},L:{0:!0,drawn:0},H:{0:!0,drawn:0},V:{},Q:{0:!0,2:!0,drawn:2},C:{0:!0,2:!0,4:!0,drawn:4},T:{0:!0,drawn:0},S:{0:!0,2:!0,drawn:2},Z:{}},N={M:{1:!0,drawn:1},L:{1:!0,drawn:1},H:{},V:{0:!0,drawn:0},Q:{1:!0,3:!0,drawn:3},C:{1:!0,3:!0,5:!0,drawn:5},T:{1:!0,drawn:1},S:{1:!0,3:!0,drawn:5},Z:{}},D={M:2,L:2,H:1,V:1,Q:4,C:6,T:2,S:4,Z:0};E.convertPath=function(t,e,n){return t.replace(C,function(t){var r=0,a=t.charAt(0),o=P[a],i=N[a],l=D[a],s=t.substr(1).replace(O,function(t){return o[r]?t=e(t):i[r]&&(t=n(t)),r++,r>l&&(t=\"X\"),t});return r>l&&(s=s.replace(/[\\s,]*X.*/,\"\"),M.log(\"Ignoring extra params in segment \"+t)),a+s})},E.calcAutorange=function(t){var e,n,r,a,o,i=t._fullLayout,l=i.shapes;if(l.length&&t._fullData.length)for(e=0;e<l.length;e++)n=l[e],r=n.line.width/2,\"paper\"!==n.xref&&(a=A.getFromId(t,n.xref),o=_(a,n.x0,n.x1,n.path,P),o&&A.expand(a,o,{ppad:r})),\"paper\"!==n.yref&&(a=A.getFromId(t,n.yref),o=_(a,n.y0,n.y1,n.path,N),o&&A.expand(a,o,{ppad:r}))}},{\"../../lib\":89,\"../../lib/setcursor\":98,\"../../plotly\":107,\"../../plots/cartesian/axes\":110,\"../color\":18,\"../dragelement\":39,\"../drawing\":41,\"./attributes\":79,\"fast-isnumeric\":11}],81:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"fast-isnumeric\"),o=t(\"../../plotly\"),i=t(\"../../plots/plots\"),l=t(\"../../lib\"),s=t(\"../drawing\"),c=t(\"../color\"),u=t(\"../../lib/svg_text_utils\"),f=e.exports={};f.draw=function(t,e,n){function f(t){l.syncOrAsync([d,h],t)}function d(e){return e.attr(\"transform\",_?\"rotate(\"+[_.rotate,b.x,b.y]+\") translate(0, \"+_.offset+\")\":null),e.style({\"font-family\":M,\"font-size\":r.round(A,2)+\"px\",fill:c.rgb(L),opacity:T*c.opacity(L),\"font-weight\":i.fontWeight}).attr(b).call(u.convertToTspans).attr(b),e.selectAll(\"tspan.line\").attr(b),i.previousPromises(t)}function h(t){var e=r.select(t.node().parentNode);if(x&&x.selection&&x.side&&S){e.attr(\"transform\",null);var n=0,o={left:\"right\",right:\"left\",top:\"bottom\",bottom:\"top\"}[x.side],i=-1!==[\"left\",\"top\"].indexOf(x.side)?-1:1,c=a(x.pad)?x.pad:2,u=s.bBox(e.node()),f={left:0,top:0,right:k.width,bottom:k.height},d=x.maxShift||(f[x.side]-u[x.side])*(\"left\"===x.side||\"top\"===x.side?-1:1);if(0>d?n=d:(u.left-=x.offsetLeft,u.right-=x.offsetLeft,u.top-=x.offsetTop,u.bottom-=x.offsetTop,x.selection.each(function(){var t=s.bBox(this);l.bBoxIntersect(u,t,c)&&(n=Math.max(n,i*(t[x.side]-u[o])+c))}),n=Math.min(d,n)),n>0||0>d){var h={left:[-n,0],right:[n,0],top:[0,-n],bottom:[0,n]}[x.side];e.attr(\"transform\",\"translate(\"+h+\")\")}}}function p(){T=0,z=!0,S=C,k._infolayer.select(\".\"+e).attr({\"data-unformatted\":S}).text(S).on(\"mouseover.opacity\",function(){r.select(this).transition().duration(100).style(\"opacity\",1)}).on(\"mouseout.opacity\",function(){r.select(this).transition().duration(1e3).style(\"opacity\",0)})}var g=n.propContainer,v=n.propName,m=n.traceIndex,y=n.dfltName,x=n.avoid||{},b=n.attributes,_=n.transform,w=n.containerGroup,k=t._fullLayout,M=g.titlefont.family,A=g.titlefont.size,L=g.titlefont.color,T=1,z=!1,S=g.title.trim();\"\"===S&&(T=0),S.match(/Click to enter .+ title/)&&(T=.2,z=!0),w||(w=k._infolayer.selectAll(\".g-\"+e).data([0]),w.enter().append(\"g\").classed(\"g-\"+e,!0));var E=w.selectAll(\"text\").data([0]);E.enter().append(\"text\"),E.text(S).attr(\"class\",e),E.attr({\"data-unformatted\":S}).call(f);var C=\"Click to enter \"+y+\" title\";t._context.editable?(S||p(),E.call(u.makeEditable).on(\"edit\",function(e){void 0!==m?o.restyle(t,v,e,m):o.relayout(t,v,e)}).on(\"cancel\",function(){this.text(this.attr(\"data-unformatted\")).call(f)}).on(\"input\",function(t){this.text(t||\" \").attr(b).selectAll(\"tspan.line\").attr(b)})):S&&!S.match(/Click to enter .+ title/)||E.remove(),E.classed(\"js-placeholder\",z)}},{\"../../lib\":89,\"../../lib/svg_text_utils\":100,\"../../plotly\":107,\"../../plots/plots\":130,\"../color\":18,\"../drawing\":41,d3:9,\"fast-isnumeric\":11}],82:[function(t,e,n){\"use strict\";n.xmlns=\"http://www.w3.org/2000/xmlns/\",n.svg=\"http://www.w3.org/2000/svg\",n.xlink=\"http://www.w3.org/1999/xlink\",n.svgAttrs={xmlns:n.svg,\"xmlns:xlink\":n.xlink}},{}],83:[function(t,e,n){\"use strict\";var r=t(\"./plotly\");n.version=\"1.15.0\",n.plot=r.plot,n.newPlot=r.newPlot,n.restyle=r.restyle,n.relayout=r.relayout,n.redraw=r.redraw,n.extendTraces=r.extendTraces,n.prependTraces=r.prependTraces,n.addTraces=r.addTraces,n.deleteTraces=r.deleteTraces,n.moveTraces=r.moveTraces,n.purge=r.purge,n.setPlotConfig=t(\"./plot_api/set_plot_config\"),n.register=r.register,n.toImage=t(\"./plot_api/to_image\"),n.downloadImage=t(\"./snapshot/download\"),n.validate=t(\"./plot_api/validate\"),n.Icons=t(\"../build/ploticon\"),n.Plots=r.Plots,n.Fx=r.Fx,n.Snapshot=r.Snapshot,n.PlotSchema=r.PlotSchema,n.Queue=r.Queue,n.d3=t(\"d3\")},{\"../build/ploticon\":2,\"./plot_api/set_plot_config\":104,\"./plot_api/to_image\":105,\"./plot_api/validate\":106,\"./plotly\":107,\"./snapshot/download\":137,d3:9}],84:[function(t,e,n){\"use strict\";\"undefined\"!=typeof MathJax?(n.MathJax=!0,MathJax.Hub.Config({messageStyle:\"none\",skipStartupTypeset:!0,displayAlign:\"left\",tex2jax:{inlineMath:[[\"$\",\"$\"],[\"\\\\(\",\"\\\\)\"]]}}),MathJax.Hub.Configured()):n.MathJax=!1},{}],85:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\"),a=t(\"tinycolor2\"),o=t(\"./nested_property\"),i=t(\"../components/colorscale/get_scale\"),l=(Object.keys(t(\"../components/colorscale/scales\")),/^([2-9]|[1-9][0-9]+)$/);n.valObjects={data_array:{coerceFunction:function(t,e,n){Array.isArray(t)?e.set(t):void 0!==n&&e.set(n)}},enumerated:{coerceFunction:function(t,e,n,r){r.coerceNumber&&(t=+t),-1===r.values.indexOf(t)?e.set(n):e.set(t)}},\"boolean\":{coerceFunction:function(t,e,n){t===!0||t===!1?e.set(t):e.set(n)}},number:{coerceFunction:function(t,e,n,a){!r(t)||void 0!==a.min&&t<a.min||void 0!==a.max&&t>a.max?e.set(n):e.set(+t)}},integer:{coerceFunction:function(t,e,n,a){t%1||!r(t)||void 0!==a.min&&t<a.min||void 0!==a.max&&t>a.max?e.set(n):e.set(+t)}},string:{coerceFunction:function(t,e,n,r){if(\"string\"!=typeof t){var a=\"number\"==typeof t;r.strict!==!0&&a?e.set(String(t)):e.set(n)}else r.noBlank&&!t?e.set(n):e.set(t)}},color:{coerceFunction:function(t,e,n){a(t).isValid()?e.set(t):e.set(n)}},colorscale:{coerceFunction:function(t,e,n){e.set(i(t,n))}},angle:{coerceFunction:function(t,e,n){\"auto\"===t?e.set(\"auto\"):r(t)?(Math.abs(t)>180&&(t-=360*Math.round(t/360)),e.set(+t)):e.set(n)}},subplotid:{coerceFunction:function(t,e,n){var r=n.length;return\"string\"==typeof t&&t.substr(0,r)===n&&l.test(t.substr(r))?void e.set(t):void e.set(n)},validateFunction:function(t,e){var n=e.dflt,r=n.length;return t===n?!0:\"string\"!=typeof t?!1:!(t.substr(0,r)!==n||!l.test(t.substr(r)))}},flaglist:{coerceFunction:function(t,e,n,r){if(\"string\"!=typeof t)return void e.set(n);if(-1!==(r.extras||[]).indexOf(t)" -, -")return void e.set(t);for(var a=t.split(\"+\"),o=0;o<a.length;){var i=a[o];-1===r.flags.indexOf(i)||a.indexOf(i)<o?a.splice(o,1):o++}a.length?e.set(a.join(\"+\")):e.set(n)}},any:{coerceFunction:function(t,e,n){void 0===t?e.set(n):e.set(t)}},info_array:{coerceFunction:function(t,e,r,a){if(!Array.isArray(t))return void e.set(r);var o=a.items,i=[];r=Array.isArray(r)?r:[];for(var l=0;l<o.length;l++)n.coerce(t,i,o,\"[\"+l+\"]\",r[l]);e.set(i)},validateFunction:function(t,e){if(!Array.isArray(t))return!1;var r=e.items;if(t.length!==r.length)return!1;for(var a=0;a<r.length;a++){var o=n.validate(t[a],e.items[a]);if(!o)return!1}return!0}}},n.coerce=function(t,e,r,a,i){var l=o(r,a).get(),s=o(t,a),c=o(e,a),u=s.get();return void 0===i&&(i=l.dflt),l.arrayOk&&Array.isArray(u)?(c.set(u),u):(n.valObjects[l.valType].coerceFunction(u,c,i,l),c.get())},n.coerce2=function(t,e,r,a,i){var l=o(t,a),s=n.coerce(t,e,r,a,i);return l.get()?s:!1},n.coerceFont=function(t,e,n){var r={};return n=n||{},r.family=t(e+\".family\",n.family),r.size=t(e+\".size\",n.size),r.color=t(e+\".color\",n.color),r},n.validate=function(t,e){var r=n.valObjects[e.valType];if(e.arrayOk&&Array.isArray(t))return!0;if(r.validateFunction)return r.validateFunction(t,e);var a={},o=a,i={set:function(t){o=t}};return r.coerceFunction(t,i,a,e),o!==a}},{\"../components/colorscale/get_scale\":30,\"../components/colorscale/scales\":36,\"./nested_property\":93,\"fast-isnumeric\":11,tinycolor2:13}],86:[function(t,e,n){\"use strict\";function r(t,e){return String(t+Math.pow(10,e)).substr(1)}function a(t){var e;return e=x.test(t)?\"Y\":\"y\",e+=b.test(t)?\"b\":\"\"}function o(t){var e;return e=w.test(t)?_.test(t)?\"I\":\"H\":\"D\"}var i=t(\"d3\"),l=t(\"fast-isnumeric\"),s=t(\"../lib\");n.dateTime2ms=function(t){try{if(t.getTime)return+t}catch(e){return!1}var n,r,a,o,i=String(t).split(\" \");if(i.length>2)return!1;var s=i[0].split(\"-\");if(s.length>3||3!==s.length&&i[1])return!1;if(4===s[0].length)n=Number(s[0]);else{if(2!==s[0].length)return!1;var c=(new Date).getFullYear();n=((Number(s[0])-c+70)%100+200)%100+c-70}return l(n)?1===s.length?new Date(n,0,1).getTime():(r=Number(s[1])-1,s[1].length>2||!(r>=0&&11>=r)?!1:2===s.length?new Date(n,r,1).getTime():(a=Number(s[2]),s[2].length>2||!(a>=1&&31>=a)?!1:(a=new Date(n,r,a).getTime(),i[1]?(s=i[1].split(\":\"),s.length>3?!1:(o=Number(s[0]),s[0].length>2||!(o>=0&&23>=o)?!1:(a+=36e5*o,1===s.length?a:(r=Number(s[1]),s[1].length>2||!(r>=0&&59>=r)?!1:(a+=6e4*r,2===s.length?a:(t=Number(s[2]),t>=0&&60>t?a+1e3*t:!1)))))):a))):!1},n.isDateTime=function(t){return n.dateTime2ms(t)!==!1},n.ms2DateTime=function(t,e){if(\"undefined\"==typeof i)return void s.error(\"d3 is not defined.\");e||(e=0);var n=new Date(t),a=i.time.format(\"%Y-%m-%d\")(n);return 7776e6>e?(a+=\" \"+r(n.getHours(),2),432e6>e&&(a+=\":\"+r(n.getMinutes(),2),108e5>e&&(a+=\":\"+r(n.getSeconds(),2),3e5>e&&(a+=\".\"+r(n.getMilliseconds(),3)))),a.replace(/([:\\s]00)*\\.?[0]*$/,\"\")):a};var c={H:[\"%H:%M:%S~%L\",\"%H:%M:%S\",\"%H:%M\"],I:[\"%I:%M:%S~%L%p\",\"%I:%M:%S%p\",\"%I:%M%p\"],D:[\"%H\",\"%I%p\",\"%Hh\"]},u={Y:[\"%Y~%m~%d\",\"%Y%m%d\",\"%y%m%d\",\"%m~%d~%Y\",\"%d~%m~%Y\"],Yb:[\"%b~%d~%Y\",\"%d~%b~%Y\",\"%Y~%d~%b\",\"%Y~%b~%d\"],y:[\"%m~%d~%y\",\"%d~%m~%y\",\"%y~%m~%d\"],yb:[\"%b~%d~%y\",\"%d~%b~%y\",\"%y~%d~%b\",\"%y~%b~%d\"]},f=i.time.format.utc,d={Y:{H:[\"%Y~%m~%dT%H:%M:%S\",\"%Y~%m~%dT%H:%M:%S~%L\"].map(f),I:[],D:[\"%Y%m%d%H%M%S\",\"%Y~%m\",\"%m~%Y\"].map(f)},Yb:{H:[],I:[],D:[\"%Y~%b\",\"%b~%Y\"].map(f)},y:{H:[],I:[],D:[]},yb:{H:[],I:[],D:[]}};[\"Y\",\"Yb\",\"y\",\"yb\"].forEach(function(t){u[t].forEach(function(e){d[t].D.push(f(e)),[\"H\",\"I\",\"D\"].forEach(function(n){c[n].forEach(function(r){var a=d[t][n];a.push(f(e+\"~\"+r)),a.push(f(r+\"~\"+e))})})})});var h=/[a-z]*/g,p=function(t){return t.substr(0,3)},g=/(mon|tue|wed|thu|fri|sat|sun|the|of|st|nd|rd|th)/g,v=/[\\s,\\/\\-\\.\\(\\)]+/g,m=/~?([ap])~?m(~|$)/,y=function(t,e){return e+\"m \"},x=/\\d\\d\\d\\d/,b=/(^|~)[a-z]{3}/,_=/[ap]m/,w=/:/,k=/q([1-4])/,M=[\"31~mar\",\"30~jun\",\"30~sep\",\"31~dec\"],A=function(t,e){return M[e-1]},L=/ ?([+\\-]\\d\\d:?\\d\\d|Z)$/;n.parseDate=function(t){if(t.getTime)return t;if(\"string\"!=typeof t)return!1;t=t.toLowerCase().replace(h,p).replace(g,\"\").replace(v,\"~\").replace(m,y).replace(k,A).trim().replace(L,\"\");var e,n,r=null,i=a(t),l=o(t);e=d[i][l],n=e.length;for(var s=0;n>s&&!(r=e[s].parse(t));s++);if(!(r instanceof Date))return!1;var c=r.getTimezoneOffset();return r.setTime(r.getTime()+60*c*1e3),r}},{\"../lib\":89,d3:9,\"fast-isnumeric\":11}],87:[function(t,e,n){\"use strict\";var r=t(\"events\").EventEmitter,a={init:function(t){if(t._ev instanceof r)return t;var e=new r;return t._ev=e,t.on=e.on.bind(e),t.once=e.once.bind(e),t.removeListener=e.removeListener.bind(e),t.removeAllListeners=e.removeAllListeners.bind(e),t.emit=function(n,r){\"undefined\"!=typeof jQuery&&jQuery(t).trigger(n,r),e.emit(n,r)},t},triggerHandler:function(t,e,n){var r,a;\"undefined\"!=typeof jQuery&&(r=jQuery(t).triggerHandler(e,n));var o=t._ev;if(!o)return r;var i=o._events[e];if(!i)return r;\"function\"==typeof i&&(i=[i]);for(var l=i.pop(),s=0;s<i.length;s++)i[s](n);return a=l(n),void 0!==r?r:a},purge:function(t){return delete t._ev,delete t.on,delete t.once,delete t.removeListener,delete t.removeAllListeners,delete t.emit,t}};e.exports=a},{events:7}],88:[function(t,e,n){\"use strict\";function r(t,e){var n,r;for(n=0;n<t.length;n++){if(r=t[n],null!==r&&\"object\"==typeof r)return!1;void 0!==r&&(e[n]=r)}return!0}function a(t,e,n){var l,s,c,u,f,d,h,p=t[0],g=t.length;if(2===g&&i(p)&&i(t[1])&&0===p.length){if(h=r(t[1],p))return p;p.splice(0,p.length)}for(var v=1;g>v;v++){l=t[v];for(s in l)c=p[s],u=l[s],e&&u&&(o(u)||(f=i(u)))?(f?(f=!1,d=c&&i(c)?c:[]):d=c&&o(c)?c:{},p[s]=a([d,u],e,n)):(\"undefined\"!=typeof u||n)&&(p[s]=u)}return p}var o=t(\"./is_plain_object.js\"),i=Array.isArray;n.extendFlat=function(){return a(arguments,!1,!1)},n.extendDeep=function(){return a(arguments,!0,!1)},n.extendDeepAll=function(){return a(arguments,!0,!0)}},{\"./is_plain_object.js\":90}],89:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=e.exports={};a.nestedProperty=t(\"./nested_property\"),a.isPlainObject=t(\"./is_plain_object\");var o=t(\"./coerce\");a.valObjects=o.valObjects,a.coerce=o.coerce,a.coerce2=o.coerce2,a.coerceFont=o.coerceFont,a.validate=o.validate;var i=t(\"./dates\");a.dateTime2ms=i.dateTime2ms,a.isDateTime=i.isDateTime,a.ms2DateTime=i.ms2DateTime,a.parseDate=i.parseDate;var l=t(\"./search\");a.findBin=l.findBin,a.sorterAsc=l.sorterAsc,a.sorterDes=l.sorterDes,a.distinctVals=l.distinctVals,a.roundUp=l.roundUp;var s=t(\"./stats\");a.aggNums=s.aggNums,a.len=s.len,a.mean=s.mean,a.variance=s.variance,a.stdev=s.stdev,a.interp=s.interp;var c=t(\"./matrix\");a.init2dArray=c.init2dArray,a.transposeRagged=c.transposeRagged,a.dot=c.dot,a.translationMatrix=c.translationMatrix,a.rotationMatrix=c.rotationMatrix,a.rotationXYMatrix=c.rotationXYMatrix,a.apply2DTransform=c.apply2DTransform,a.apply2DTransform2=c.apply2DTransform2;var u=t(\"./extend\");a.extendFlat=u.extendFlat,a.extendDeep=u.extendDeep,a.extendDeepAll=u.extendDeepAll;var f=t(\"./loggers\");a.log=f.log,a.warn=f.warn,a.error=f.error,a.notifier=t(\"./notifier\"),a.swapAttrs=function(t,e,n,r){n||(n=\"x\"),r||(r=\"y\");for(var o=0;o<e.length;o++){var i=e[o],l=a.nestedProperty(t,i.replace(\"?\",n)),s=a.nestedProperty(t,i.replace(\"?\",r)),c=l.get();l.set(s.get()),s.set(c)}},a.pauseEvent=function(t){return t.stopPropagation&&t.stopPropagation(),t.preventDefault&&t.preventDefault(),t.cancelBubble=!0,!1},a.constrain=function(t,e,n){return e>n?Math.max(n,Math.min(e,t)):Math.max(e,Math.min(n,t))},a.bBoxIntersect=function(t,e,n){return n=n||0,t.left<=e.right+n&&e.left<=t.right+n&&t.top<=e.bottom+n&&e.top<=t.bottom+n},a.identity=function(t){return t},a.randstr=function d(t,e,n){if(n||(n=16),void 0===e&&(e=24),0>=e)return\"0\";var r,a,o,i=Math.log(Math.pow(2,e))/Math.log(n),l=\"\";for(r=2;i===1/0;r*=2)i=Math.log(Math.pow(2,e/r))/Math.log(n)*r;var s=i-Math.floor(i);for(r=0;r<Math.floor(i);r++)o=Math.floor(Math.random()*n).toString(n),l=o+l;s&&(a=Math.pow(n,s),o=Math.floor(Math.random()*a).toString(n),l=o+l);var c=parseInt(l,n);return t&&t.indexOf(l)>-1||c!==1/0&&c>=Math.pow(2,e)?d(t,e,n):l},a.OptionControl=function(t,e){t||(t={}),e||(e=\"opt\");var n={};return n.optionList=[],n._newoption=function(r){r[e]=t,n[r.name]=r,n.optionList.push(r)},n[\"_\"+e]=t,n},a.smooth=function(t,e){if(e=Math.round(e)||0,2>e)return t;var n,r,a,o,i=t.length,l=2*i,s=2*e-1,c=new Array(s),u=new Array(i);for(n=0;s>n;n++)c[n]=(1-Math.cos(Math.PI*(n+1)/e))/(2*e);for(n=0;i>n;n++){for(o=0,r=0;s>r;r++)a=n+r+1-e,-i>a?a-=l*Math.round(a/l):a>=l&&(a-=l*Math.floor(a/l)),0>a?a=-1-a:a>=i&&(a=l-1-a),o+=t[a]*c[r];u[n]=o}return u},a.syncOrAsync=function(t,e,n){function r(){return a.syncOrAsync(t,e,n)}for(var o,i;t.length;)if(i=t.splice(0,1)[0],o=i(e),o&&o.then)return o.then(r).then(void 0,a.promiseError);return n&&n(e)},a.stripTrailingSlash=function(t){return\"/\"===t.substr(-1)?t.substr(0,t.length-1):t},a.noneOrAll=function(t,e,n){if(t){var r,a,o=!1,i=!0;for(r=0;r<n.length;r++)a=t[n[r]],void 0!==a&&null!==a?o=!0:i=!1;if(o&&!i)for(r=0;r<n.length;r++)t[n[r]]=e[n[r]]}},a.pushUnique=function(t,e){return e&&-1===t.indexOf(e)&&t.push(e),t},a.mergeArray=function(t,e,n){if(Array.isArray(t))for(var r=Math.min(t.length,e.length),a=0;r>a;a++)e[a][n]=t[a]},a.minExtend=function(t,e){var n={};\"object\"!=typeof e&&(e={});var r,o,i,l=3,s=Object.keys(t);for(r=0;r<s.length;r++)o=s[r],i=t[o],\"_\"!==o.charAt(0)&&\"function\"!=typeof i&&(\"module\"===o?n[o]=i:Array.isArray(i)?n[o]=i.slice(0,l):i&&\"object\"==typeof i?n[o]=a.minExtend(t[o],e[o]):n[o]=i);for(s=Object.keys(e),r=0;r<s.length;r++)o=s[r],i=e[o],\"object\"==typeof i&&o in n&&\"object\"==typeof n[o]||(n[o]=i);return n},a.titleCase=function(t){return t.charAt(0).toUpperCase()+t.substr(1)},a.containsAny=function(t,e){for(var n=0;n<e.length;n++)if(-1!==t.indexOf(e[n]))return!0;return!1},a.getPlotDiv=function(t){for(;t&&t.removeAttribute;t=t.parentNode)if(a.isPlotDiv(t))return t},a.isPlotDiv=function(t){var e=r.select(t);return e.size()&&e.classed(\"js-plotly-plot\")},a.removeElement=function(t){var e=t&&t.parentNode;e&&e.removeChild(t)},a.add" -, -"StyleRule=function(t,e){if(!a.styleSheet){var n=document.createElement(\"style\");n.appendChild(document.createTextNode(\"\")),document.head.appendChild(n),a.styleSheet=n.sheet}var r=a.styleSheet;r.insertRule?r.insertRule(t+\"{\"+e+\"}\",0):r.addRule?r.addRule(t,e,0):a.warn(\"addStyleRule failed\")},a.getTranslate=function(t){var e=/.*\\btranslate\\((\\d*\\.?\\d*)[^\\d]*(\\d*\\.?\\d*)[^\\d].*/,n=t.attr?\"attr\":\"getAttribute\",r=t[n](\"transform\")||\"\",a=r.replace(e,function(t,e,n){return[e,n].join(\" \")}).split(\" \");return{x:+a[0]||0,y:+a[1]||0}},a.setTranslate=function(t,e,n){var r=/(\\btranslate\\(.*?\\);?)/,a=t.attr?\"attr\":\"getAttribute\",o=t.attr?\"attr\":\"setAttribute\",i=t[a](\"transform\")||\"\";return e=e||0,n=n||0,i=i.replace(r,\"\").trim(),i+=\" translate(\"+e+\", \"+n+\")\",i=i.trim(),t[o](\"transform\",i),i},a.getScale=function(t){var e=/.*\\bscale\\((\\d*\\.?\\d*)[^\\d]*(\\d*\\.?\\d*)[^\\d].*/,n=t.attr?\"attr\":\"getAttribute\",r=t[n](\"transform\")||\"\",a=r.replace(e,function(t,e,n){return[e,n].join(\" \")}).split(\" \");return{x:+a[0]||1,y:+a[1]||1}},a.setScale=function(t,e,n){var r=/(\\bscale\\(.*?\\);?)/,a=t.attr?\"attr\":\"getAttribute\",o=t.attr?\"attr\":\"setAttribute\",i=t[a](\"transform\")||\"\";return e=e||1,n=n||1,i=i.replace(r,\"\").trim(),i+=\" scale(\"+e+\", \"+n+\")\",i=i.trim(),t[o](\"transform\",i),i},a.setPointGroupScale=function(t,e,n){var r,a,o;return e=e||1,n=n||1,a=1===e&&1===n?\"\":\" scale(\"+e+\",\"+n+\")\",o=/\\s*sc.*/,t.each(function(){r=(this.getAttribute(\"transform\")||\"\").replace(o,\"\"),r+=a,r=r.trim(),this.setAttribute(\"transform\",r)}),a},a.isIE=function(){return\"undefined\"!=typeof window.navigator.msSaveBlob},a.objectFromPath=function(t,e){for(var n,r=t.split(\".\"),a=n={},o=0;o<r.length;o++){var i=r[o],l=null,s=r[o].match(/(.*)\\[([0-9]+)\\]/);s?(i=s[1],l=s[2],n=n[i]=[],o===r.length-1?n[l]=e:n[l]={},n=n[l]):(o===r.length-1?n[i]=e:n[i]={},n=n[i])}return a},a.numSeparate=function(t,e){if(\"string\"!=typeof e||0===e.length)throw new Error(\"Separator string required for formatting!\");\"number\"==typeof t&&(t=String(t));var n=/(\\d+)(\\d{3})/,r=e.charAt(0),a=e.charAt(1),o=t.split(\".\"),i=o[0],l=o.length>1?r+o[1]:\"\";\n" -, -"if(a&&(o.length>1||i.length>4))for(;n.test(i);)i=i.replace(n,\"$1\"+a+\"$2\");return i+l}},{\"./coerce\":85,\"./dates\":86,\"./extend\":88,\"./is_plain_object\":90,\"./loggers\":91,\"./matrix\":92,\"./nested_property\":93,\"./notifier\":94,\"./search\":97,\"./stats\":99,d3:9}],90:[function(t,e,n){\"use strict\";e.exports=function(t){return\"[object Object]\"===Object.prototype.toString.call(t)&&Object.getPrototypeOf(t)===Object.prototype}},{}],91:[function(t,e,n){\"use strict\";var r=t(\"../plot_api/plot_config\"),a=e.exports={};a.log=function(){if(r.logging>1){for(var t=[\"LOG:\"],e=0;e<arguments.length;e++)t.push(arguments[e]);console.trace?console.trace.apply(console,t):console.log.apply(console,t)}},a.warn=function(){if(r.logging>0){for(var t=[\"WARN:\"],e=0;e<arguments.length;e++)t.push(arguments[e]);console.trace?console.trace.apply(console,t):console.log.apply(console,t)}},a.error=function(){if(r.logging>0){for(var t=[\"ERROR:\"],e=0;e<arguments.length;e++)t.push(arguments[e]);console.error.apply(console,arguments)}}},{\"../plot_api/plot_config\":102}],92:[function(t,e,n){\"use strict\";n.init2dArray=function(t,e){for(var n=new Array(t),r=0;t>r;r++)n[r]=new Array(e);return n},n.transposeRagged=function(t){var e,n,r=0,a=t.length;for(e=0;a>e;e++)r=Math.max(r,t[e].length);var o=new Array(r);for(e=0;r>e;e++)for(o[e]=new Array(a),n=0;a>n;n++)o[e][n]=t[n][e];return o},n.dot=function(t,e){if(!t.length||!e.length||t.length!==e.length)return null;var r,a,o=t.length;if(t[0].length)for(r=new Array(o),a=0;o>a;a++)r[a]=n.dot(t[a],e);else if(e[0].length){var i=n.transposeRagged(e);for(r=new Array(i.length),a=0;a<i.length;a++)r[a]=n.dot(t,i[a])}else for(r=0,a=0;o>a;a++)r+=t[a]*e[a];return r},n.translationMatrix=function(t,e){return[[1,0,t],[0,1,e],[0,0,1]]},n.rotationMatrix=function(t){var e=t*Math.PI/180;return[[Math.cos(e),-Math.sin(e),0],[Math.sin(e),Math.cos(e),0],[0,0,1]]},n.rotationXYMatrix=function(t,e,r){return n.dot(n.dot(n.translationMatrix(e,r),n.rotationMatrix(t)),n.translationMatrix(-e,-r))},n.apply2DTransform=function(t){return function(){var e=arguments;3===e.length&&(e=e[0]);var r=1===arguments.length?e[0]:[e[0],e[1]];return n.dot(t,[r[0],r[1],1]).slice(0,2)}},n.apply2DTransform2=function(t){var e=n.apply2DTransform(t);return function(t){return e(t.slice(0,2)).concat(e(t.slice(2,4)))}}},{}],93:[function(t,e,n){\"use strict\";function r(t,e){return function(){var n,a,o,i,l,s=t;for(i=0;i<e.length-1;i++){if(n=e[i],-1===n){for(a=!0,o=[],l=0;l<s.length;l++)o[l]=r(s[l],e.slice(i+1))(),o[l]!==o[0]&&(a=!1);return a?o[0]:o}if(\"number\"==typeof n&&!Array.isArray(s))return;if(s=s[n],\"object\"!=typeof s||null===s)return}if(\"object\"==typeof s&&null!==s&&(o=s[e[i]],null!==o))return o}}function a(t,e){var n=[\"annotations\",\"shapes\",\"range\",\"domain\",\"buttons\"],r=-1===n.indexOf(e);return Array.isArray(t)&&r}function o(t,e){return function(n){var r,o,u=t,f=[t],d=c(n)&&!a(n,e[e.length-1]);for(o=0;o<e.length-1;o++){if(r=e[o],\"number\"==typeof r&&!Array.isArray(u))throw\"array index but container is not an array\";if(-1===r){if(d=!i(u,e.slice(o+1),n))break;return}if(!l(u,r,e[o+1],d))break;if(u=u[r],\"object\"!=typeof u||null===u)throw\"container is not an object\";f.push(u)}d?(o===e.length-1&&delete u[e[o]],s(f)):u[e[o]]=n}}function i(t,e,n){var r,a=Array.isArray(n),i=!0,s=n,u=a?!1:c(n),f=e[0];for(r=0;r<t.length;r++)a&&(s=n[r%n.length],u=c(s)),u&&(i=!1),l(t,r,f,u)&&o(t[r],e)(s);return i}function l(t,e,n,r){if(void 0===t[e]){if(r)return!1;\"number\"==typeof n?t[e]=[]:t[e]={}}return!0}function s(t){var e,n,r,o,i;for(e=t.length-1;e>=0;e--){if(r=t[e],i=!1,Array.isArray(r))for(n=r.length-1;n>=0;n--)c(r[n])?i?r[n]=void 0:r.pop():i=!0;else if(\"object\"==typeof r&&null!==r)for(o=Object.keys(r),i=!1,n=o.length-1;n>=0;n--)c(r[o[n]])&&!a(r[o[n]],o[n])?delete r[o[n]]:i=!0;if(i)return}}function c(t){return void 0===t||null===t?!0:\"object\"!=typeof t?!1:Array.isArray(t)?!t.length:!Object.keys(t).length}function u(t,e,n){return{set:function(){throw\"bad container\"},get:function(){},astr:e,parts:n,obj:t}}var f=t(\"fast-isnumeric\");e.exports=function(t,e){if(f(e))e=String(e);else if(\"string\"!=typeof e||\"[-1]\"===e.substr(e.length-4))throw\"bad property string\";for(var n,a,i,l=0,s=e.split(\".\");l<s.length;){if(n=String(s[l]).match(/^([^\\[\\]]*)((\\[\\-?[0-9]*\\])+)$/)){if(n[1])s[l]=n[1];else{if(0!==l)throw\"bad property string\";s.splice(0,1)}for(a=n[2].substr(1,n[2].length-2).split(\"][\"),i=0;i<a.length;i++)l++,s.splice(l,0,Number(a[i]))}l++}return\"object\"!=typeof t?u(t,e,s):{set:o(t,s),get:r(t,s),astr:e,parts:s,obj:t}}},{\"fast-isnumeric\":11}],94:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"fast-isnumeric\"),o=[];e.exports=function(t,e){function n(t){t.duration(700).style(\"opacity\",0).each(\"end\",function(t){var e=o.indexOf(t);-1!==e&&o.splice(e,1),r.select(this).remove()})}if(-1===o.indexOf(t)){o.push(t);var i=1e3;a(e)?i=e:\"long\"===e&&(i=3e3);var l=r.select(\"body\").selectAll(\".plotly-notifier\").data([0]);l.enter().append(\"div\").classed(\"plotly-notifier\",!0);var s=l.selectAll(\".notifier-note\").data(o);s.enter().append(\"div\").classed(\"notifier-note\",!0).style(\"opacity\",0).each(function(t){var e=r.select(this);e.append(\"button\").classed(\"notifier-close\",!0).html(\"×\").on(\"click\",function(){e.transition().call(n)}),e.append(\"p\").html(t),e.transition().duration(700).style(\"opacity\",1).transition().delay(i).call(n)})}}},{d3:9,\"fast-isnumeric\":11}],95:[function(t,e,n){\"use strict\";var r=t(\"./matrix\").dot,a=e.exports={};a.tester=function(t){function e(t,e){var n=t[0],r=t[1];return a>n||n>o||i>r||r>l?!1:!e||!c(t)}function n(t,e){var n=t[0],s=t[1];if(a>n||n>o||i>s||s>l)return!1;var c,u,f,d,h,p=r.length,g=r[0][0],v=r[0][1],m=0;for(c=1;p>c;c++)if(u=g,f=v,g=r[c][0],v=r[c][1],d=Math.min(u,g),!(d>n||n>Math.max(u,g)||s>Math.max(f,v)))if(s<Math.min(f,v))n!==d&&m++;else{if(h=g===u?s:f+(n-u)*(v-f)/(g-u),s===h)return 1!==c||!e;h>=s&&n!==d&&m++}return m%2===1}var r=t.slice(),a=r[0][0],o=a,i=r[0][1],l=i;r.push(r[0]);for(var s=1;s<r.length;s++)a=Math.min(a,r[s][0]),o=Math.max(o,r[s][0]),i=Math.min(i,r[s][1]),l=Math.max(l,r[s][1]);var c,u=!1;return 5===r.length&&(r[0][0]===r[1][0]?r[2][0]===r[3][0]&&r[0][1]===r[3][1]&&r[1][1]===r[2][1]&&(u=!0,c=function(t){return t[0]===r[0][0]}):r[0][1]===r[1][1]&&r[2][1]===r[3][1]&&r[0][0]===r[3][0]&&r[1][0]===r[2][0]&&(u=!0,c=function(t){return t[1]===r[0][1]})),{xmin:a,xmax:o,ymin:i,ymax:l,pts:r,contains:u?e:n,isRect:u}};var o=a.isSegmentBent=function(t,e,n,a){var o,i,l,s=t[e],c=[t[n][0]-s[0],t[n][1]-s[1]],u=r(c,c),f=Math.sqrt(u),d=[-c[1]/f,c[0]/f];for(o=e+1;n>o;o++)if(i=[t[o][0]-s[0],t[o][1]-s[1]],l=r(i,c),0>l||l>u||Math.abs(r(i,d))>a)return!0;return!1};a.filter=function(t,e){function n(n){t.push(n);var l=r.length,s=a;r.splice(i+1);for(var c=s+1;c<t.length;c++)(c===t.length-1||o(t,s,c+1,e))&&(r.push(t[c]),r.length<l-2&&(a=c,i=r.length-1),s=c)}var r=[t[0]],a=0,i=0;if(t.length>1){var l=t.pop();n(l)}return{addPt:n,raw:t,filtered:r}}},{\"./matrix\":92}],96:[function(t,e,n){\"use strict\";function r(t,e){for(var n,r=[],o=0;o<e.length;o++)n=e[o],n===t?r[o]=n:\"object\"==typeof n?r[o]=Array.isArray(n)?a.extendDeep([],n):a.extendDeepAll({},n):r[o]=n;return r}var a=t(\"../lib\"),o=t(\"../plot_api/plot_config\"),i={};i.add=function(t,e,n,r,a){var i,l;return t.undoQueue=t.undoQueue||{index:0,queue:[],sequence:!1},l=t.undoQueue.index,t.autoplay?void(t.undoQueue.inSequence||(t.autoplay=!1)):(!t.undoQueue.sequence||t.undoQueue.beginSequence?(i={undo:{calls:[],args:[]},redo:{calls:[],args:[]}},t.undoQueue.queue.splice(l,t.undoQueue.queue.length-l,i),t.undoQueue.index+=1):i=t.undoQueue.queue[l-1],t.undoQueue.beginSequence=!1,i&&(i.undo.calls.unshift(e),i.undo.args.unshift(n),i.redo.calls.push(r),i.redo.args.push(a)),void(t.undoQueue.queue.length>o.queueLength&&(t.undoQueue.queue.shift(),t.undoQueue.index--)))},i.startSequence=function(t){t.undoQueue=t.undoQueue||{index:0,queue:[],sequence:!1},t.undoQueue.sequence=!0,t.undoQueue.beginSequence=!0},i.stopSequence=function(t){t.undoQueue=t.undoQueue||{index:0,queue:[],sequence:!1},t.undoQueue.sequence=!1,t.undoQueue.beginSequence=!1},i.undo=function(t){var e,n;if(t.framework&&t.framework.isPolar)return void t.framework.undo();if(!(void 0===t.undoQueue||isNaN(t.undoQueue.index)||t.undoQueue.index<=0)){for(t.undoQueue.index--,e=t.undoQueue.queue[t.undoQueue.index],t.undoQueue.inSequence=!0,n=0;n<e.undo.calls.length;n++)i.plotDo(t,e.undo.calls[n],e.undo.args[n]);t.undoQueue.inSequence=!1,t.autoplay=!1}},i.redo=function(t){var e,n;if(t.framework&&t.framework.isPolar)return void t.framework.redo();if(!(void 0===t.undoQueue||isNaN(t.undoQueue.index)||t.undoQueue.index>=t.undoQueue.queue.length)){for(e=t.undoQueue.queue[t.undoQueue.index],t.undoQueue.inSequence=!0,n=0;n<e.redo.calls.length;n++)i.plotDo(t,e.redo.calls[n],e.redo.args[n]);t.undoQueue.inSequence=!1,t.autoplay=!1,t.undoQueue.index++}},i.plotDo=function(t,e,n){t.autoplay=!0,n=r(t,n),e.apply(null,n)},e.exports=i},{\"../lib\":89,\"../plot_api/plot_config\":102}],97:[function(t,e,n){\"use strict\";function r(t,e){return e>t}function a(t,e){return e>=t}function o(t,e){return t>e}function i(t,e){return t>=e}var l=t(\"fast-isnumeric\"),s=t(\"../lib\");n.findBin=function(t,e,n){if(l(e.start))return n?Math.ceil((t-e.start)/e.size)-1:Math.floor((t-e.start)/e.size);var c,u,f=0,d=e.length,h=0;for(u=e[e.length-1]>=e[0]?n?r:a:n?i:o;d>f&&h++<100;)c=Math.floor((f+d)/2),u(e[c],t)?f=c+1:d=c;return h>90&&s.log(\"Long binary search...\"),f-1},n.sorterAsc=function(t,e){return t-e},n.sorterDes=function(t,e){return e-t},n.distinctVals=function(t){var e=t.slice();e.sort(n.sorterAsc);for(var r=e.length-1,a=e[r]-e[0]||1,o=a/(r||1)/1e4,i=[e[0]],l=0;r>l;l++)e[l+1]>e[l]+o&&(a=Math.min(a,e[l+1]-e[l]),i.push(e[l+1]));return{vals:i,minDiff:a}},n.roundUp=function(t,e,n){for(var r,a=0,o=e.length-1,i=0,l=n?0:1,s=n?1:0,c=n?Math.ceil:Math.floor;o>a&&i++<100;)r=c((a+o)/2),e[r]<=t?a=r+l:o=r-s;return e[a]}},{\"../lib\":89,\"fast-isnumeric\":11}],98:[function(t,e,n){\"use strict\";e.exports=function(t,e){(t.attr(\"class\")||\"\").split(\" \").forEach(function(e){0===e.inde" -, -"xOf(\"cursor-\")&&t.classed(e,!1)}),e&&t.classed(\"cursor-\"+e,!0)}},{}],99:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\");n.aggNums=function(t,e,a,o){var i,l;if(o||(o=a.length),r(e)||(e=!1),Array.isArray(a[0])){for(l=new Array(o),i=0;o>i;i++)l[i]=n.aggNums(t,e,a[i]);a=l}for(i=0;o>i;i++)r(e)?r(a[i])&&(e=t(+e,+a[i])):e=a[i];return e},n.len=function(t){return n.aggNums(function(t){return t+1},0,t)},n.mean=function(t,e){return e||(e=n.len(t)),n.aggNums(function(t,e){return t+e},0,t)/e},n.variance=function(t,e,a){return e||(e=n.len(t)),r(a)||(a=n.mean(t,e)),n.aggNums(function(t,e){return t+Math.pow(e-a,2)},0,t)/e},n.stdev=function(t,e,r){return Math.sqrt(n.variance(t,e,r))},n.interp=function(t,e){if(!r(e))throw\"n should be a finite number\";if(e=e*t.length-.5,0>e)return t[0];if(e>t.length-1)return t[t.length-1];var n=e%1;return n*t[Math.ceil(e)]+(1-n)*t[Math.floor(e)]}},{\"fast-isnumeric\":11}],100:[function(t,e,n){\"use strict\";function r(t,e){return t.node().getBoundingClientRect()[e]}function a(t){return t.replace(/(<|<|<)/g,\"\\\\lt \").replace(/(>|>|>)/g,\"\\\\gt \")}function o(t,e,n){var r=\"math-output-\"+s.Lib.randstr([],64),o=c.select(\"body\").append(\"div\").attr({id:r}).style({visibility:\"hidden\",position:\"absolute\"}).style({\"font-size\":e.fontSize+\"px\"}).text(a(t));MathJax.Hub.Queue([\"Typeset\",MathJax.Hub,o.node()],function(){var e=c.select(\"body\").select(\"#MathJax_SVG_glyphs\");if(o.select(\".MathJax_SVG\").empty()||!o.select(\"svg\").node())u.log(\"There was an error in the tex syntax.\",t),n();else{var r=o.select(\"svg\").node().getBoundingClientRect();n(o.select(\".MathJax_SVG\"),e,r)}o.remove()})}function i(t){for(var e=s.util.html_entity_decode(t),n=e.split(/(<[^<>]*>)/).map(function(t){var e=t.match(/<(\\/?)([^ >]*)\\s*(.*)>/i),n=e&&e[2].toLowerCase(),r=h[n];if(void 0!==r){var a=e[1],o=e[3],i=o.match(/^style\\s*=\\s*\"([^\"]+)\"\\s*/i);if(\"a\"===n){if(a)return\"</a>\";if(\"href\"!==o.substr(0,4).toLowerCase())return\"<a>\";var l=o.substr(4).replace(/[\"']/g,\"\").replace(/=/,\"\").replace(/&/g,\"&\"),c=document.createElement(\"a\");return c.href=l,-1===p.indexOf(c.protocol)?\"<a>\":'<a xlink:show=\"new\" xlink:href=\"'+l+'\">'}if(\"br\"===n)return\"<br>\";if(a)return\"sup\"===n?'</tspan><tspan dy=\"0.42em\">​</tspan>':\"sub\"===n?'</tspan><tspan dy=\"-0.21em\">​</tspan>':\"</tspan>\";var u=\"<tspan\";return\"sup\"!==n&&\"sub\"!==n||(u=\"​\"+u),i&&(i=i[1].replace(/(^|;)\\s*color:/,\"$1 fill:\"),r=(r?r+\";\":\"\")+i),u+(r?' style=\"'+r+'\"':\"\")+\">\"}return s.util.xml_entity_encode(t).replace(/</g,\"<\")}),r=[],a=n.indexOf(\"<br>\");a>0;a=n.indexOf(\"<br>\",a+1))r.push(a);var o=0;r.forEach(function(t){for(var e=t+o,r=n.slice(0,e),a=\"\",i=r.length-1;i>=0;i--){var l=r[i].match(/<(\\/?).*>/i);if(l&&\"<br>\"!==r[i]){l[1]||(a=r[i]);break}}a&&(n.splice(e+1,0,a),n.splice(e,0,\"</tspan>\"),o+=2)});var i=n.join(\"\"),l=i.split(/<br>/gi);return l.length>1&&(n=l.map(function(t,e){return'<tspan class=\"line\" dy=\"'+1.3*e+'em\">'+t+\"</tspan>\"})),n.join(\"\")}function l(t,e,n){var r,a,o,i=n.horizontalAlign,l=n.verticalAlign||\"top\",s=t.node().getBoundingClientRect(),c=e.node().getBoundingClientRect();return a=\"bottom\"===l?function(){return s.bottom-r.height}:\"middle\"===l?function(){return s.top+(s.height-r.height)/2}:function(){return s.top},o=\"right\"===i?function(){return s.right-r.width}:\"center\"===i?function(){return s.left+(s.width-r.width)/2}:function(){return s.left},function(){return r=this.node().getBoundingClientRect(),this.style({top:a()-c.top+\"px\",left:o()-c.left+\"px\",\"z-index\":1e3}),this}}var s=t(\"../plotly\"),c=t(\"d3\"),u=t(\"../lib\"),f=t(\"../constants/xmlns_namespaces\"),d=e.exports={};c.selection.prototype.appendSVG=function(t){for(var e=['<svg xmlns=\"',f.svg,'\" ','xmlns:xlink=\"',f.xlink,'\">',t,\"</svg>\"].join(\"\"),n=(new DOMParser).parseFromString(e,\"application/xml\"),r=n.documentElement.firstChild;r;)this.node().appendChild(this.node().ownerDocument.importNode(r,!0)),r=r.nextSibling;return n.querySelector(\"parsererror\")?(u.log(n.querySelector(\"parsererror div\").textContent),null):c.select(this.node().lastChild)},d.html_entity_decode=function(t){var e=c.select(\"body\").append(\"div\").style({display:\"none\"}).html(\"\"),n=t.replace(/(&[^;]*;)/gi,function(t){return\"<\"===t?\"<\":\"&rt;\"===t?\">\":e.html(t).text()});return e.remove(),n},d.xml_entity_encode=function(t){return t.replace(/&(?!\\w+;|\\#[0-9]+;| \\#x[0-9A-F]+;)/g,\"&\")},d.convertToTspans=function(t,e){function n(){h.empty()||(p=u.attr(\"class\")+\"-math\",h.select(\"svg.\"+p).remove()),t.text(\"\").style({visibility:\"visible\",\"white-space\":\"pre\"}),d=t.appendSVG(l),d||t.text(a),t.select(\"a\").size()&&t.style(\"pointer-events\",\"all\"),e&&e.call(u)}var a=t.text(),l=i(a),u=t,f=!u.attr(\"data-notex\")&&l.match(/([^$]*)([$]+[^$]*[$]+)([^$]*)/),d=a,h=c.select(u.node().parentNode);if(!h.empty()){var p=u.attr(\"class\")?u.attr(\"class\").split(\" \")[0]:\"text\";p+=\"-math\",h.selectAll(\"svg.\"+p).remove(),h.selectAll(\"g.\"+p+\"-group\").remove(),t.style({visibility:null});for(var g=t.node();g&&g.removeAttribute;g=g.parentNode)g.removeAttribute(\"data-bb\");if(f){var v=s.Lib.getPlotDiv(u.node());(v&&v._promises||[]).push(new Promise(function(t){u.style({visibility:\"hidden\"});var a={fontSize:parseInt(u.style(\"font-size\"),10)};o(f[2],a,function(a,o,i){h.selectAll(\"svg.\"+p).remove(),h.selectAll(\"g.\"+p+\"-group\").remove();var l=a&&a.select(\"svg\");if(!l||!l.node())return n(),void t();var s=h.append(\"g\").classed(p+\"-group\",!0).attr({\"pointer-events\":\"none\"});s.node().appendChild(l.node()),o&&o.node()&&l.node().insertBefore(o.node().cloneNode(!0),l.node().firstChild),l.attr({\"class\":p,height:i.height,preserveAspectRatio:\"xMinYMin meet\"}).style({overflow:\"visible\",\"pointer-events\":\"none\"});var c=u.style(\"fill\")||\"black\";l.select(\"g\").attr({fill:c,stroke:c});var f=r(l,\"width\"),d=r(l,\"height\"),g=+u.attr(\"x\")-f*{start:0,middle:.5,end:1}[u.attr(\"text-anchor\")||\"start\"],v=parseInt(u.style(\"font-size\"),10)||r(u,\"height\"),m=-v/4;\"y\"===p[0]?(s.attr({transform:\"rotate(\"+[-90,+u.attr(\"x\"),+u.attr(\"y\")]+\") translate(\"+[-f/2,m-d/2]+\")\"}),l.attr({x:+u.attr(\"x\"),y:+u.attr(\"y\")})):\"l\"===p[0]?l.attr({x:u.attr(\"x\"),y:m-d/2}):\"a\"===p[0]?l.attr({x:0,y:m}):l.attr({x:g,y:+u.attr(\"y\")+m-d/2}),e&&e.call(u,s),t(s)})}))}else n();return t}};var h={sup:'font-size:70%\" dy=\"-0.6em',sub:'font-size:70%\" dy=\"0.3em',b:\"font-weight:bold\",i:\"font-style:italic\",a:\"\",span:\"\",br:\"\",em:\"font-style:italic;font-weight:bold\"},p=[\"http:\",\"https:\",\"mailto:\"],g=new RegExp(\"</?(\"+Object.keys(h).join(\"|\")+\")( [^>]*)?/?>\",\"g\");d.plainText=function(t){return(t||\"\").replace(g,\" \")},d.makeEditable=function(t,e,n){function r(){o(),i.style({opacity:0});var t,e=d.attr(\"class\");t=e?\".\"+e.split(\" \")[0]+\"-math-group\":\"[class*=-math-group]\",t&&c.select(i.node().parentNode).select(t).style({opacity:0})}function a(t){var e=t.node(),n=document.createRange();n.selectNodeContents(e);var r=window.getSelection();r.removeAllRanges(),r.addRange(n),e.focus()}function o(){var t=c.select(s.Lib.getPlotDiv(i.node())),e=t.select(\".svg-container\"),r=e.append(\"div\");r.classed(\"plugin-editable editable\",!0).style({position:\"absolute\",\"font-family\":i.style(\"font-family\")||\"Arial\",\"font-size\":i.style(\"font-size\")||12,color:n.fill||i.style(\"fill\")||\"black\",opacity:1,\"background-color\":n.background||\"transparent\",outline:\"#ffffff33 1px solid\",margin:[-parseFloat(i.style(\"font-size\"))/8+1,0,0,-1].join(\"px \")+\"px\",padding:\"0\",\"box-sizing\":\"border-box\"}).attr({contenteditable:!0}).text(n.text||i.attr(\"data-unformatted\")).call(l(i,e,n)).on(\"blur\",function(){i.text(this.textContent).style({opacity:1});var t,e=c.select(this).attr(\"class\");t=e?\".\"+e.split(\" \")[0]+\"-math-group\":\"[class*=-math-group]\",t&&c.select(i.node().parentNode).select(t).style({opacity:0});var n=this.textContent;c.select(this).transition().duration(0).remove(),c.select(document).on(\"mouseup\",null),u.edit.call(i,n)}).on(\"focus\",function(){var t=this;c.select(document).on(\"mouseup\",function(){return c.event.target===t?!1:void(document.activeElement===r.node()&&r.node().blur())})}).on(\"keyup\",function(){27===c.event.which?(i.style({opacity:1}),c.select(this).style({opacity:0}).on(\"blur\",function(){return!1}).transition().remove(),u.cancel.call(i,this.textContent)):(u.input.call(i,this.textContent),c.select(this).call(l(i,e,n)))}).on(\"keydown\",function(){13===c.event.which&&this.blur()}).call(a)}n||(n={});var i=this,u=c.dispatch(\"edit\",\"input\",\"cancel\"),f=c.select(this.node()).style({\"pointer-events\":\"all\"}),d=e||f;return e&&f.style({\"pointer-events\":\"none\"}),n.immediate?r():d.on(\"click\",r),c.rebind(this,u,\"on\")}},{\"../constants/xmlns_namespaces\":82,\"../lib\":89,\"../plotly\":107,d3:9}],101:[function(t,e,n){\"use strict\";function r(t){var e;if(\"string\"==typeof t){if(e=document.getElementById(t),null===e)throw new Error(\"No DOM element with id '\"+t+\"' exists on the page.\");return e}if(null===t||void 0===t)throw new Error(\"DOM element provided is null or undefined\");return t}function a(t,e){t._fullLayout._paperdiv.style(\"background\",\"white\"),O.defaultConfig.setBackground(t,e)}function o(t,e){t._context||(t._context=P.extendFlat({},O.defaultConfig));var n=t._context;e&&(Object.keys(e).forEach(function(t){t in n&&(\"setBackground\"===t&&\"opaque\"===e[t]?n[t]=a:n[t]=e[t])}),e.plot3dPixelRatio&&!n.plotGlPixelRatio&&(n.plotGlPixelRatio=n.plot3dPixelRatio)),n.staticPlot&&(n.editable=!1,n.autosizable=!1,n.scrollZoom=!1,n.doubleClick=!1,n.showTips=!1,n.showLink=!1,n.displayModeBar=!1)}function i(t,e,n){var r=S.select(t).selectAll(\".plot-container\").data([0]);r.enter().insert(\"div\",\":first-child\").classed(\"plot-container plotly\",!0);var a=r.selectAll(\".svg-container\").data([0]);a.enter().append(\"div\").classed(\"svg-container\",!0).style(\"position\",\"relative\"),a.html(\"\"),e&&(t.data=e),n&&(t.layout=n),O.micropolar.manager.fillLayout(t),\"initial\"===t._fullLayout.autosize&&t._context.autosizable&&(w(t,{}),t._fullLayout.autosize=n.autosize=!0),a.style({width:t._fullLayout.width+\"px\",height:t._fullLayout.height+\"px\"}),t.framework=O.micropolar.manager.framework(t),t.framework({data:t.data,layout:" -, -"t.layout},a.node()),t.framework.setUndoPoint();var o=t.framework.svg(),i=1,l=t._fullLayout.title;\"\"!==l&&l||(i=0);var s=\"Click to enter title\",c=function(){this.call(O.util.convertToTspans)},u=o.select(\".title-group text\").call(c);if(t._context.editable){u.attr({\"data-unformatted\":l}),l&&l!==s||(i=.2,u.attr({\"data-unformatted\":s}).text(s).style({opacity:i}).on(\"mouseover.opacity\",function(){S.select(this).transition().duration(100).style(\"opacity\",1)}).on(\"mouseout.opacity\",function(){S.select(this).transition().duration(1e3).style(\"opacity\",0)}));var f=function(){this.call(O.util.makeEditable).on(\"edit\",function(e){t.framework({layout:{title:e}}),this.attr({\"data-unformatted\":e}).text(e).call(c),this.call(f)}).on(\"cancel\",function(){var t=this.attr(\"data-unformatted\");this.text(t).call(c)})};u.call(f)}return t._context.setBackground(t,t._fullLayout.paper_bgcolor),I.addLinks(t),Promise.resolve()}function l(t){var e,n;t||(t={}),t.xaxis1&&(t.xaxis||(t.xaxis=t.xaxis1),delete t.xaxis1),t.yaxis1&&(t.yaxis||(t.yaxis=t.yaxis1),delete t.yaxis1);var r=O.Axes.list({_fullLayout:t});for(e=0;e<r.length;e++){var a=r[e];a.anchor&&\"free\"!==a.anchor&&(a.anchor=O.Axes.cleanId(a.anchor)),a.overlaying&&(a.overlaying=O.Axes.cleanId(a.overlaying)),a.type||(a.isdate?a.type=\"date\":a.islog?a.type=\"log\":a.isdate===!1&&a.islog===!1&&(a.type=\"linear\")),\"withzero\"!==a.autorange&&\"tozero\"!==a.autorange||(a.autorange=!0,a.rangemode=\"tozero\"),delete a.islog,delete a.isdate,delete a.categories,f(a,\"domain\")&&delete a.domain,void 0!==a.autotick&&(void 0===a.tickmode&&(a.tickmode=a.autotick?\"auto\":\"linear\"),delete a.autotick)}void 0===t.annotations||Array.isArray(t.annotations)||(P.warn(\"Annotations must be an array.\"),delete t.annotations);var o=(t.annotations||[]).length;for(e=0;o>e;e++){var i=t.annotations[e];i.ref&&(\"paper\"===i.ref?(i.xref=\"paper\",i.yref=\"paper\"):\"data\"===i.ref&&(i.xref=\"x\",i.yref=\"y\"),delete i.ref),s(i,\"xref\"),s(i,\"yref\")}void 0===t.shapes||Array.isArray(t.shapes)||(P.warn(\"Shapes must be an array.\"),delete t.shapes);var l=(t.shapes||[]).length;for(e=0;l>e;e++){var c=t.shapes[e];s(c,\"xref\"),s(c,\"yref\")}var u=t.legend;u&&(u.x>3?(u.x=1.02,u.xanchor=\"left\"):u.x<-2&&(u.x=-.02,u.xanchor=\"right\"),u.y>3?(u.y=1.02,u.yanchor=\"bottom\"):u.y<-2&&(u.y=-.02,u.yanchor=\"top\")),\"rotate\"===t.dragmode&&(t.dragmode=\"orbit\"),t.scene1&&(t.scene||(t.scene=t.scene1),delete t.scene1);var d=I.getSubplotIds(t,\"gl3d\");for(e=0;e<d.length;e++){var h=t[d[e]],p=h.cameraposition;if(Array.isArray(p)&&4===p[0].length){var g=p[0],v=p[1],m=p[2],y=E([],g),x=[];for(n=0;3>n;++n)x[n]=v[e]+m*y[2+4*n];h.camera={eye:{x:x[0],y:x[1],z:x[2]},center:{x:v[0],y:v[1],z:v[2]},up:{x:y[1],y:y[5],z:y[9]}},delete h.cameraposition}}return j.clean(t),t}function s(t,e){var n=t[e],r=e.charAt(0);n&&\"paper\"!==n&&(t[e]=O.Axes.cleanId(n,r))}function c(t,e){for(var n=[],r=(t.concat(Array.isArray(e)?e:[]).filter(function(t){return\"uid\"in t}).map(function(t){return t.uid})),a=0;a<t.length;a++){var o,i=t[a];if(!(\"uid\"in i)||-1!==n.indexOf(i.uid)){var l;for(o=0;100>o&&(l=P.randstr(r),-1!==n.indexOf(l));o++);i.uid=P.randstr(r),r.push(i.uid)}if(n.push(i.uid),\"histogramy\"===i.type&&\"xbins\"in i&&!(\"ybins\"in i)&&(i.ybins=i.xbins,delete i.xbins),i.error_y&&\"opacity\"in i.error_y){var s=j.defaults,c=i.error_y.color||(I.traceIs(i,\"bar\")?j.defaultLine:s[a%s.length]);i.error_y.color=j.addOpacity(j.rgb(c),j.opacity(c)*i.error_y.opacity),delete i.error_y.opacity}if(\"bardir\"in i&&(\"h\"!==i.bardir||!I.traceIs(i,\"bar\")&&\"histogram\"!==i.type.substr(0,9)||(i.orientation=\"h\",b(i)),delete i.bardir),\"histogramy\"===i.type&&b(i),\"histogramx\"!==i.type&&\"histogramy\"!==i.type||(i.type=\"histogram\"),\"scl\"in i&&(i.colorscale=i.scl,delete i.scl),\"reversescl\"in i&&(i.reversescale=i.reversescl,delete i.reversescl),i.xaxis&&(i.xaxis=O.Axes.cleanId(i.xaxis,\"x\")),i.yaxis&&(i.yaxis=O.Axes.cleanId(i.yaxis,\"y\")),I.traceIs(i,\"gl3d\")&&i.scene&&(i.scene=I.subplotsRegistry.gl3d.cleanId(i.scene)),I.traceIs(i,\"pie\")||(Array.isArray(i.textposition)?i.textposition=i.textposition.map(u):i.textposition&&(i.textposition=u(i.textposition))),I.traceIs(i,\"2dMap\")&&(\"YIGnBu\"===i.colorscale&&(i.colorscale=\"YlGnBu\"),\"YIOrRd\"===i.colorscale&&(i.colorscale=\"YlOrRd\")),I.traceIs(i,\"markerColorscale\")&&i.marker){var d=i.marker;\"YIGnBu\"===d.colorscale&&(d.colorscale=\"YlGnBu\"),\"YIOrRd\"===d.colorscale&&(d.colorscale=\"YlOrRd\")}if(\"surface\"===i.type&&P.isPlainObject(i.contours)){var h=[\"x\",\"y\",\"z\"];for(o=0;o<h.length;o++){var p=i.contours[h[o]];P.isPlainObject(p)&&(p.highlightColor&&(p.highlightcolor=p.highlightColor,delete p.highlightColor),p.highlightWidth&&(p.highlightwidth=p.highlightWidth,delete p.highlightWidth))}}f(i,\"line\")&&delete i.line,\"marker\"in i&&(f(i.marker,\"line\")&&delete i.marker.line,f(i,\"marker\")&&delete i.marker),j.clean(i)}}function u(t){var e=\"middle\",n=\"center\";return-1!==t.indexOf(\"top\")?e=\"top\":-1!==t.indexOf(\"bottom\")&&(e=\"bottom\"),-1!==t.indexOf(\"left\")?n=\"left\":-1!==t.indexOf(\"right\")&&(n=\"right\"),e+\" \"+n}function f(t,e){return e in t&&\"object\"==typeof t[e]&&0===Object.keys(t[e]).length}function d(t){var e,n=O.Axes.list(t),r=t._fullData,a=t._fullLayout,o=t.calcdata=new Array(r.length);for(t.firstscatter=!0,t.numboxes=0,t._hmpixcount=0,t._hmlumcount=0,a._piecolormap={},a._piedefaultcolorcount=0,e=0;e<n.length;e++)n[e]._categories=n[e]._initialCategories.slice();for(e=0;e<r.length;e++){var i=r[e],l=i._module,s=[];l&&i.visible===!0&&l.calc&&(s=l.calc(t,i)),Array.isArray(s)&&s[0]||(s=[{x:!1,y:!1}]),s[0].t||(s[0].t={}),s[0].trace=i,o[e]=s}}function h(t,e){var n,r,a=e+1,o=[];for(n=0;n<t.length;n++)r=t[n],0>r?o.push(a+r):o.push(r);return o}function p(t,e,n){var r,a;for(r=0;r<e.length;r++){if(a=e[r],a!==parseInt(a,10))throw new Error(\"all values in \"+n+\" must be integers\");if(a>=t.data.length||a<-t.data.length)throw new Error(n+\" must be valid indices for gd.data.\");if(e.indexOf(a,r+1)>-1||a>=0&&e.indexOf(-t.data.length+a)>-1||0>a&&e.indexOf(t.data.length+a)>-1)throw new Error(\"each index in \"+n+\" must be unique.\")}}function g(t,e,n){if(!Array.isArray(t.data))throw new Error(\"gd.data must be an array.\");if(\"undefined\"==typeof e)throw new Error(\"currentIndices is a required argument.\");if(Array.isArray(e)||(e=[e]),p(t,e,\"currentIndices\"),\"undefined\"==typeof n||Array.isArray(n)||(n=[n]),\"undefined\"!=typeof n&&p(t,n,\"newIndices\"),\"undefined\"!=typeof n&&e.length!==n.length)throw new Error(\"current and new indices must be of equal length.\")}function v(t,e,n){var r,a;if(!Array.isArray(t.data))throw new Error(\"gd.data must be an array.\");if(\"undefined\"==typeof e)throw new Error(\"traces must be defined.\");for(Array.isArray(e)||(e=[e]),r=0;r<e.length;r++)if(a=e[r],\"object\"!=typeof a||Array.isArray(a)||null===a)throw new Error(\"all values in traces array must be non-array objects\");if(\"undefined\"==typeof n||Array.isArray(n)||(n=[n]),\"undefined\"!=typeof n&&n.length!==e.length)throw new Error(\"if indices is specified, traces.length must equal indices.length\")}function m(t,e,n,r){var a=P.isPlainObject(r);if(!Array.isArray(t.data))throw new Error(\"gd.data must be an array\");if(!P.isPlainObject(e))throw new Error(\"update must be a key:value object\");if(\"undefined\"==typeof n)throw new Error(\"indices must be an integer or array of integers\");p(t,n,\"indices\");for(var o in e){if(!Array.isArray(e[o])||e[o].length!==n.length)throw new Error(\"attribute \"+o+\" must be an array of length equal to indices array length\");if(a&&(!(o in r)||!Array.isArray(r[o])||r[o].length!==e[o].length))throw new Error(\"when maxPoints is set as a key:value object it must contain a 1:1 corrispondence with the keys and number of traces in the update object\")}}function y(t,e,n,r){var a,o,i,l,s,c=P.isPlainObject(r),u=[];Array.isArray(n)||(n=[n]),n=h(n,t.data.length-1);for(var f in e)for(var d=0;d<n.length;d++){if(a=t.data[n[d]],i=P.nestedProperty(a,f),o=i.get(),l=e[f][d],!Array.isArray(l))throw new Error(\"attribute: \"+f+\" index: \"+d+\" must be an array\");if(!Array.isArray(o))throw new Error(\"cannot extend missing or non-array attribute: \"+f);s=c?r[f][d]:r,C(s)||(s=-1),u.push({prop:i,target:o,insert:l,maxp:Math.floor(s)})}return u}function x(t,e,n,r,a,o){m(t,e,n,r);for(var i,l,s,c=y(t,e,n,r),u=[],f={},d={},h=0;h<c.length;h++)l=c[h].prop,s=c[h].maxp,i=a(c[h].target,c[h].insert),s>=0&&s<i.length&&(u=o(i,s)),s=c[h].target.length,l.set(i),Array.isArray(f[l.astr])||(f[l.astr]=[]),Array.isArray(d[l.astr])||(d[l.astr]=[]),f[l.astr].push(u),d[l.astr].push(s);return{update:f,maxPoints:d}}function b(t){var e;if(P.swapAttrs(t,[\"?\",\"?0\",\"d?\",\"?bins\",\"nbins?\",\"autobin?\",\"?src\",\"error_?\"]),Array.isArray(t.z)&&Array.isArray(t.z[0])&&(t.transpose?delete t.transpose:t.transpose=!0),t.error_x&&t.error_y){var n=t.error_y,r=\"copy_ystyle\"in n?n.copy_ystyle:!(n.color||n.thickness||n.width);P.swapAttrs(t,[\"error_?.copy_ystyle\"]),r&&P.swapAttrs(t,[\"error_?.color\",\"error_?.thickness\",\"error_?.width\"])}if(t.hoverinfo){var a=t.hoverinfo.split(\"+\");for(e=0;e<a.length;e++)\"x\"===a[e]?a[e]=\"y\":\"y\"===a[e]&&(a[e]=\"x\");t.hoverinfo=a.join(\"+\")}}function _(t){var e,n={left:0,right:0,bottom:0,top:0};if(t)for(e in t)t.hasOwnProperty(e)&&(n.left+=t[e].left||0,n.right+=t[e].right||0,n.bottom+=t[e].bottom||0,n.top+=t[e].top||0);return n}function w(t,e){var n,r,a,o=t._fullLayout,i=t._context;if(t.emit(\"plotly_autosize\"),t._context.fillFrame)a=window.innerWidth,r=window.innerHeight,document.body.style.overflow=\"hidden\";else if(C(i.frameMargins)&&i.frameMargins>0){var l=_(t._boundingBoxMargins),s=l.left+l.right,c=l.bottom+l.top,u=o._container.node().getBoundingClientRect(),f=1-2*i.frameMargins;a=Math.round(f*(u.width-s)),r=Math.round(f*(u.height-c))}else n=window.getComputedStyle(t),r=parseFloat(n.height)||o.height,a=parseFloat(n.width)||o.width;return Math.abs(o.width-a)>1||Math.abs(o.height-r)>1?(o.height=t.layout.height=r,o.width=t.layout.width=a):\"initial\"!==o.autosize&&(delete e.autosize,o.autosize=t.layout.autosize=!0),I.sanitizeMargins(o),e}function k(t){var e=S.select(t),n=t._fullLayout;if(n._container=e.selectAll(\".pl" -, -"ot-container\").data([0]),n._container.enter().insert(\"div\",\":first-child\").classed(\"plot-container\",!0).classed(\"plotly\",!0),n._paperdiv=n._container.selectAll(\".svg-container\").data([0]),n._paperdiv.enter().append(\"div\").classed(\"svg-container\",!0).style(\"position\",\"relative\"),\"initial\"===n.autosize&&(w(t,{}),n.autosize=!0,t.layout.autosize=!0),n._glcontainer=n._paperdiv.selectAll(\".gl-container\").data([0]),n._glcontainer.enter().append(\"div\").classed(\"gl-container\",!0),n._geocontainer=n._paperdiv.selectAll(\".geo-container\").data([0]),n._geocontainer.enter().append(\"div\").classed(\"geo-container\",!0),n._paperdiv.selectAll(\".main-svg\").remove(),n._paper=n._paperdiv.insert(\"svg\",\":first-child\").classed(\"main-svg\",!0),n._toppaper=n._paperdiv.append(\"svg\").classed(\"main-svg\",!0),!n._uid){var r=[];S.selectAll(\"defs\").each(function(){this.id&&r.push(this.id.split(\"-\")[1])}),n._uid=P.randstr(r)}n._paperdiv.selectAll(\".main-svg\").attr(G.svgAttrs),n._defs=n._paper.append(\"defs\").attr(\"id\",\"defs-\"+n._uid),n._topdefs=n._toppaper.append(\"defs\").attr(\"id\",\"topdefs-\"+n._uid),n._draggers=n._paper.append(\"g\").classed(\"draglayer\",!0);var a=n._paper.append(\"g\").classed(\"layer-below\",!0);n._imageLowerLayer=a.append(\"g\").classed(\"imagelayer\",!0),n._shapeLowerLayer=a.append(\"g\").classed(\"shapelayer\",!0);var o=O.Axes.getSubplots(t);o.join(\"\")!==Object.keys(t._fullLayout._plots||{}).join(\"\")&&M(t,o),n._has(\"cartesian\")&&A(t,o),n._ternarylayer=n._paper.append(\"g\").classed(\"ternarylayer\",!0);var i=n._paper.selectAll(\".layer-subplot\");n._imageSubplotLayer=i.selectAll(\".imagelayer\"),n._shapeSubplotLayer=i.selectAll(\".shapelayer\");var l=n._paper.append(\"g\").classed(\"layer-above\",!0);n._imageUpperLayer=l.append(\"g\").classed(\"imagelayer\",!0),n._shapeUpperLayer=l.append(\"g\").classed(\"shapelayer\",!0),n._pielayer=n._paper.append(\"g\").classed(\"pielayer\",!0),n._glimages=n._paper.append(\"g\").classed(\"glimages\",!0),n._geoimages=n._paper.append(\"g\").classed(\"geoimages\",!0),n._infolayer=n._toppaper.append(\"g\").classed(\"infolayer\",!0),\n" -, -"n._zoomlayer=n._toppaper.append(\"g\").classed(\"zoomlayer\",!0),n._hoverlayer=n._toppaper.append(\"g\").classed(\"hoverlayer\",!0),t.emit(\"plotly_framework\");var s=P.syncOrAsync([L,function(){return O.Axes.doTicks(t,\"redraw\")},R.init],t);return s&&s.then&&t._promises.push(s),s}function M(t,e){function n(e,n){return function(){return O.Axes.getFromId(t,e,n)}}for(var r,a,o=t._fullLayout._plots={},i=0;i<e.length;i++)r=e[i],a=o[r]={},a.id=r,a.x=n(r,\"x\"),a.y=n(r,\"y\"),a.xaxis=a.x(),a.yaxis=a.y()}function A(t,e){function n(t){t.append(\"g\").classed(\"imagelayer\",!0),t.append(\"g\").classed(\"maplayer\",!0),t.append(\"g\").classed(\"barlayer\",!0),t.append(\"g\").classed(\"boxlayer\",!0),t.append(\"g\").classed(\"scatterlayer\",!0)}var r=t._fullLayout,a=[];r._paper.selectAll(\"g.subplot\").data(e).enter().append(\"g\").classed(\"subplot\",!0).each(function(o){var i=r._plots[o],l=i.plotgroup=S.select(this).classed(o,!0),s=i.xaxis,c=i.yaxis;i.overlays=[];var u=O.Axes.getFromId(t,s.overlaying)||s;u!==s&&u.overlaying&&(u=s,s.overlaying=!1);var f=O.Axes.getFromId(t,c.overlaying)||c;f!==c&&f.overlaying&&(f=c,c.overlaying=!1);var d=u._id+f._id;if(d!==o&&-1!==e.indexOf(d))i.mainplot=d,a.push(i),s.domain=u.domain.slice(),c.domain=f.domain.slice();else{i.bg=l.append(\"rect\").style(\"stroke-width\",0);var h=l.append(\"g\").classed(\"layer-subplot\",!0);i.shapelayer=h.append(\"g\").classed(\"shapelayer\",!0),i.imagelayer=h.append(\"g\").classed(\"imagelayer\",!0),i.gridlayer=l.append(\"g\"),i.overgrid=l.append(\"g\"),i.zerolinelayer=l.append(\"g\"),i.overzero=l.append(\"g\"),i.plot=l.append(\"g\").call(n),i.overplot=l.append(\"g\"),i.xlines=l.append(\"path\"),i.ylines=l.append(\"path\"),i.overlines=l.append(\"g\"),i.xaxislayer=l.append(\"g\"),i.yaxislayer=l.append(\"g\"),i.overaxes=l.append(\"g\")}i.draglayer=r._draggers.append(\"g\")}),a.forEach(function(t){var e=r._plots[t.mainplot];e.overlays.push(t),t.gridlayer=e.overgrid.append(\"g\"),t.zerolinelayer=e.overzero.append(\"g\"),t.plot=e.overplot.append(\"g\").call(n),t.xlines=e.overlines.append(\"path\"),t.ylines=e.overlines.append(\"path\"),t.xaxislayer=e.overaxes.append(\"g\"),t.yaxislayer=e.overaxes.append(\"g\")}),e.forEach(function(t){var e=r._plots[t];e.xlines.style(\"fill\",\"none\").classed(\"crisp\",!0),e.ylines.style(\"fill\",\"none\").classed(\"crisp\",!0)})}function L(t){return P.syncOrAsync([I.doAutoMargin,T],t)}function T(t){var e,n=t._fullLayout,r=n._size,a=O.Axes.list(t);for(e=0;e<a.length;e++)a[e]._linepositions={};n._paperdiv.style({width:n.width+\"px\",height:n.height+\"px\"}).selectAll(\".main-svg\").call(q.setSize,n.width,n.height),t._context.setBackground(t,n.paper_bgcolor);var o=[];return n._paper.selectAll(\"g.subplot\").each(function(e){var a=n._plots[e],i=O.Axes.getFromId(t,e,\"x\"),l=O.Axes.getFromId(t,e,\"y\");i.setScale(),l.setScale(),a.bg&&a.bg.call(q.setRect,i._offset-r.p,l._offset-r.p,i._length+2*r.p,l._length+2*r.p).call(j.fill,n.plot_bgcolor),a.clipId=\"clip\"+n._uid+e+\"plot\";var s=n._defs.selectAll(\"g.clips\").selectAll(\"#\"+a.clipId).data([0]);s.enter().append(\"clipPath\").attr({\"class\":\"plotclip\",id:a.clipId}).append(\"rect\"),s.selectAll(\"rect\").attr({width:i._length,height:l._length}),a.plot.call(P.setTranslate,i._offset,l._offset),a.plot.call(q.setClipUrl,a.clipId);var c=q.crispRound(t,i.linewidth,1),u=q.crispRound(t,l.linewidth,1),f=r.p+u,d=\"M\"+-f+\",\",h=\"h\"+(i._length+2*f),p=\"free\"===i.anchor&&-1===o.indexOf(i._id),g=r.h*(1-(i.position||0))+c/2%1,v=i.anchor===l._id&&(i.mirror||\"top\"!==i.side)||\"all\"===i.mirror||\"allticks\"===i.mirror||i.mirrors&&i.mirrors[l._id+\"bottom\"],m=l._length+r.p+c/2,y=i.anchor===l._id&&(i.mirror||\"top\"===i.side)||\"all\"===i.mirror||\"allticks\"===i.mirror||i.mirrors&&i.mirrors[l._id+\"top\"],x=-r.p-c/2,b=r.p,_=v?0:c,w=y?0:c,k=\",\"+(-b-w)+\"v\"+(l._length+2*b+w+_),M=\"free\"===l.anchor&&-1===o.indexOf(l._id),A=r.w*(l.position||0)+u/2%1,L=l.anchor===i._id&&(l.mirror||\"right\"!==l.side)||\"all\"===l.mirror||\"allticks\"===l.mirror||l.mirrors&&l.mirrors[i._id+\"left\"],T=-r.p-u/2,z=l.anchor===i._id&&(l.mirror||\"right\"===l.side)||\"all\"===l.mirror||\"allticks\"===l.mirror||l.mirrors&&l.mirrors[i._id+\"right\"],S=i._length+r.p+u/2;i._linepositions[e]=[v?m:void 0,y?x:void 0,p?g:void 0],i.anchor===l._id?i._linepositions[e][3]=\"top\"===i.side?x:m:p&&(i._linepositions[e][3]=g),l._linepositions[e]=[L?T:void 0,z?S:void 0,M?A:void 0],l.anchor===i._id?l._linepositions[e][3]=\"right\"===l.side?S:T:M&&(l._linepositions[e][3]=A);var E=\"translate(\"+i._offset+\",\"+l._offset+\")\",C=E,N=E;p&&(C=\"translate(\"+i._offset+\",\"+r.t+\")\",x+=l._offset-r.t,m+=l._offset-r.t),M&&(N=\"translate(\"+r.l+\",\"+l._offset+\")\",T+=i._offset-r.l,S+=i._offset-r.l),a.xlines.attr(\"transform\",C).attr(\"d\",(v?d+m+h:\"\")+(y?d+x+h:\"\")+(p?d+g+h:\"\")||\"M0,0\").style(\"stroke-width\",c+\"px\").call(j.stroke,i.showline?i.linecolor:\"rgba(0,0,0,0)\"),a.ylines.attr(\"transform\",N).attr(\"d\",(L?\"M\"+T+k:\"\")+(z?\"M\"+S+k:\"\")+(M?\"M\"+A+k:\"\")||\"M0,0\").attr(\"stroke-width\",u+\"px\").call(j.stroke,l.showline?l.linecolor:\"rgba(0,0,0,0)\"),a.xaxislayer.attr(\"transform\",C),a.yaxislayer.attr(\"transform\",N),a.gridlayer.attr(\"transform\",E),a.zerolinelayer.attr(\"transform\",E),a.draglayer.attr(\"transform\",E),p&&o.push(i._id),M&&o.push(l._id)}),O.Axes.makeClipPaths(t),z(t),X(t),t._promises.length&&Promise.all(t._promises)}function z(t){var e=t._fullLayout;U.draw(t,\"gtitle\",{propContainer:e,propName:\"title\",dfltName:\"Plot\",attributes:{x:e.width/2,y:e._size.t/2,\"text-anchor\":\"middle\"}})}var S=t(\"d3\"),E=t(\"gl-mat4/fromQuat\"),C=t(\"fast-isnumeric\"),O=t(\"../plotly\"),P=t(\"../lib\"),N=t(\"../lib/events\"),D=t(\"../lib/queue\"),I=t(\"../plots/plots\"),R=t(\"../plots/cartesian/graph_interact\"),j=t(\"../components/color\"),q=t(\"../components/drawing\"),F=t(\"../components/errorbars\"),B=t(\"../components/images\"),H=t(\"../components/legend\"),V=t(\"../components/rangeslider\"),Z=t(\"../components/rangeselector\"),Y=t(\"../components/shapes\"),U=t(\"../components/titles\"),X=t(\"../components/modebar/manage\"),G=t(\"../constants/xmlns_namespaces\");O.plot=function(t,e,n,a){function s(){var e,n,r,a=t.calcdata;for(H.draw(t),Z.draw(t),e=0;e<a.length;e++)n=a[e],r=n[0].trace,r.visible===!0&&r._module.colorbar?r._module.colorbar(t,n):I.autoMargin(t,\"cb\"+r.uid);return I.doAutoMargin(t),I.previousPromises(t)}function u(){var e=JSON.stringify(A._size)===E?[]:[s,L];return P.syncOrAsync(e.concat(R.init),t)}function f(){if(T){for(var e,n,r=I.getSubplotIds(A,\"cartesian\"),a=A._modules,o=0;o<r.length;o++){e=A._plots[r[o]];for(var i=0;i<a.length;i++)n=a[i],n.setPositions&&n.setPositions(t,e)}return F.calc(t),P.syncOrAsync([Y.calcAutorange,O.Annotations.calcAutorange,h],t)}}function h(){for(var e=O.Axes.list(t,\"\",!0),n=0;n<e.length;n++)O.Axes.doAutoRange(e[n])}function p(){return O.Axes.doTicks(t,\"redraw\")}function g(){var e,n=t.calcdata;for(e=0;e<n.length;e++){var r=n[e][0].trace,a=r.visible===!0,o=r.uid;a&&I.traceIs(r,\"2dMap\")||A._paper.selectAll(\".hm\"+o+\",.contour\"+o+\",#clip\"+o).remove(),a&&r._module.colorbar||A._infolayer.selectAll(\".cb\"+o).remove()}var i=A._basePlotModules;for(e=0;e<i.length;e++)i[e].plot(t);return I.style(t),Y.drawAll(t),O.Annotations.drawAll(t),I.addLinks(t),t._replotting=!1,I.previousPromises(t)}function v(){Y.drawAll(t),B.draw(t),O.Annotations.drawAll(t),H.draw(t),V.draw(t),Z.draw(t)}function m(){t.emit(\"plotly_afterplot\")}t=r(t),N.init(t);var y=N.triggerHandler(t,\"plotly_beforeplot\",[e,n,a]);if(y===!1)return Promise.reject();e||n||P.isPlotDiv(t)||P.warn(\"Calling Plotly.plot as if redrawing but this container doesn't yet have a plot.\",t),o(t,a),n||(n={}),S.select(t).classed(\"js-plotly-plot\",!0),q.makeTester(t),t._promises=[];var x=0===(t.data||[]).length&&Array.isArray(e);if(Array.isArray(e)&&(c(e,t.data),x?t.data=e:t.data.push.apply(t.data,e),t.empty=!1),t.layout&&!x||(t.layout=l(n)),t._dragging)return t._replotPending=!0,Promise.reject();if(t._replotPending=!1,I.supplyDefaults(t),e&&e[0]&&e[0].r)return i(t,e,n);t._replotting=!0;var b=t._fullData.length>0,_=O.Axes.getSubplots(t).join(\"\"),w=Object.keys(t._fullLayout._plots||{}).join(\"\"),M=w===_;b?t.framework===k&&!x&&M||(t.framework=k,k(t)):M?x&&k(t):(t.framework=k,k(t)),x&&O.Axes.saveRangeInitial(t);var A=t._fullLayout,T=!t.calcdata||t.calcdata.length!==(t.data||[]).length;T&&d(t);for(var z=0;z<t.calcdata.length;z++)t.calcdata[z][0].trace=t._fullData[z];var E=JSON.stringify(A._size);return P.syncOrAsync([I.previousPromises,s,u,f,L,p,g,v],t,m),Promise.all(t._promises).then(function(){return t},function(){P.log(\"Clearing previous rejected promises from queue.\"),t._promises=[]})},O.redraw=function(t){return t=r(t),P.isPlotDiv(t)?(t.calcdata=void 0,O.plot(t).then(function(){return t.emit(\"plotly_redraw\"),t})):void P.warn(\"This element is not a Plotly plot.\",t)},O.newPlot=function(t,e,n,a){return t=r(t),I.cleanPlot([],{},t._fullData||{},t._fullLayout||{}),I.purge(t),O.plot(t,e,n,a)},O.extendTraces=function $(t,e,n,a){t=r(t);var o=x(t,e,n,a,function(t,e){return t.concat(e)},function(t,e){return t.splice(0,t.length-e)}),i=O.redraw(t),l=[t,o.update,n,o.maxPoints];return D.add(t,O.prependTraces,l,$,arguments),i},O.prependTraces=function Q(t,e,n,a){t=r(t);var o=x(t,e,n,a,function(t,e){return e.concat(t)},function(t,e){return t.splice(e,t.length)}),i=O.redraw(t),l=[t,o.update,n,o.maxPoints];return D.add(t,O.extendTraces,l,Q,arguments),i},O.addTraces=function W(t,e,n){t=r(t);var a,o,i=[],l=O.deleteTraces,s=W,u=[t,i],f=[t,e];for(v(t,e,n),Array.isArray(e)||(e=[e]),c(e,t.data),a=0;a<e.length;a+=1)t.data.push(e[a]);for(a=0;a<e.length;a++)i.push(-e.length+a);if(\"undefined\"==typeof n)return o=O.redraw(t),D.add(t,l,u,s,f),o;Array.isArray(n)||(n=[n]);try{g(t,i,n)}catch(d){throw t.data.splice(t.data.length-e.length,e.length),d}return D.startSequence(t),D.add(t,l,u,s,f),o=O.moveTraces(t,i,n),D.stopSequence(t),o},O.deleteTraces=function J(t,e){t=r(t);var n,a,o=[],i=O.addTraces,l=J,s=[t,o,e],c=[t,e];if(\"undefined\"==typeof e)throw new Error(\"indices must be an integer or array of integers.\");for(Array.isArray(e)||(e=[e]),p(t,e,\"indices\"),e=h(e,t.data.length-1),e.sort(P.sorterDes),n=0;n<e.length;n+=1)a=t.data.splice(e[n],1)[0],o.push(a);var u=O.redraw(" -, -"t);return D.add(t,i,s,l,c),u},O.moveTraces=function K(t,e,n){t=r(t);var a,o=[],i=[],l=K,s=K,c=[t,n,e],u=[t,e,n];if(g(t,e,n),e=Array.isArray(e)?e:[e],\"undefined\"==typeof n)for(n=[],a=0;a<e.length;a++)n.push(-e.length+a);for(n=Array.isArray(n)?n:[n],e=h(e,t.data.length-1),n=h(n,t.data.length-1),a=0;a<t.data.length;a++)-1===e.indexOf(a)&&o.push(t.data[a]);for(a=0;a<e.length;a++)i.push({newIndex:n[a],trace:t.data[e[a]]});for(i.sort(function(t,e){return t.newIndex-e.newIndex}),a=0;a<i.length;a+=1)o.splice(i[a].newIndex,0,i[a].trace);t.data=o;var f=O.redraw(t);return D.add(t,l,c,s,u),f},O.restyle=function tt(t,e,n,a){function o(){return a.map(function(){})}function i(t){var e=O.Axes.id2name(t);-1===p.indexOf(e)&&p.push(e)}function l(t){return\"LAYOUT\"+t+\".autorange\"}function s(t){return\"LAYOUT\"+t+\".range\"}function c(e,n,r){if(Array.isArray(e))return void e.forEach(function(t){c(t,n,r)});if(!(e in d)){var i;i=\"LAYOUT\"===e.substr(0,6)?P.nestedProperty(t.layout,e.replace(\"LAYOUT\",\"\")):P.nestedProperty(t.data[a[r]],e),e in L||(L[e]=o()),void 0===L[e][r]&&(L[e][r]=i.get()),void 0!==n&&i.set(n)}}t=r(t);var u,f=t._fullLayout,d={};if(\"string\"==typeof e)d[e]=n;else{if(!P.isPlainObject(e))return P.warn(\"Restyle fail.\",e,n,a),Promise.reject();d=e,void 0===a&&(a=n)}Object.keys(d).length&&(t.changed=!0),C(a)?a=[a]:Array.isArray(a)&&a.length||(a=t.data.map(function(t,e){return e}));var h=[\"mode\",\"visible\",\"type\",\"orientation\",\"fill\",\"histfunc\",\"histnorm\",\"text\",\"x\",\"y\",\"z\",\"a\",\"b\",\"c\",\"xtype\",\"x0\",\"dx\",\"ytype\",\"y0\",\"dy\",\"xaxis\",\"yaxis\",\"line.width\",\"connectgaps\",\"transpose\",\"zsmooth\",\"showscale\",\"marker.showscale\",\"zauto\",\"marker.cauto\",\"autocolorscale\",\"marker.autocolorscale\",\"colorscale\",\"marker.colorscale\",\"reversescale\",\"marker.reversescale\",\"autobinx\",\"nbinsx\",\"xbins\",\"xbins.start\",\"xbins.end\",\"xbins.size\",\"autobiny\",\"nbinsy\",\"ybins\",\"ybins.start\",\"ybins.end\",\"ybins.size\",\"autocontour\",\"ncontours\",\"contours\",\"contours.coloring\",\"error_y\",\"error_y.visible\",\"error_y.value\",\"error_y.type\",\"error_y.traceref\",\"error_y.array\",\"error_y.symmetric\",\"error_y.arrayminus\",\"error_y.valueminus\",\"error_y.tracerefminus\",\"error_x\",\"error_x.visible\",\"error_x.value\",\"error_x.type\",\"error_x.traceref\",\"error_x.array\",\"error_x.symmetric\",\"error_x.arrayminus\",\"error_x.valueminus\",\"error_x.tracerefminus\",\"swapxy\",\"swapxyaxes\",\"orientationaxes\",\"marker.colors\",\"values\",\"labels\",\"label0\",\"dlabel\",\"sort\",\"textinfo\",\"textposition\",\"textfont.size\",\"textfont.family\",\"textfont.color\",\"insidetextfont.size\",\"insidetextfont.family\",\"insidetextfont.color\",\"outsidetextfont.size\",\"outsidetextfont.family\",\"outsidetextfont.color\",\"hole\",\"scalegroup\",\"domain\",\"domain.x\",\"domain.y\",\"domain.x[0]\",\"domain.x[1]\",\"domain.y[0]\",\"domain.y[1]\",\"tilt\",\"tiltaxis\",\"depth\",\"direction\",\"rotation\",\"pull\",\"line.showscale\",\"line.cauto\",\"line.autocolorscale\",\"line.reversescale\",\"marker.line.showscale\",\"marker.line.cauto\",\"marker.line.autocolorscale\",\"marker.line.reversescale\"];for(u=0;u<a.length;u++)if(I.traceIs(t._fullData[a[u]],\"box\")){h.push(\"name\");break}var p,g=[\"marker\",\"marker.size\",\"textfont\",\"boxpoints\",\"jitter\",\"pointpos\",\"whiskerwidth\",\"boxmean\"],v=[\"zmin\",\"zmax\",\"zauto\",\"marker.cmin\",\"marker.cmax\",\"marker.cauto\",\"line.cmin\",\"line.cmax\",\"marker.line.cmin\",\"marker.line.cmax\",\"contours.start\",\"contours.end\",\"contours.size\",\"contours.showlines\",\"line\",\"line.smoothing\",\"line.shape\",\"error_y.width\",\"error_x.width\",\"error_x.copy_ystyle\",\"marker.maxdisplayed\"],m=[\"type\",\"x\",\"y\",\"x0\",\"y0\",\"orientation\",\"xaxis\",\"yaxis\"],y=!1,x=!1,_=!1,w=!1,k=!1,M=!1,A={},L={},T={},z=[\"cartesian\",\"pie\",\"ternary\"];f._basePlotModules.forEach(function(t){-1===z.indexOf(t.name)&&(y=!0)});var S=[\"zmin\",\"zmax\"],E=[\"xbins.start\",\"xbins.end\",\"xbins.size\"],N=[\"ybins.start\",\"ybins.end\",\"ybins.size\"],R=[\"contours.start\",\"contours.end\",\"contours.size\"];for(var j in d){var q,F,B,V,Z,Y=d[j];if(A[j]=Y,\"LAYOUT\"!==j.substr(0,6)){for(\"transforms\"===j.substr(0,10)&&(y=!0),L[j]=o(),u=0;u<a.length;u++){if(q=t.data[a[u]],F=t._fullData[a[u]],B=P.nestedProperty(q,j),V=B.get(),Z=Array.isArray(Y)?Y[u%Y.length]:Y,-1!==S.indexOf(j))c(\"zauto\",!1,u);else if(\"colorscale\"===j)c(\"autocolorscale\",!1,u);else if(\"autocolorscale\"===j)c(\"colorscale\",void 0,u);else if(\"marker.colorscale\"===j)c(\"marker.autocolorscale\",!1,u);else if(\"marker.autocolorscale\"===j)c(\"marker.colorscale\",void 0,u);else if(\"zauto\"===j)c(S,void 0,u);else if(-1!==E.indexOf(j))c(\"autobinx\",!1,u);else if(\"autobinx\"===j)c(E,void 0,u);else if(-1!==N.indexOf(j))c(\"autobiny\",!1,u);else if(\"autobiny\"===j)c(N,void 0,u);else if(-1!==R.indexOf(j))c(\"autocontour\",!1,u);else if(\"autocontour\"===j)c(R,void 0,u);else if(-1!==[\"x0\",\"dx\"].indexOf(j)&&F.x&&\"scaled\"!==F.xtype)c(\"xtype\",\"scaled\",u);else if(-1!==[\"y0\",\"dy\"].indexOf(j)&&F.y&&\"scaled\"!==F.ytype)c(\"ytype\",\"scaled\",u);else if(\"colorbar.thicknessmode\"===j&&B.get()!==Z&&-1!==[\"fraction\",\"pixels\"].indexOf(Z)&&F.colorbar){var U=-1!==[\"top\",\"bottom\"].indexOf(F.colorbar.orient)?f.height-f.margin.t-f.margin.b:f.width-f.margin.l-f.margin.r;c(\"colorbar.thickness\",F.colorbar.thickness*(\"fraction\"===Z?1/U:U),u)}else if(\"colorbar.lenmode\"===j&&B.get()!==Z&&-1!==[\"fraction\",\"pixels\"].indexOf(Z)&&F.colorbar){var X=-1!==[\"top\",\"bottom\"].indexOf(F.colorbar.orient)?f.width-f.margin.l-f.margin.r:f.height-f.margin.t-f.margin.b;c(\"colorbar.len\",F.colorbar.len*(\"fraction\"===Z?1/X:X),u)}else\"colorbar.tick0\"===j||\"colorbar.dtick\"===j?c(\"colorbar.tickmode\",\"linear\",u):\"colorbar.tickmode\"===j&&c([\"colorbar.tick0\",\"colorbar.dtick\"],void 0,u);if(\"type\"===j&&\"pie\"===Z!=(\"pie\"===V)){var G=\"x\",$=\"y\";\"bar\"!==Z&&\"bar\"!==V||\"h\"!==q.orientation||(G=\"y\",$=\"x\"),P.swapAttrs(q,[\"?\",\"?src\"],\"labels\",G),P.swapAttrs(q,[\"d?\",\"?0\"],\"label\",G),P.swapAttrs(q,[\"?\",\"?src\"],\"values\",$),\"pie\"===V?(P.nestedProperty(q,\"marker.color\").set(P.nestedProperty(q,\"marker.colors\").get()),f._pielayer.selectAll(\"g.trace\").remove()):I.traceIs(q,\"cartesian\")&&(P.nestedProperty(q,\"marker.colors\").set(P.nestedProperty(q,\"marker.color\").get()),T[q.xaxis||\"x\"]=!0,T[q.yaxis||\"y\"]=!0)}L[j][u]=V;var Q=[\"swapxy\",\"swapxyaxes\",\"orientation\",\"orientationaxes\"];if(-1!==Q.indexOf(j)){if(\"orientation\"===j){if(B.set(Z),B.get()===L[j][u])continue}else\"orientationaxes\"===j&&(q.orientation={v:\"h\",h:\"v\"}[F.orientation]);b(q)}else B.set(Z)}if(-1!==[\"swapxyaxes\",\"orientationaxes\"].indexOf(j)&&O.Axes.swap(t,a),\"orientationaxes\"===j){var W=P.nestedProperty(t.layout,\"hovermode\");\"x\"===W.get()?W.set(\"y\"):\"y\"===W.get()&&W.set(\"x\")}if(-1!==a.indexOf(0)&&-1!==m.indexOf(j)&&(O.Axes.clearTypes(t,a),y=!0),-1!==[\"autobinx\",\"autobiny\",\"zauto\"].indexOf(j)&&Z===!1||(k=!0),(-1!==[\"colorbar\",\"line\"].indexOf(B.parts[0])||\"marker\"===B.parts[0]&&\"colorbar\"===B.parts[1])&&(M=!0),-1!==h.indexOf(j)){if(-1!==[\"orientation\",\"type\"].indexOf(j)){for(p=[],u=0;u<a.length;u++){var J=t.data[a[u]];I.traceIs(J,\"cartesian\")&&(i(J.xaxis||\"x\"),i(J.yaxis||\"y\"),\"type\"===e&&c([\"autobinx\",\"autobiny\"],!0,u))}c(p.map(l),!0,0),c(p.map(s),[0,1],0)}y=!0}else-1!==v.indexOf(j)?_=!0:-1!==g.indexOf(j)&&(x=!0)}else B=P.nestedProperty(t.layout,j.replace(\"LAYOUT\",\"\")),L[j]=[B.get()],B.set(Array.isArray(Y)?Y[0]:Y),y=!0}var K=Object.keys(T);t:for(u=0;u<K.length;u++){for(var et=K[u],nt=et.charAt(0),rt=nt+\"axis\",at=0;at<t.data.length;at++)if(I.traceIs(t.data[at],\"cartesian\")&&(t.data[at][rt]||nt)===et)continue t;c(\"LAYOUT\"+O.Axes.id2name(et),null,0)}D.add(t,tt,[t,L,a],tt,[t,A,a]);var ot=!1;O.Axes.list(t).forEach(function(t){t.autorange&&(ot=!0)}),(y||w||x&&ot)&&(t.calcdata=void 0);var it;w?it=[function(){var e=t.layout;return t.layout=void 0,O.plot(t,\"\",e)}]:y||_||x?it=[O.plot]:(I.supplyDefaults(t),it=[I.previousPromises],k&&it.push(function(){var e,n,r;for(e=0;e<t.calcdata.length;e++)n=t.calcdata[e],r=(((n[0]||{}).trace||{})._module||{}).arraysToCalcdata,r&&r(n);return I.style(t),H.draw(t),I.previousPromises(t)}),M&&it.push(function(){return t.calcdata.forEach(function(t){if((t[0].t||{}).cb){var e=t[0].trace,n=t[0].t.cb;I.traceIs(e,\"contour\")&&n.line({width:e.contours.showlines!==!1?e.line.width:0,dash:e.line.dash,color:\"line\"===e.contours.coloring?n._opts.line.color:e.line.color}),I.traceIs(e,\"markerColorscale\")?n.options(e.marker.colorbar)():n.options(e.colorbar)()}}),I.previousPromises(t)}));var lt=P.syncOrAsync(it,t);return lt&<.then||(lt=Promise.resolve()),lt.then(function(){return t.emit(\"plotly_restyle\",P.extendDeep([],[A,a])),t})},O.relayout=function et(t,e,n){function a(t,e){if(Array.isArray(t))return void t.forEach(function(t){a(t,e)});if(!(t in v)){var n=P.nestedProperty(p,t);t in T||(T[t]=n.get()),void 0!==e&&n.set(e)}}function o(t,e){var n=O.Axes.id2name(t[e+\"ref\"]||e);return(g[n]||{}).autorange}function i(t){var e=t[\"xaxis.range\"]?t[\"xaxis.range\"][0]:t[\"xaxis.range[0]\"],n=t[\"xaxis.range\"]?t[\"xaxis.range\"][1]:t[\"xaxis.range[1]\"],r=g.xaxis&&g.xaxis.rangeslider?g.xaxis.rangeslider:{};r.visible&&(e||n?g.xaxis.rangeslider.setRange(e,n):t[\"xaxis.autorange\"]&&g.xaxis.rangeslider.setRange())}if(t=r(t),t.framework&&t.framework.isPolar)return Promise.resolve(t);var l,s,c,u,f,d,h,p=t.layout,g=t._fullLayout,v={},m=!1,y=!1,x=!1,b=!1,_=!1,k=!1;if(\"string\"==typeof e)v[e]=n;else{if(!P.isPlainObject(e))return P.warn(\"Relayout fail.\",e,n),Promise.reject();v=e}for(Object.keys(v).length&&(t.changed=!0),c=Object.keys(v),s=O.Axes.list(t),h=0;h<c.length;h++){if(0===c[h].indexOf(\"allaxes\")){for(var M=0;M<s.length;M++)f=s[M]._id.substr(1),d=-1!==f.indexOf(\"scene\")?f+\".\":\"\",l=c[h].replace(\"allaxes\",d+s[M]._name),v[l]||(v[l]=v[c[h]]);delete v[c[h]]}c[h].match(/^annotations\\[[0-9-]+\\].ref$/)&&(u=v[c[h]].split(\"y\"),v[c[h].replace(\"ref\",\"xref\")]=u[0],v[c[h].replace(\"ref\",\"yref\")]=2===u.length?\"y\"+u[1]:\"paper\",delete v[c[h]])}var A={},T={},S=[\"height\",\"width\"];for(var E in v){var C=P.nestedProperty(p,E),N=v[E],R=C.parts.length,j=\"string\"==typeof C.parts[R-1]?R-1:R-2,q=C.parts[j],F=C.parts[j-1]+\".\"+q,V=C.parts.slice(0,j).join(\".\"),Z=P.nestedProperty(t.layout,V).get(),Y=P.nestedProperty(g,V).get();if(A[E]=N,T[E]=\"reverse\"===q?N:C.get(),-1!==S.indexOf(E)?a(\"autosize\",!1):\"" -, -"autosize\"===E?a(S,void 0):F.match(/^[xyz]axis[0-9]*\\.range(\\[[0|1]\\])?$/)?a(V+\".autorange\",!1):F.match(/^[xyz]axis[0-9]*\\.autorange$/)?a([V+\".range[0]\",V+\".range[1]\"],void 0):F.match(/^aspectratio\\.[xyz]$/)?a(C.parts[0]+\".aspectmode\",\"manual\"):F.match(/^aspectmode$/)?a([V+\".x\",V+\".y\",V+\".z\"],void 0):\"tick0\"===q||\"dtick\"===q?a(V+\".tickmode\",\"linear\"):\"tickmode\"===q?a([V+\".tick0\",V+\".dtick\"],void 0):/[xy]axis[0-9]*?$/.test(q)&&!Object.keys(N||{}).length?_=!0:/[xy]axis[0-9]*\\.categoryorder$/.test(F)?_=!0:/[xy]axis[0-9]*\\.categoryarray/.test(F)&&(_=!0),-1!==F.indexOf(\"rangeslider\")&&(_=!0),\"type\"===q&&\"log\"===Y.type!=(\"log\"===N)){var U=Z;if(U&&U.range)if(Y.autorange)\"log\"===N&&(U.range=U.range[1]>U.range[0]?[1,2]:[2,1]);else{var G=U.range[0],$=U.range[1];\"log\"===N?(0>=G&&0>=$&&a(V+\".autorange\",!0),0>=G?G=$/1e6:0>=$&&($=G/1e6),a(V+\".range[0]\",Math.log(G)/Math.LN10),a(V+\".range[1]\",Math.log($)/Math.LN10)):(a(V+\".range[0]\",Math.pow(10,G)),a(V+\".range[1]\",Math.pow(10,$)))}else a(V+\".autorange\",!0)}if(\"reverse\"===q)Z.range?Z.range.reverse():(a(V+\".autorange\",!0),Z.range=[1,0]),Y.autorange?_=!0:b=!0;else if(\"annotations\"===C.parts[0]||\"shapes\"===C.parts[0]){var Q=C.parts[1],W=C.parts[0],J=p[W]||[],K=O[P.titleCase(W)],tt=J[Q]||{};2===C.parts.length&&(\"add\"===v[E]||P.isPlainObject(v[E])?T[E]=\"remove\":\"remove\"===v[E]?-1===Q?(T[W]=J,delete T[E]):T[E]=tt:P.log(\"???\",v)),!o(tt,\"x\")&&!o(tt,\"y\")||P.containsAny(E,[\"color\",\"opacity\",\"align\",\"dash\"])||(_=!0),K.draw(t,Q,C.parts.slice(2).join(\".\"),v[E]),delete v[E]}else if(\"images\"===C.parts[0]){var nt=P.objectFromPath(E,N);P.extendDeepAll(t.layout,nt),B.supplyLayoutDefaults(t.layout,t._fullLayout),B.draw(t)}else if(\"mapbox\"===C.parts[0]&&\"layers\"===C.parts[1]){P.extendDeepAll(t.layout,P.objectFromPath(E,N));var rt=(t._fullLayout.mapbox||{}).layers||[],at=C.parts[2]+1-rt.length;for(h=0;at>h;h++)rt.push({});b=!0}else 0===C.parts[0].indexOf(\"scene\")?b=!0:0===C.parts[0].indexOf(\"geo\")?b=!0:0===C.parts[0].indexOf(\"ternary\")?b=!0:!g._has(\"gl2d\")||-1===E.indexOf(\"axis\")&&\"plot_bgcolor\"!==C.parts[0]?\"hiddenlabels\"===E?_=!0:-1!==C.parts[0].indexOf(\"legend\")?m=!0:-1!==E.indexOf(\"title\")?y=!0:-1!==C.parts[0].indexOf(\"bgcolor\")?x=!0:C.parts.length>1&&P.containsAny(C.parts[1],[\"tick\",\"exponent\",\"grid\",\"zeroline\"])?y=!0:-1!==E.indexOf(\".linewidth\")&&-1!==E.indexOf(\"axis\")?y=x=!0:C.parts.length>1&&-1!==C.parts[1].indexOf(\"line\")?x=!0:C.parts.length>1&&\"mirror\"===C.parts[1]?y=x=!0:\"margin.pad\"===E?y=x=!0:\"margin\"===C.parts[0]||\"autorange\"===C.parts[1]||\"rangemode\"===C.parts[1]||\"type\"===C.parts[1]||\"domain\"===C.parts[1]||E.match(/^(bar|box|font)/)?_=!0:-1!==[\"hovermode\",\"dragmode\"].indexOf(E)?k=!0:-1===[\"hovermode\",\"dragmode\",\"height\",\"width\",\"autosize\"].indexOf(E)&&(b=!0):b=!0,C.set(N)}D.add(t,et,[t,T],et,[t,A]),v.autosize&&(v=w(t,v)),(v.height||v.width||v.autosize)&&(_=!0);var ot=Object.keys(v),it=[I.previousPromises];if(b||_)it.push(function(){return t.layout=void 0,_&&(t.calcdata=void 0),O.plot(t,\"\",p)});else if(ot.length&&(I.supplyDefaults(t),g=t._fullLayout,m&&it.push(function(){return H.draw(t),I.previousPromises(t)}),x&&it.push(L),y&&it.push(function(){return O.Axes.doTicks(t,\"redraw\"),z(t),I.previousPromises(t)}),k)){var lt;for(X(t),O.Fx.supplyLayoutDefaults(t.layout,g,t._fullData),O.Fx.init(t),lt=I.getSubplotIds(g,\"gl3d\"),h=0;h<lt.length;h++)f=g[lt[h]]._scene,f.updateFx(g.dragmode,g.hovermode);for(lt=I.getSubplotIds(g,\"gl2d\"),h=0;h<lt.length;h++)f=g._plots[lt[h]]._scene2d,f.updateFx(g);for(lt=I.getSubplotIds(g,\"geo\"),h=0;h<lt.length;h++){var st=g[lt[h]]._geo;st.updateFx(g.hovermode)}}var ct=P.syncOrAsync(it,t);return ct&&ct.then||(ct=Promise.resolve(t)),ct.then(function(){var e=P.extendDeep({},A);return i(e),t.emit(\"plotly_relayout\",e),t})},O.purge=function(t){t=r(t);var e=t._fullLayout||{},n=t._fullData||[];return I.cleanPlot([],{},n,e),I.purge(t),N.purge(t),e._container&&e._container.remove(),delete t._context,delete t._replotPending,delete t._mouseDownTime,delete t._hmpixcount,delete t._hmlumcount,t}},{\"../components/color\":18,\"../components/drawing\":41,\"../components/errorbars\":47,\"../components/images\":53,\"../components/legend\":61,\"../components/modebar/manage\":65,\"../components/rangeselector\":72,\"../components/rangeslider\":77,\"../components/shapes\":80,\"../components/titles\":81,\"../constants/xmlns_namespaces\":82,\"../lib\":89,\"../lib/events\":87,\"../lib/queue\":96,\"../plotly\":107,\"../plots/cartesian/graph_interact\":117,\"../plots/plots\":130,d3:9,\"fast-isnumeric\":11,\"gl-mat4/fromQuat\":12}],102:[function(t,e,n){\"use strict\";function r(t,e){try{t._fullLayout._paper.style(\"background\",e)}catch(n){a.error(n)}}var a=t(\"../lib\");e.exports={staticPlot:!1,editable:!1,queueLength:0,autosizable:!1,fillFrame:!1,frameMargins:0,scrollZoom:!1,doubleClick:\"reset+autosize\",showTips:!0,showLink:!1,sendData:!0,linkText:\"Edit chart\",showSources:!1,displayModeBar:\"hover\",modeBarButtonsToRemove:[],modeBarButtonsToAdd:[],modeBarButtons:!1,displaylogo:!0,plotGlPixelRatio:2,setBackground:r,topojsonURL:\"https://cdn.plot.ly/\",mapboxAccessToken:null,logging:!1}},{\"../lib\":89}],103:[function(t,e,n){\"use strict\";function r(t){var e=m.attributes,n=c({type:t}),r=f(t),a=h(t),o={},i={};o.type=null,b(o,e),o=l(n.attributes,o,\"attributes\",t),void 0!==a.attributes&&b(o,a.attributes),o.type=t,o=u(o),s(o),z.traces[t]=x({},r,{attributes:o}),void 0!==n.layoutAttributes&&(i=l(n.layoutAttributes,i,\"layoutAttributes\",t),s(i),z.traces[t].layoutAttributes=i)}function a(){var t=m.layoutAttributes,e={};e=l(t,e,\"layoutAttributes\",\"*\"),e=d(e),e=p(e),e=u(e),s(e),g(e),z.layout={layoutAttributes:e}}function o(t){var e=m.transformsRegistry[t],n={};n=l(n,e.attributes||{},\"attributes\",\"*\"),n=u(n),s(n),g(n),z.transforms[t]={attributes:n}}function i(){z.defs={valObjects:y.valObjects,metaKeys:T.concat([\"description\",\"role\"])}}function l(t,e,n,r){var a,o,i,s,u;return Object.keys(t).forEach(function(f){return f===w?void Object.keys(t[f]).forEach(function(s){a=c({module:t[f][s]}),void 0!==a&&(o=a[n],i=l(o,{},n,r),y.nestedProperty(e,s).set(b({},i)))}):f===k?void Object.keys(t[f]).forEach(function(a){a===r&&(s=c({module:t[f][a]}),void 0!==s&&(u=s[n],u=l(u,{},n,r),_(e,u)))}):void(e[f]=y.isPlainObject(t[f])?_({},t[f]):t[f])}),e}function s(t){function e(t){return{valType:\"string\"}}function n(t,n,r){C.isValObject(t)?\"data_array\"===t.valType?(t.role=\"data\",r[n+\"src\"]=e(n)):t.arrayOk===!0&&(r[n+\"src\"]=e(n)):y.isPlainObject(t)&&(t.role=\"object\")}C.crawl(t,n)}function c(t){if(\"type\"in t)return\"area\"===t.type?{attributes:S}:m.getModule({type:t.type});var e=m.subplotsRegistry,n=t.module;return e[n]?e[n]:\"module\"in t?v[n]:void 0}function u(t){return Object.keys(t).forEach(function(e){\"_\"===e.charAt(0)&&-1===T.indexOf(e)&&delete t[e]}),t}function f(t){return\"area\"===t?{}:m.modules[t].meta||{}}function d(t){return x(t,{radialaxis:E.radialaxis,angularaxis:E.angularaxis}),x(t,E.layout),t}function h(t){if(\"area\"===t)return{};var e=m.subplotsRegistry,n=Object.keys(e).filter(function(e){return m.traceIs({type:t},e)})[0];return void 0===n?{}:e[n]}function p(t){var e=m.subplotsRegistry;return Object.keys(t).forEach(function(n){Object.keys(e).forEach(function(r){var a,o=e[r];o.attrRegex&&(a=\"cartesian\"===r||\"gl2d\"===r?o.attrRegex.x.test(n)||o.attrRegex.y.test(n):o.attrRegex.test(n),a&&(t[n][M]=!0))})}),t}function g(t){function e(t,e,n){if(t[A]===!0){var r=e.substr(0,e.length-1);delete t[A],n[e]={items:{}},n[e].items[r]=t,n[e].role=\"object\"}}C.crawl(t,e)}var v=t(\"../plotly\"),m=t(\"../plots/plots\"),y=t(\"../lib\"),x=y.extendFlat,b=y.extendDeep,_=y.extendDeepAll,w=\"_nestedModules\",k=\"_composedModules\",M=\"_isSubplotObj\",A=\"_isLinkedToArray\",L=\"_deprecated\",T=[M,A,L],z={traces:{},layout:{},transforms:{},defs:{}},S=t(\"../plots/polar/area_attributes\"),E=t(\"../plots/polar/axis_attributes\"),C=e.exports={};C.get=function(){return m.allTypes.concat(\"area\").forEach(r),a(),Object.keys(m.transformsRegistry).forEach(o),i(),z},C.crawl=function(t,e){Object.keys(t).forEach(function(n){var r=t[n];-1===T.indexOf(n)&&(e(r,n,t),C.isValObject(r)||y.isPlainObject(r)&&C.crawl(r,e))})},C.isValObject=function(t){return t&&void 0!==t.valType}},{\"../lib\":89,\"../plotly\":107,\"../plots/plots\":130,\"../plots/polar/area_attributes\":131,\"../plots/polar/axis_attributes\":132}],104:[function(t,e,n){\"use strict\";var r=t(\"../plotly\"),a=t(\"../lib\");e.exports=function(t){return a.extendFlat(r.defaultConfig,t)}},{\"../lib\":89,\"../plotly\":107}],105:[function(t,e,n){\"use strict\";function r(e,n){var r=t(\"../snapshot\"),l=new Promise(function(t,l){function s(){var t=r.getDelay(f._fullLayout);return new Promise(function(e,a){setTimeout(function(){var t=r.toSVG(f),o=document.createElement(\"canvas\");o.id=i.randstr(),r.svgToImg({format:n.format,width:f._fullLayout.width,height:f._fullLayout.height,canvas:o,svg:t,promise:!0}).then(function(t){f&&document.body.removeChild(f),e(t)}).catch(function(t){a(t)})},t)})}n=n||{},n.format=n.format||\"png\";var c=function(t){return void 0===t||null===t?!0:!!(a(t)&&t>1)};c(n.width)&&c(n.height)||l(new Error(\"Height and width should be pixel values.\"));var u=r.clone(e,{format:\"png\",height:n.height,width:n.width}),f=u.td;f.style.position=\"absolute\",f.style.left=\"-5000px\",document.body.appendChild(f);var d=r.getRedrawFunc(f);o.plot(f,u.data,u.layout,u.config).then(d).then(s).then(function(e){t(e)}).catch(function(t){l(t)})});return l}var a=t(\"fast-isnumeric\"),o=t(\"../plotly\"),i=t(\"../lib\");e.exports=r},{\"../lib\":89,\"../plotly\":107,\"../snapshot\":139,\"fast-isnumeric\":11}],106:[function(t,e,n){\"use strict\";function r(t,e,n,a,o,c){c=c||[];for(var u=Object.keys(t),d=0;d<u.length;d++){var h=u[d];if(\"transforms\"!==h){var v=c.slice();v.push(h);var m=t[h],y=e[h],x=s(n,h);if(l(n,h))if(p(m)&&p(y))r(m,y,x,a,o,v);else if(x.items&&g(m))for(var b=h.substr(0,h.length-1),_=0;_<m.length;_++){var w=x.items[b],k=v.slice();k.push(_),r(m[_],y[_],w,a,o,k)}else!p(m)&&p(y)?a.push(i(\"object\",o,v,m)):!g(m)&&g(y)&&\"info_array\"!==x.valType?a.push(i(\"array\",o,v,m)):h in e?f.validate(m,x)||a.push(i(\"value\",o,v,m)):a.push(i(\"u" -, -"nused\",o,v,m));else a.push(i(\"schema\",o,v))}}return a}function a(t,e){for(var n=0;n<e.length;n++){var r=e[n].type,a=t.traces[r].layoutAttributes;a&&f.extendFlat(t.layout.layoutAttributes,a)}return t.layout.layoutAttributes}function o(t){return g(t)?\"In data trace \"+t[1]+\", \":\"In \"+t+\", \"}function i(t,e,n,r){n=n||\"\";var a,o;g(e)?(a=e[0],o=e[1]):(a=e,o=null);var i=u(n),l=v[t](e,i,r);return f.log(l),{code:t,container:a,trace:o,path:n,astr:i,msg:l}}function l(t,e){var n=c(e),r=n.keyMinusId,a=n.id;return r in t&&t[r]._isSubplotObj&&a?!0:e in t}function s(t,e){var n=c(e);return t[n.keyMinusId]}function c(t){var e=/([2-9]|[1-9][0-9]+)$/,n=t.split(e)[0],r=t.substr(n.length,t.length);return{keyMinusId:n,id:r}}function u(t){if(!g(t))return String(t);for(var e=\"\",n=0;n<t.length;n++){var r=t[n];\"number\"==typeof r?e=e.substr(0,e.length-1)+\"[\"+r+\"]\":e+=r,n<t.length-1&&(e+=\".\")}return e}var f=t(\"../lib\"),d=t(\"../plots/plots\"),h=t(\"./plot_schema\"),p=f.isPlainObject,g=Array.isArray;e.exports=function(t,e){var n,o,l=h.get(),s=[],c={};g(t)?(c.data=f.extendDeep([],t),n=t):(c.data=[],n=[],s.push(i(\"array\",\"data\"))),p(e)?(c.layout=f.extendDeep({},e),o=e):(c.layout={},o={},arguments.length>1&&s.push(i(\"object\",\"layout\"))),d.supplyDefaults(c);for(var u=c._fullData,v=n.length,m=0;v>m;m++){var y=n[m],x=[\"data\",m];if(p(y)){var b=u[m],_=b.type,w=l.traces[_].attributes;w.type={valType:\"enumerated\",values:[_]},b.visible===!1&&y.visible!==!1&&s.push(i(\"invisible\",x)),r(y,b,w,s,x);var k=y.transforms,M=b.transforms;if(k){g(k)||s.push(i(\"array\",x,[\"transforms\"])),x.push(\"transforms\");for(var A=0;A<k.length;A++){var L=[\"transforms\",A],T=k[A].type;if(p(k[A])){var z=l.transforms[T]?l.transforms[T].attributes:{};z.type={valType:\"enumerated\",values:Object.keys(l.transforms)},r(k[A],M[A],z,s,x,L)}else s.push(i(\"object\",x,L))}}}else s.push(i(\"object\",x))}var S=c._fullLayout,E=a(l,u);return r(o,S,E,s,\"layout\"),0===s.length?void 0:s};var v={object:function(t,e){var n;return n=\"layout\"===t&&\"\"===e?\"The layout argument\":\"data\"===t[0]&&\"\"===e?\"Trace \"+t[1]+\" in the data argument\":o(t)+\"key \"+e,\n" -, -"n+\" must be linked to an object container\"},array:function(t,e){var n;return n=\"data\"===t?\"The data argument\":o(t)+\"key \"+e,n+\" must be linked to an array container\"},schema:function(t,e){return o(t)+\"key \"+e+\" is not part of the schema\"},unused:function(t,e,n){var r=p(n)?\"container\":\"key\";return o(t)+r+\" \"+e+\" did not get coerced\"},invisible:function(t){return\"Trace \"+t[1]+\" got defaulted to be not visible\"},value:function(t,e,n){return[o(t)+\"key \"+e,\"is set to an invalid value (\"+n+\")\"].join(\" \")}}},{\"../lib\":89,\"../plots/plots\":130,\"./plot_schema\":103}],107:[function(t,e,n){\"use strict\";t(\"es6-promise\").polyfill();var r=n.Lib=t(\"./lib\");n.util=t(\"./lib/svg_text_utils\"),n.Queue=t(\"./lib/queue\"),t(\"../build/plotcss\"),n.MathJaxConfig=t(\"./fonts/mathjax_config\"),n.defaultConfig=t(\"./plot_api/plot_config\");var a=n.Plots=t(\"./plots/plots\");n.Axes=t(\"./plots/cartesian/axes\"),n.Fx=t(\"./plots/cartesian/graph_interact\"),n.micropolar=t(\"./plots/polar/micropolar\"),n.Color=t(\"./components/color\"),n.Drawing=t(\"./components/drawing\"),n.Colorscale=t(\"./components/colorscale\"),n.Colorbar=t(\"./components/colorbar\"),n.ErrorBars=t(\"./components/errorbars\"),n.Annotations=t(\"./components/annotations\"),n.Shapes=t(\"./components/shapes\"),n.Legend=t(\"./components/legend\"),n.Images=t(\"./components/images\"),n.ModeBar=t(\"./components/modebar\"),n.register=function(t){if(!t)throw new Error(\"No argument passed to Plotly.register.\");t&&!Array.isArray(t)&&(t=[t]);for(var e=0;e<t.length;e++){var n=t[e];if(!n)throw new Error(\"Invalid module was attempted to be registered!\");switch(n.moduleType){case\"trace\":a.register(n,n.name,n.categories,n.meta),a.subplotsRegistry[n.basePlotModule.name]||a.registerSubplot(n.basePlotModule);break;case\"transform\":if(\"string\"!=typeof n.name)throw new Error(\"Transform module *name* must be a string.\");var o=\"Transform module \"+n.name;if(\"function\"!=typeof n.transform)throw new Error(o+\" is missing a *transform* function.\");r.isPlainObject(n.attributes)||r.log(o+\" registered without an *attributes* object.\"),\"function\"!=typeof n.supplyDefaults&&r.log(o+\" registered without a *supplyDefaults* function.\"),a.transformsRegistry[n.name]=n;break;default:throw new Error(\"Invalid module was attempted to be registered!\")}}},n.register(t(\"./traces/scatter\")),t(\"./plot_api/plot_api\"),n.PlotSchema=t(\"./plot_api/plot_schema\"),n.Snapshot=t(\"./snapshot\")},{\"../build/plotcss\":1,\"./components/annotations\":16,\"./components/color\":18,\"./components/colorbar\":23,\"./components/colorscale\":32,\"./components/drawing\":41,\"./components/errorbars\":47,\"./components/images\":53,\"./components/legend\":61,\"./components/modebar\":64,\"./components/shapes\":80,\"./fonts/mathjax_config\":84,\"./lib\":89,\"./lib/queue\":96,\"./lib/svg_text_utils\":100,\"./plot_api/plot_api\":101,\"./plot_api/plot_config\":102,\"./plot_api/plot_schema\":103,\"./plots/cartesian/axes\":110,\"./plots/cartesian/graph_interact\":117,\"./plots/plots\":130,\"./plots/polar/micropolar\":133,\"./snapshot\":139,\"./traces/scatter\":177,\"es6-promise\":10}],108:[function(t,e,n){\"use strict\";e.exports={type:{valType:\"enumerated\",values:[],dflt:\"scatter\"},visible:{valType:\"enumerated\",values:[!0,!1,\"legendonly\"],dflt:!0},showlegend:{valType:\"boolean\",dflt:!0},legendgroup:{valType:\"string\",dflt:\"\"},opacity:{valType:\"number\",min:0,max:1,dflt:1},name:{valType:\"string\"},uid:{valType:\"string\",dflt:\"\"},hoverinfo:{valType:\"flaglist\",flags:[\"x\",\"y\",\"z\",\"text\",\"name\"],extras:[\"all\",\"none\"],dflt:\"all\"},stream:{token:{valType:\"string\",noBlank:!0,strict:!0},maxpoints:{valType:\"number\",min:0}}}},{}],109:[function(t,e,n){\"use strict\";e.exports={xaxis:{valType:\"subplotid\",dflt:\"x\"},yaxis:{valType:\"subplotid\",dflt:\"y\"}}},{}],110:[function(t,e,n){\"use strict\";function r(t){var e,n,r=t.tickvals,a=t.ticktext,o=new Array(r.length),i=1.0001*t.range[0]-1e-4*t.range[1],s=1.0001*t.range[1]-1e-4*t.range[0],c=Math.min(i,s),u=Math.max(i,s),f=0;for(Array.isArray(a)||(a=[]),n=0;n<r.length;n++)e=t.d2l(r[n]),e>c&&u>e&&(void 0===a[n]?o[f]=L.tickText(t,e):o[f]=l(t,e,String(a[n])),f++);return f<r.length&&o.splice(f,r.length-f),o}function a(t,e,n){return e*_.roundUp(t/e,n)}function o(t){var e,n=t.dtick;if(t._tickexponent=0,x(n)||\"string\"==typeof n||(n=1),\"category\"===t.type)t._tickround=null;else if(x(n)||\"L\"===n.charAt(0))if(\"date\"===t.type)n>=864e5?t._tickround=\"d\":n>=36e5?t._tickround=\"H\":n>=6e4?t._tickround=\"M\":n>=1e3?t._tickround=\"S\":t._tickround=3-Math.round(Math.log(n/2)/Math.LN10);else{x(n)||(n=Number(n.substr(1))),t._tickround=2-Math.floor(Math.log(n)/Math.LN10+.01),e=\"log\"===t.type?Math.pow(10,Math.max(t.range[0],t.range[1])):Math.max(Math.abs(t.range[0]),Math.abs(t.range[1]));var r=Math.floor(Math.log(e)/Math.LN10+.01);Math.abs(r)>3&&(\"SI\"===t.exponentformat||\"B\"===t.exponentformat?t._tickexponent=3*Math.round((r-1)/3):t._tickexponent=r)}else\"M\"===n.charAt(0)?t._tickround=2===n.length?\"m\":\"y\":t._tickround=null}function i(t,e){var n=t.match(B),r=new Date(e);if(n){var a=Math.min(+n[1]||6,6),o=String(e/1e3%1+2.0000005).substr(2,a).replace(/0+$/,\"\")||\"0\";return y.time.format(t.replace(B,o))(r)}return y.time.format(t)(r)}function l(t,e,n){var r=t.tickfont||t._gd._fullLayout.font;return{x:e,dx:0,dy:0,text:n||\"\",fontSize:r.size,font:r.family,fontColor:r.color}}function s(t,e,n,r){var a,o=e.x,l=t._tickround,s=new Date(o),c=\"\";n&&t.hoverformat?a=i(t.hoverformat,o):t.tickformat?a=i(t.tickformat,o):(r&&(x(l)?l+=2:l={y:\"m\",m:\"d\",d:\"H\",H:\"M\",M:\"S\",S:2}[l]),\"y\"===l?a=D(s):\"m\"===l?a=I(s):(o!==t._tmin||n||(c=\"<br>\"+D(s)),\"d\"===l?a=R(s):\"H\"===l?a=j(s):(o!==t._tmin||n||(c=\"<br>\"+R(s)+\", \"+D(s)),a=q(s),\"M\"!==l&&(a+=F(s),\"S\"!==l&&(a+=d(m(o/1e3,1),t,\"none\",n).substr(1)))))),e.text=a+c}function c(t,e,n,r,a){var o=t.dtick,i=e.x;if(!r||\"string\"==typeof o&&\"L\"===o.charAt(0)||(o=\"L3\"),t.tickformat||\"string\"==typeof o&&\"L\"===o.charAt(0))e.text=d(Math.pow(10,i),t,a,r);else if(x(o)||\"D\"===o.charAt(0)&&m(i+.01,1)<.1)if(-1!==[\"e\",\"E\",\"power\"].indexOf(t.exponentformat)){var l=Math.round(i);0===l?e.text=1:1===l?e.text=\"10\":l>1?e.text=\"10<sup>\"+l+\"</sup>\":e.text=\"10<sup>\\u2212\"+-l+\"</sup>\",e.fontSize*=1.25}else e.text=d(Math.pow(10,i),t,\"\",\"fakehover\"),\"D1\"===o&&\"y\"===t._id.charAt(0)&&(e.dy-=e.fontSize/6);else{if(\"D\"!==o.charAt(0))throw\"unrecognized dtick \"+String(o);e.text=String(Math.round(Math.pow(10,m(i,1)))),e.fontSize*=.75}if(\"D1\"===t.dtick){var s=String(e.text).charAt(0);\"0\"!==s&&\"1\"!==s||(\"y\"===t._id.charAt(0)?e.dx-=e.fontSize/4:(e.dy+=e.fontSize/2,e.dx+=(t.range[1]>t.range[0]?1:-1)*e.fontSize*(0>i?.5:.25)))}}function u(t,e){var n=t._categories[Math.round(e.x)];void 0===n&&(n=\"\"),e.text=String(n)}function f(t,e,n,r,a){\"all\"===t.showexponent&&Math.abs(e.x/t.dtick)<1e-6&&(a=\"hide\"),e.text=d(e.x,t,a,r)}function d(t,e,n,r){var a=0>t,i=e._tickround,l=n||e.exponentformat||\"B\",s=e._tickexponent,c=e.tickformat;if(r){var u={exponentformat:e.exponentformat,dtick:\"none\"===e.showexponent?e.dtick:x(t)?Math.abs(t)||1:1,range:\"none\"===e.showexponent?e.range:[0,t||1]};o(u),i=(Number(u._tickround)||0)+4,s=u._tickexponent,e.hoverformat&&(c=e.hoverformat)}if(c)return y.format(c)(t).replace(/-/g,\"\\u2212\");var f=Math.pow(10,-i)/2;if(\"none\"===l&&(s=0),t=Math.abs(t),f>t)t=\"0\",a=!1;else{if(t+=f,s&&(t*=Math.pow(10,-s),i+=s),0===i)t=String(Math.floor(t));else if(0>i){t=String(Math.round(t)),t=t.substr(0,t.length+i);for(var d=i;0>d;d++)t+=\"0\"}else{t=String(t);var h=t.indexOf(\".\")+1;h&&(t=t.substr(0,h+i).replace(/\\.?0+$/,\"\"))}t=_.numSeparate(t,e._gd._fullLayout.separators)}if(s&&\"hide\"!==l){var p;p=0>s?\"\\u2212\"+-s:\"power\"!==l?\"+\"+s:String(s),\"e\"===l||(\"SI\"===l||\"B\"===l)&&(s>12||-15>s)?t+=\"e\"+p:\"E\"===l?t+=\"E\"+p:\"power\"===l?t+=\"×10<sup>\"+p+\"</sup>\":\"B\"===l&&9===s?t+=\"B\":\"SI\"!==l&&\"B\"!==l||(t+=H[s/3+5])}return a?\"\\u2212\"+t:t}function h(t,e){var n,r,a=[];for(n=0;n<e.length;n++){var o=[],i=t._fullData[e[n]].xaxis,l=t._fullData[e[n]].yaxis;if(i&&l){for(r=0;r<a.length;r++)-1===a[r].x.indexOf(i)&&-1===a[r].y.indexOf(l)||o.push(r);if(o.length){var s,c=a[o[0]];if(o.length>1)for(r=1;r<o.length;r++)s=a[o[r]],p(c.x,s.x),p(c.y,s.y);p(c.x,[i]),p(c.y,[l])}else a.push({x:[i],y:[l]})}}return a}function p(t,e){for(var n=0;n<e.length;n++)-1===t.indexOf(e[n])&&t.push(e[n])}function g(t,e,n){var r,a,o=[],i=[],l=t.layout;for(r=0;r<e.length;r++)o.push(L.getFromId(t,e[r]));for(r=0;r<n.length;r++)i.push(L.getFromId(t,n[r]));var s=Object.keys(o[0]),c=[\"anchor\",\"domain\",\"overlaying\",\"position\",\"side\",\"tickangle\"],u=[\"linear\",\"log\"];for(r=0;r<s.length;r++){var f=s[r],d=o[0][f],h=i[0][f],p=!0,g=!1,m=!1;if(\"_\"!==f.charAt(0)&&\"function\"!=typeof d&&-1===c.indexOf(f)){for(a=1;a<o.length&&p;a++){var y=o[a][f];\"type\"===f&&-1!==u.indexOf(d)&&-1!==u.indexOf(y)&&d!==y?g=!0:y!==d&&(p=!1)}for(a=1;a<i.length&&p;a++){var x=i[a][f];\"type\"===f&&-1!==u.indexOf(h)&&-1!==u.indexOf(x)&&h!==x?m=!0:i[a][f]!==h&&(p=!1)}p&&(g&&(l[o[0]._name].type=\"linear\"),m&&(l[i[0]._name].type=\"linear\"),v(l,f,o,i))}}for(r=0;r<t._fullLayout.annotations.length;r++){var b=t._fullLayout.annotations[r];-1!==e.indexOf(b.xref)&&-1!==n.indexOf(b.yref)&&_.swapAttrs(l.annotations[r],[\"?\"])}}function v(t,e,n,r){var a,o=_.nestedProperty,i=o(t[n[0]._name],e).get(),l=o(t[r[0]._name],e).get();for(\"title\"===e&&(\"Click to enter X axis title\"===i&&(i=\"Click to enter Y axis title\"),\"Click to enter Y axis title\"===l&&(l=\"Click to enter X axis title\")),a=0;a<n.length;a++)o(t,n[a]._name+\".\"+e).set(l);for(a=0;a<r.length;a++)o(t,r[a]._name+\".\"+e).set(i)}function m(t,e){return(t%e+e)%e}var y=t(\"d3\"),x=t(\"fast-isnumeric\"),b=t(\"../../plotly\"),_=t(\"../../lib\"),w=t(\"../../lib/svg_text_utils\"),k=t(\"../../components/titles\"),M=t(\"../../components/color\"),A=t(\"../../components/drawing\"),L=e.exports={};L.layoutAttributes=t(\"./layout_attributes\"),L.supplyLayoutDefaults=t(\"./layout_defaults\"),L.setConvert=t(\"./set_convert\");var T=t(\"./axis_ids\");L.id2name=T.id2name,L.cleanId=T.cleanId,L.list=T.list,L.listIds=T.listIds,L.getFromId=T.getFromId,L.getFromTrace=T.getFromTrace,L.coerceRef=function(t,e,n,r,a){var o=n._fullLayout._has(\"gl2d\")?[]:L.listIds(n,r),i=r+\"ref\",l={};return l[i]={va" -, -"lType:\"enumerated\",values:o.concat([\"paper\"]),dflt:a||o[0]||\"paper\"},_.coerce(t,e,l,i)},L.coerceARef=function(t,e,n,r,a){var o=n._fullLayout._has(\"gl2d\")?[]:L.listIds(n,r),i=\"a\"+r+\"ref\",l={};return l[i]={valType:\"enumerated\",values:o.concat([\"pixel\"]),dflt:a||\"pixel\"||o[0]},_.coerce(t,e,l,i)},L.clearTypes=function(t,e){Array.isArray(e)&&e.length||(e=t._fullData.map(function(t,e){return e})),e.forEach(function(e){var n=t.data[e];delete(L.getFromId(t,n.xaxis)||{}).type,delete(L.getFromId(t,n.yaxis)||{}).type})},L.counterLetter=function(t){var e=t.charAt(0);return\"x\"===e?\"y\":\"y\"===e?\"x\":void 0},L.minDtick=function(t,e,n,r){-1===[\"log\",\"category\"].indexOf(t.type)&&r?null===t._minDtick?(t._minDtick=e,t._forceTick0=n):t._minDtick&&((t._minDtick/e+1e-6)%1<2e-6&&((n-t._forceTick0)/e%1+1.000001)%1<2e-6?(t._minDtick=e,t._forceTick0=n):((e/t._minDtick+1e-6)%1>2e-6||((n-t._forceTick0)/t._minDtick%1+1.000001)%1>2e-6)&&(t._minDtick=0)):t._minDtick=0},L.getAutoRange=function(t){var e,n=[],r=t._min[0].val,a=t._max[0].val;for(e=1;e<t._min.length&&r===a;e++)r=Math.min(r,t._min[e].val);for(e=1;e<t._max.length&&r===a;e++)a=Math.max(a,t._max[e].val);var o,i,l,s,c,u,f,d=0,h=t.range&&t.range[1]<t.range[0];for(\"reversed\"===t.autorange&&(h=!0,t.autorange=!0),e=0;e<t._min.length;e++)for(i=t._min[e],o=0;o<t._max.length;o++)l=t._max[o],f=l.val-i.val,u=t._length-i.pad-l.pad,f>0&&u>0&&f/u>d&&(s=i,c=l,d=f/u);return r===a?n=h?[r+1,\"normal\"!==t.rangemode?0:r-1]:[\"normal\"!==t.rangemode?0:r-1,r+1]:d&&(\"linear\"!==t.type&&\"-\"!==t.type||(\"tozero\"===t.rangemode&&s.val>=0?s={val:0,pad:0}:\"nonnegative\"===t.rangemode&&(s.val-d*s.pad<0&&(s={val:0,pad:0}),c.val<0&&(c={val:1,pad:0})),d=(c.val-s.val)/(t._length-s.pad-c.pad)),n=[s.val-d*s.pad,c.val+d*c.pad],n[0]===n[1]&&(n=[n[0]-1,n[0]+1]),h&&n.reverse()),n},L.doAutoRange=function(t){t._length||t.setScale();var e=t._min&&t._max&&t._min.length&&t._max.length;if(t.autorange&&e){t.range=L.getAutoRange(t);var n=t._gd.layout[t._name];n||(t._gd.layout[t._name]=n={}),n!==t&&(n.range=t.range.slice(),n.autorange=t.autorange)}},L.saveRangeInitial=function(t,e){for(var n=L.list(t,\"\",!0),r=!1,a=0;a<n.length;a++){var o=n[a],i=void 0===o._rangeInitial,l=i||!(o.range[0]===o._rangeInitial[0]&&o.range[1]===o._rangeInitial[1]);(i&&o.autorange===!1||e&&l)&&(o._rangeInitial=o.range.slice(),r=!0)}return r};var z=Number.MAX_VALUE/2;L.expand=function(t,e,n){function r(t){if(Array.isArray(t))return function(e){return Math.max(Number(t[e]||0),0)};var e=Math.max(Number(t||0),0);return function(){return e}}function a(n){function r(t){return x(t)&&Math.abs(t)<z}if(s=e[n],x(s)){if(f=b(n)+m,d=_(n)+m,p=s-k(n),g=s+w(n),\"log\"===t.type&&g/10>p&&(p=g/10),c=t.c2l(p),u=t.c2l(g),y&&(c=Math.min(0,c),u=Math.max(0,u)),r(c)){for(h=!0,i=0;i<t._min.length&&h;i++)l=t._min[i],l.val<=c&&l.pad>=d?h=!1:l.val>=c&&l.pad<=d&&(t._min.splice(i,1),i--);h&&t._min.push({val:c,pad:y&&0===c?0:d})}if(r(u)){for(h=!0,i=0;i<t._max.length&&h;i++)l=t._max[i],l.val>=u&&l.pad>=f?h=!1:l.val<=u&&l.pad<=f&&(t._max.splice(i,1),i--);h&&t._max.push({val:u,pad:y&&0===u?0:f})}}}if((t.autorange||t._needsExpand)&&e){t._min||(t._min=[]),t._max||(t._max=[]),n||(n={}),t._m||t.setScale();var o,i,l,s,c,u,f,d,h,p,g,v=e.length,m=n.padded?.05*t._length:0,y=n.tozero&&(\"linear\"===t.type||\"-\"===t.type),b=r((t._m>0?n.ppadplus:n.ppadminus)||n.ppad||0),_=r((t._m>0?n.ppadminus:n.ppadplus)||n.ppad||0),w=r(n.vpadplus||n.vpad),k=r(n.vpadminus||n.vpad);for(o=0;6>o;o++)a(o);for(o=v-1;o>5;o--)a(o)}},L.autoBin=function(t,e,n,r){function a(t){return(1+100*(t-h)/f.dtick)%100<2}var o=_.aggNums(Math.min,null,t),i=_.aggNums(Math.max,null,t);if(\"category\"===e.type)return{start:o-.5,end:i+.5,size:1};var l;if(n)l=(i-o)/n;else{var s=_.distinctVals(t),c=Math.pow(10,Math.floor(Math.log(s.minDiff)/Math.LN10)),u=c*_.roundUp(s.minDiff/c,[.9,1.9,4.9,9.9],!0);l=Math.max(u,2*_.stdev(t)/Math.pow(t.length,r?.25:.4))}var f={type:\"log\"===e.type?\"linear\":e.type,range:[o,i]};L.autoTicks(f,l);var d,h=L.tickIncrement(L.tickFirst(f),f.dtick,\"reverse\");if(\"number\"==typeof f.dtick){for(var p=0,g=0,v=0,m=0,y=0;y<t.length;y++)t[y]%1===0?v++:x(t[y])||m++,a(t[y])&&p++,a(t[y]+f.dtick/2)&&g++;var b=t.length-m;if(v===b&&\"date\"!==e.type)f.dtick<1?h=o-.5*f.dtick:h-=.5;else if(.1*b>g&&(p>.3*b||a(o)||a(i))){var w=f.dtick/2;h+=o>h+w?w:-w}var k=1+Math.floor((i-h)/f.dtick);d=h+k*f.dtick}else for(d=h;i>=d;)d=L.tickIncrement(d,f.dtick);return{start:h,end:d,size:f.dtick}},L.calcTicks=function(t){if(\"array\"===t.tickmode)return r(t);if(\"auto\"===t.tickmode||!t.dtick){var e,n=t.nticks;n||(\"category\"===t.type?(e=t.tickfont?1.2*(t.tickfont.size||12):15,n=t._length/e):(e=\"y\"===t._id.charAt(0)?40:80,n=_.constrain(t._length/e,4,9)+1)),L.autoTicks(t,Math.abs(t.range[1]-t.range[0])/n),t._minDtick>0&&t.dtick<2*t._minDtick&&(t.dtick=t._minDtick,t.tick0=t._forceTick0)}t.tick0||(t.tick0=\"date\"===t.type?new Date(2e3,0,1).getTime():0),o(t),t._tmin=L.tickFirst(t);var a=t.range[1]<t.range[0],i=[],l=1.0001*t.range[1]-1e-4*t.range[0];\"category\"===t.type&&(l=a?Math.max(-.5,l):Math.min(t._categories.length-.5,l));for(var s=t._tmin;(a?s>=l:l>=s)&&(i.push(s),!(i.length>1e3));s=L.tickIncrement(s,t.dtick,a));t._tmax=i[i.length-1];for(var c=new Array(i.length),u=0;u<i.length;u++)c[u]=L.tickText(t,i[u]);return c};var S=[2,5,10],E=[1,2,3,6,12],C=[1,2,5,10,15,30],O=[1,2,3,7,14],P=[-.046,0,.301,.477,.602,.699,.778,.845,.903,.954,1],N=[-.301,0,.301,.699,1];L.autoTicks=function(t,e){var n;if(\"date\"===t.type)t.tick0=new Date(2e3,0,1).getTime(),e>157788e5?(e/=315576e5,n=Math.pow(10,Math.floor(Math.log(e)/Math.LN10)),t.dtick=\"M\"+12*a(e,n,S)):e>12096e5?(e/=26298e5,t.dtick=\"M\"+a(e,1,E)):e>432e5?(t.dtick=a(e,864e5,O),t.tick0=new Date(2e3,0,2).getTime()):e>18e5?t.dtick=a(e,36e5,E):e>3e4?t.dtick=a(e,6e4,C):e>500?t.dtick=a(e,1e3,C):(n=Math.pow(10,Math.floor(Math.log(e)/Math.LN10)),t.dtick=a(e,n,S));else if(\"log\"===t.type)if(t.tick0=0,e>.7)t.dtick=Math.ceil(e);else if(Math.abs(t.range[1]-t.range[0])<1){var r=1.5*Math.abs((t.range[1]-t.range[0])/e);e=Math.abs(Math.pow(10,t.range[1])-Math.pow(10,t.range[0]))/r,n=Math.pow(10,Math.floor(Math.log(e)/Math.LN10)),t.dtick=\"L\"+a(e,n,S)}else t.dtick=e>.3?\"D2\":\"D1\";else\"category\"===t.type?(t.tick0=0,t.dtick=Math.ceil(Math.max(e,1))):(t.tick0=0,n=Math.pow(10,Math.floor(Math.log(e)/Math.LN10)),t.dtick=a(e,n,S));if(0===t.dtick&&(t.dtick=1),!x(t.dtick)&&\"string\"!=typeof t.dtick){var o=t.dtick;throw t.dtick=1,\"ax.dtick error: \"+String(o)}},L.tickIncrement=function(t,e,n){var r=n?-1:1;if(x(e))return t+r*e;var a=e.charAt(0),o=r*Number(e.substr(1));if(\"M\"===a){var i=new Date(t);return i.setMonth(i.getMonth()+o)}if(\"L\"===a)return Math.log(Math.pow(10,t)+o)/Math.LN10;if(\"D\"===a){var l=\"D2\"===e?N:P,s=t+.01*r,c=_.roundUp(m(s,1),l,n);return Math.floor(s)+Math.log(y.round(Math.pow(10,c),1))/Math.LN10}throw\"unrecognized dtick \"+String(e)},L.tickFirst=function(t){var e=t.range[1]<t.range[0],n=e?Math.floor:Math.ceil,r=1.0001*t.range[0]-1e-4*t.range[1],a=t.dtick,o=t.tick0;if(x(a)){var i=n((r-o)/a)*a+o;return\"category\"===t.type&&(i=_.constrain(i,0,t._categories.length-1)),i}var l,s,c,u=a.charAt(0),f=Number(a.substr(1));if(\"M\"===u){for(l=new Date(o),r=new Date(r),s=12*(r.getFullYear()-l.getFullYear())+r.getMonth()-l.getMonth(),c=l.setMonth(l.getMonth()+(Math.round(s/f)+(e?1:-1))*f);e?c>r:r>c;)c=L.tickIncrement(c,a,e);return c}if(\"L\"===u)return Math.log(n((Math.pow(10,r)-o)/f)*f+o)/Math.LN10;if(\"D\"===u){var d=\"D2\"===a?N:P,h=_.roundUp(m(r,1),d,e);return Math.floor(r)+Math.log(y.round(Math.pow(10,h),1))/Math.LN10}throw\"unrecognized dtick \"+String(a)};var D=y.time.format(\"%Y\"),I=y.time.format(\"%b %Y\"),R=y.time.format(\"%b %-d\"),j=y.time.format(\"%b %-d %Hh\"),q=y.time.format(\"%H:%M\"),F=y.time.format(\":%S\"),B=/%(\\d?)f/g;L.tickText=function(t,e,n){function r(r){var a;return void 0===r?!0:n?\"none\"===r:(a={first:t._tmin,last:t._tmax}[r],\"all\"!==r&&e!==a)}var a,o,i=l(t,e),d=\"array\"===t.tickmode,h=n||d;if(d&&Array.isArray(t.ticktext)){var p=Math.abs(t.range[1]-t.range[0])/1e4;for(o=0;o<t.ticktext.length&&!(Math.abs(e-t.d2l(t.tickvals[o]))<p);o++);if(o<t.ticktext.length)return i.text=String(t.ticktext[o]),i}return a=\"none\"!==t.exponentformat&&r(t.showexponent)?\"hide\":\"\",\"date\"===t.type?s(t,i,n,h):\"log\"===t.type?c(t,i,n,h,a):\"category\"===t.type?u(t,i):f(t,i,n,h,a),t.tickprefix&&!r(t.showtickprefix)&&(i.text=t.tickprefix+i.text),t.ticksuffix&&!r(t.showticksuffix)&&(i.text+=t.ticksuffix),i};var H=[\"f\",\"p\",\"n\",\"μ\",\"m\",\"\",\"k\",\"M\",\"G\",\"T\"];L.subplotMatch=/^x([0-9]*)y([0-9]*)$/,L.getSubplots=function(t,e){function n(t,e){return-1!==t.indexOf(e._id)}var r,a,o,i=[],l=t.data||[];for(r=0;r<l.length;r++){var s=l[r];if(s.visible!==!1&&\"legendonly\"!==s.visible&&(b.Plots.traceIs(s,\"cartesian\")||b.Plots.traceIs(s,\"gl2d\"))){var c=s.xaxis||\"x\",u=s.yaxis||\"y\";o=c+u,-1===i.indexOf(o)&&i.push(o)}}var f=L.list(t,\"\",!0);for(r=0;r<f.length;r++){var d=f[r],h=d._id.charAt(0),p=\"free\"===d.anchor?\"x\"===h?\"y\":\"x\":d.anchor,g=L.getFromId(t,p),v=!1;for(a=0;a<i.length;a++)if(n(i[a],d)){v=!0;break}\"free\"===d.anchor&&v||g&&(o=\"x\"===h?d._id+g._id:g._id+d._id,-1===i.indexOf(o)&&i.push(o))}var m=L.subplotMatch,y=[];for(r=0;r<i.length;r++)o=i[r],m.test(o)&&y.push(o);return y.sort(function(t,e){var n=t.match(m),r=e.match(m);return n[1]===r[1]?+(n[2]||1)-(r[2]||1):+(n[1]||0)-(r[1]||0)}),e?L.findSubplotsWithAxis(y,e):y},L.findSubplotsWithAxis=function(t,e){for(var n=new RegExp(\"x\"===e._id.charAt(0)?\"^\"+e._id+\"y\":e._id+\"$\"),r=[],a=0;a<t.length;a++){var o=t[a];n.test(o)&&r.push(o)}return r},L.makeClipPaths=function(t){var e,n,r=t._fullLayout,a=r._defs,o={_offset:0,_length:r.width,_id:\"\"},i={_offset:0,_length:r.height,_id:\"\"},l=L.list(t,\"x\",!0),s=L.list(t,\"y\",!0),c=[];for(e=0;e<l.length;e++)for(c.push({x:l[e],y:i}),n=0;n<s.length;n++)0===e&&c.push({x:o,y:s[n]}),c.push({x:l[e],y:s[n]});var u=a.selectAll(\"g.clips\").data([0]);u.enter().append(\"g\").classed(\"clips\",!0);var f=u.selectAll(\".axesclip\").data(c,function(t){return t.x._id+t.y._id});f.enter().append(\"clipPath\").classed(\"axesclip\",!0).attr(\"id\",function(t){return\"clip\"+r" -, -"._uid+t.x._id+t.y._id}).append(\"rect\"),f.exit().remove(),f.each(function(t){y.select(this).select(\"rect\").attr({x:t.x._offset||0,y:t.y._offset||0,width:t.x._length||1,height:t.y._length||1})})},L.doTicks=function(t,e,n){function r(t){var e=c.l2p(t.x);return e>1&&e<c._length-1}function a(t,e){var n=t.selectAll(\"path.\"+E).data(\"inside\"===c.ticks?H:z,S);e&&c.ticks?(n.enter().append(\"path\").classed(E,1).classed(\"ticks\",1).classed(\"crisp\",1).call(M.stroke,c.tickcolor).style(\"stroke-width\",j+\"px\").attr(\"d\",e),n.attr(\"transform\",h),n.exit().remove()):n.remove()}function o(n,r){function a(t,e){t.each(function(t){var n=p(e),r=y.select(this),a=r.select(\".text-math-group\"),o=h(t)+(x(e)&&0!==+e?\" rotate(\"+e+\",\"+f(t)+\",\"+(d(t)-t.fontSize/2)+\")\":\"\");if(a.empty()){var i=r.select(\"text\").attr({transform:o,\"text-anchor\":n});i.empty()||i.selectAll(\"tspan.line\").attr({x:i.attr(\"x\"),y:i.attr(\"y\")})}else{var l=A.bBox(a.node()).width*{end:-.5,start:.5}[n];a.attr(\"transform\",o+(l?\"translate(\"+l+\",0)\":\"\"))}})}function o(){return L.length&&Promise.all(L)}function l(){if(a(u,c.tickangle),\"x\"===v&&!x(c.tickangle)&&(\"log\"!==c.type||\"D\"!==String(c.dtick).charAt(0))){var t=[];for(u.each(function(e){var n=y.select(this),r=n.select(\".text-math-group\"),a=c.l2p(e.x);r.empty()&&(r=n.select(\"text\"));var o=A.bBox(r.node());t.push({top:0,bottom:10,height:10,left:a-o.width/2,right:a+o.width/2+2,width:o.width+2})}),g=0;g<t.length-1;g++)if(_.bBoxIntersect(t[g],t[g+1])){M=30;break}if(M){var n=Math.abs((z[z.length-1].x-z[0].x)*c._m)/(z.length-1);2.5*k>n&&(M=90),a(u,M)}c._lastangle=M}return i(e),e+\" done\"}function s(){c._boundingBox=n.node().getBoundingClientRect()}var u=n.selectAll(\"g.\"+E).data(z,S);if(!c.showticklabels||!x(r))return u.remove(),void i(e);var f,d,p,m,b;\"x\"===v?(b=\"bottom\"===F?1:-1,f=function(t){return t.dx+D*b},m=r+(N+P)*b,d=function(t){return t.dy+m+t.fontSize*(\"bottom\"===F?1:-.5)},p=function(t){return x(t)&&0!==t&&180!==t?0>t*b?\"end\":\"start\":\"middle\"}):(b=\"right\"===F?1:-1,d=function(t){return t.dy+t.fontSize/2-D*b},f=function(t){return t.dx+r+(N+P+(90===Math.abs(c.tickangle)?t.fontSize/2:0))*b},p=function(t){return x(t)&&90===Math.abs(t)?\"middle\":\"right\"===F?\"start\":\"end\"});var k=0,M=0,L=[];u.enter().append(\"g\").classed(E,1).append(\"text\").attr(\"text-anchor\",\"middle\").each(function(e){var n=y.select(this),r=t._promises.length;n.call(A.setPosition,f(e),d(e)).call(A.font,e.font,e.fontSize,e.fontColor).text(e.text).call(w.convertToTspans),r=t._promises[r],r?L.push(t._promises.pop().then(function(){a(n,c.tickangle)})):a(n,c.tickangle)}),u.exit().remove(),u.each(function(t){k=Math.max(k,t.fontSize)}),a(u,c._lastangle||c.tickangle);var T=_.syncOrAsync([o,l,s]);return T&&T.then&&t._promises.push(T),T}function i(e){if(!n){var r,a,o,i,l=T.getFromId(t,e),s=y.select(t).selectAll(\"g.\"+e+\"tick\"),c={selection:s,side:l.side},f=e.charAt(0),d=t._fullLayout._size,h=1.5,p=l.titlefont.size;if(s.size()){var g=y.select(s.node().parentNode).attr(\"transform\").match(/translate\\(([-\\.\\d]+),([-\\.\\d]+)\\)/);g&&(c.offsetLeft=+g[1],c.offsetTop=+g[2])}\"x\"===f?(a=\"free\"===l.anchor?{_offset:d.t+(1-(l.position||0))*d.h,_length:0}:T.getFromId(t,l.anchor),o=l._offset+l._length/2,i=a._offset+(\"top\"===l.side?-10-p*(h+(l.showticklabels?1:0)):a._length+10+p*(h+(l.showticklabels?1.5:.5))),l.rangeslider&&l.rangeslider.visible&&l._boundingBox&&(i+=(u.height-u.margin.b-u.margin.t)*l.rangeslider.thickness+l._boundingBox.height),c.side||(c.side=\"bottom\")):(a=\"free\"===l.anchor?{_offset:d.l+(l.position||0)*d.w,_length:0}:T.getFromId(t,l.anchor),i=l._offset+l._length/2,o=a._offset+(\"right\"===l.side?a._length+10+p*(h+(l.showticklabels?1:.5)):-10-p*(h+(l.showticklabels?.5:0))),r={rotate:\"-90\",offset:0},c.side||(c.side=\"left\")),k.draw(t,e+\"title\",{propContainer:l,propName:l._name+\".title\",dfltName:f.toUpperCase()+\" axis\",avoid:c,transform:r,attributes:{x:o,y:i,\"text-anchor\":\"middle\"}})}}function l(t,e){return t.visible!==!0||t.xaxis+t.yaxis!==e?!1:b.Plots.traceIs(t,\"bar\")&&t.orientation==={x:\"h\",y:\"v\"}[v]?!0:t.fill&&t.fill.charAt(t.fill.length-1)===v}function s(e,n,a){var o=e.gridlayer,i=e.zerolinelayer,s=e[\"hidegrid\"+v]?[]:H,u=c._gridpath||\"M0,0\"+(\"x\"===v?\"v\":\"h\")+n._length,f=o.selectAll(\"path.\"+C).data(c.showgrid===!1?[]:s,S);if(f.enter().append(\"path\").classed(C,1).classed(\"crisp\",1).attr(\"d\",u).each(function(t){c.zeroline&&(\"linear\"===c.type||\"-\"===c.type)&&Math.abs(t.x)<c.dtick/100&&y.select(this).remove()}),f.attr(\"transform\",h).call(M.stroke,c.gridcolor||\"#ddd\").style(\"stroke-width\",I+\"px\"),f.exit().remove(),i){for(var d=!1,p=0;p<t._fullData.length;p++)if(l(t._fullData[p],a)){d=!0;break}var g=c.range[0]*c.range[1]<=0&&c.zeroline&&(\"linear\"===c.type||\"-\"===c.type)&&s.length&&(d||r({x:0})||!c.showline),m=i.selectAll(\"path.\"+O).data(g?[{x:0}]:[]);m.enter().append(\"path\").classed(O,1).classed(\"zl\",1).classed(\"crisp\",1).attr(\"d\",u),m.attr(\"transform\",h).call(M.stroke,c.zerolinecolor||M.defaultLine).style(\"stroke-width\",R+\"px\"),m.exit().remove()}}var c,u=t._fullLayout,f=!1;if(\"object\"==typeof e)c=e,e=c._id,f=!0;else if(c=L.getFromId(t,e),\"redraw\"===e&&u._paper.selectAll(\"g.subplot\").each(function(t){var e=u._plots[t],n=e.x(),r=e.y();e.xaxislayer.selectAll(\".\"+n._id+\"tick\").remove(),e.yaxislayer.selectAll(\".\"+r._id+\"tick\").remove(),e.gridlayer.selectAll(\"path\").remove(),e.zerolinelayer.selectAll(\"path\").remove()}),!e||\"redraw\"===e)return _.syncOrAsync(L.list(t,\"\",!0).map(function(n){return function(){if(n._id){var r=L.doTicks(t,n._id);return\"redraw\"===e&&(n._r=n.range.slice()),r}}}));c.tickformat||(-1===[\"none\",\"e\",\"E\",\"power\",\"SI\",\"B\"].indexOf(c.exponentformat)&&(c.exponentformat=\"e\"),-1===[\"all\",\"first\",\"last\",\"none\"].indexOf(c.showexponent)&&(c.showexponent=\"all\")),c.range=[+c.range[0],+c.range[1]],c.setScale();var d,h,p,g,v=e.charAt(0),m=L.counterLetter(e),z=L.calcTicks(c),S=function(t){return t.text+t.x+c.mirror},E=e+\"tick\",C=e+\"grid\",O=e+\"zl\",P=(c.linewidth||1)/2,N=(\"outside\"===c.ticks?c.ticklen:1)+(c.linewidth||0),D=0,I=A.crispRound(t,c.gridwidth,1),R=A.crispRound(t,c.zerolinewidth,I),j=A.crispRound(t,c.tickwidth,1);if(c._counterangle&&\"outside\"===c.ticks){var q=c._counterangle*Math.PI/180;N=c.ticklen*Math.cos(q)+(c.linewidth||0),D=c.ticklen*Math.sin(q)}if(\"x\"===v)d=[\"bottom\",\"top\"],h=function(t){return\"translate(\"+c.l2p(t.x)+\",0)\"},p=function(t,e){if(c._counterangle){var n=c._counterangle*Math.PI/180;return\"M0,\"+t+\"l\"+Math.sin(n)*e+\",\"+Math.cos(n)*e}return\"M0,\"+t+\"v\"+e};else{if(\"y\"!==v)return void _.warn(\"Unrecognized doTicks axis:\",e);d=[\"left\",\"right\"],h=function(t){return\"translate(0,\"+c.l2p(t.x)+\")\"},p=function(t,e){if(c._counterangle){var n=c._counterangle*Math.PI/180;return\"M\"+t+\",0l\"+Math.cos(n)*e+\",\"+-Math.sin(n)*e}return\"M\"+t+\",0h\"+e}}var F=c.side||d[0],B=[-1,1,F===d[1]?1:-1];\"inside\"!==c.ticks==(\"x\"===v)&&(B=B.map(function(t){return-t}));var H=z.filter(r);if(f){if(a(c._axislayer,p(c._pos+P*B[2],B[2]*c.ticklen)),c._counteraxis){var V={gridlayer:c._gridlayer,zerolinelayer:c._zerolinelayer};s(V,c._counteraxis)}return o(c._axislayer,c._pos)}var Z=L.getSubplots(t,c).map(function(t){var e=u._plots[t];if(u._has(\"cartesian\")){var n=e[v+\"axislayer\"],r=c._linepositions[t]||[],i=e[m](),l=i._id===c.anchor,f=[!1,!1,!1],h=\"\";if(\"allticks\"===c.mirror?f=[!0,!0,!1]:l&&(\"ticks\"===c.mirror?f=[!0,!0,!1]:f[d.indexOf(F)]=!0),c.mirrors)for(g=0;2>g;g++){var y=c.mirrors[i._id+d[g]];\"ticks\"!==y&&\"labels\"!==y||(f[g]=!0)}return void 0!==r[2]&&(f[2]=!0),f.forEach(function(t,e){var n=r[e],a=B[e];t&&x(n)&&(h+=p(n+P*a,a*c.ticklen))}),a(n,h),s(e,i,t),o(n,r[3])}}).filter(function(t){return t&&t.then});return Z.length?Promise.all(Z):0},L.swap=function(t,e){for(var n=h(t,e),r=0;r<n.length;r++)g(t,n[r].x,n[r].y)}},{\"../../components/color\":18,\"../../components/drawing\":41,\"../../components/titles\":81,\"../../lib\":89,\"../../lib/svg_text_utils\":100,\"../../plotly\":107,\"./axis_ids\":112,\"./layout_attributes\":119,\"./layout_defaults\":120,\"./set_convert\":124,d3:9,\"fast-isnumeric\":11}],111:[function(t,e,n){\"use strict\";function r(t,e){if(\"-\"===t.type){var n=t._id,r=n.charAt(0);-1!==n.indexOf(\"scene\")&&(n=r);var s=l(e,n,r);if(s){if(\"histogram\"===s.type&&r==={v:\"y\",h:\"x\"}[s.orientation||\"v\"])return void(t.type=\"linear\");if(o(s,r)){for(var c,u=a(s),f=[],d=0;d<e.length;d++)c=e[d],p.traceIs(c,\"box\")&&(c[r+\"axis\"]||r)===n&&(void 0!==c[u]?f.push(c[u][0]):void 0!==c.name?f.push(c.name):f.push(\"text\"));t.type=i(f)}else t.type=i(s[r]||[s[r+\"0\"]])}}}function a(t){return{v:\"x\",h:\"y\"}[t.orientation||\"v\"]}function o(t,e){var n=a(t);return p.traceIs(t,\"box\")&&e===n&&void 0===t[n]&&void 0===t[n+\"0\"]}function i(t){return c(t)?\"date\":u(t)?\"category\":s(t)?\"linear\":\"-\"}function l(t,e,n){for(var r=0;r<t.length;r++){var a=t[r];if((a[n+\"axis\"]||n)===e){if(o(a,n))return a;if((a[n]||[]).length||a[n+\"0\"])return a}}}function s(t){if(!t)return!1;for(var e=0;e<t.length;e++)if(f(t[e]))return!0;return!1}function c(t){for(var e,n=0,r=0,a=Math.max(1,(t.length-1)/1e3),o=0;o<t.length;o+=a)e=t[Math.round(o)],h.isDateTime(e)&&(n+=1),f(e)&&(r+=1);return n>2*r}function u(t){for(var e,n=Math.max(1,(t.length-1)/1e3),r=0,a=0,o=0;o<t.length;o+=n)e=k(t[Math.round(o)]),f(e)?r++:\"string\"==typeof e&&\"\"!==e&&\"None\"!==e&&a++;return a>2*r}var f=t(\"fast-isnumeric\"),d=t(\"tinycolor2\").mix,h=t(\"../../lib\"),p=t(\"../plots\"),g=t(\"../../components/color/attributes\").lightFraction,v=t(\"./layout_attributes\"),m=t(\"./tick_value_defaults\"),y=t(\"./tick_mark_defaults\"),x=t(\"./tick_label_defaults\"),b=t(\"./category_order_defaults\"),_=t(\"./set_convert\"),w=t(\"./ordered_categories\"),k=t(\"./clean_datum\"),M=t(\"./axis_ids\");e.exports=function(t,e,n,a){function o(n,r){return h.coerce2(t,e,v,n,r)}var i=a.letter,l=a.font||{},s=\"Click to enter \"+(a.title||i.toUpperCase()+\" axis\")+\" title\";a.name&&(e._name=a.name,e._id=M.name2id(a.name));var c=n(\"type\");\"-\"===c&&(r(e,a.data),\"-\"===e.type?e.type=\"linear\":c=t.type=e.type),_(e);var u=n(\"color\"),p=u===t.color?u:l.color;n(\"title\",s),h.coerceFont(n,\"titlefont\",{family:l.family,size:Math.round(1.2*l.size),color:p});var k=2===(t.range||[]).length&&" -, -"f(t.range[0])&&f(t.range[1]),A=n(\"autorange\",!k);A&&n(\"rangemode\");var L=n(\"range\",[-1,\"x\"===i?6:4]);L[0]===L[1]&&(e.range=[L[0]-1,L[0]+1]),h.noneOrAll(t.range,e.range,[0,1]),n(\"fixedrange\"),m(t,e,n,c),x(t,e,n,c,a),y(t,e,n,a),b(t,e,n);var T=o(\"linecolor\",u),z=o(\"linewidth\"),S=n(\"showline\",!!T||!!z);S||(delete e.linecolor,delete e.linewidth),(S||e.ticks)&&n(\"mirror\");var E=o(\"gridcolor\",d(u,a.bgColor,g).toRgbString()),C=o(\"gridwidth\"),O=n(\"showgrid\",a.showGrid||!!E||!!C);O||(delete e.gridcolor,delete e.gridwidth);var P=o(\"zerolinecolor\",u),N=o(\"zerolinewidth\"),D=n(\"zeroline\",a.showGrid||!!P||!!N);return D||(delete e.zerolinecolor,delete e.zerolinewidth),e._initialCategories=\"category\"===c?w(i,e.categoryorder,e.categoryarray,a.data):[],e}},{\"../../components/color/attributes\":17,\"../../lib\":89,\"../plots\":130,\"./axis_ids\":112,\"./category_order_defaults\":113,\"./clean_datum\":114,\"./layout_attributes\":119,\"./ordered_categories\":121,\"./set_convert\":124,\"./tick_label_defaults\":125,\"./tick_mark_defaults\":126,\"./tick_value_defaults\":127,\"fast-isnumeric\":11,tinycolor2:13}],112:[function(t,e,n){\"use strict\";function r(t,e,n){function r(t,n){for(var r=Object.keys(t),a=/^[xyz]axis[0-9]*/,o=[],i=0;i<r.length;i++){var l=r[i];e&&l.charAt(0)!==e||a.test(l)&&o.push(n+l)}return o.sort()}var o=t._fullLayout;if(!o)return[];var i=r(o,\"\");if(n)return i;for(var l=a.getSubplotIds(o,\"gl3d\")||[],s=0;s<l.length;s++){var c=l[s];i=i.concat(r(o[c],c+\".\"))}return i}var a=t(\"../plots\"),o=t(\"../../lib\"),i=t(\"./constants\");n.id2name=function(t){if(\"string\"==typeof t&&t.match(i.AX_ID_PATTERN)){var e=t.substr(1);return\"1\"===e&&(e=\"\"),t.charAt(0)+\"axis\"+e}},n.name2id=function(t){if(t.match(i.AX_NAME_PATTERN)){var e=t.substr(5);return\"1\"===e&&(e=\"\"),t.charAt(0)+e}},n.cleanId=function(t,e){if(t.match(i.AX_ID_PATTERN)&&(!e||t.charAt(0)===e)){var n=t.substr(1).replace(/^0+/,\"\");return\"1\"===n&&(n=\"\"),t.charAt(0)+n}},n.list=function(t,e,n){return r(t,e,n).map(function(e){return o.nestedProperty(t._fullLayout,e).get();\n" -, -"})},n.listIds=function(t,e){return r(t,e,!0).map(n.name2id)},n.getFromId=function(t,e,r){var a=t._fullLayout;return\"x\"===r?e=e.replace(/y[0-9]*/,\"\"):\"y\"===r&&(e=e.replace(/x[0-9]*/,\"\")),a[n.id2name(e)]},n.getFromTrace=function(t,e,r){var o=t._fullLayout,i=null;if(a.traceIs(e,\"gl3d\")){var l=e.scene;\"scene\"===l.substr(0,5)&&(i=o[l][r+\"axis\"])}else i=n.getFromId(t,e[r+\"axis\"]||r);return i}},{\"../../lib\":89,\"../plots\":130,\"./constants\":115}],113:[function(t,e,n){\"use strict\";e.exports=function(t,e,n){if(\"category\"===e.type){var r,a=t.categoryarray,o=Array.isArray(a)&&a.length>0;o&&(r=\"array\");var i=n(\"categoryorder\",r);\"array\"===i&&n(\"categoryarray\"),o||\"array\"!==i||(e.categoryorder=\"trace\")}}},{}],114:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\"),a=t(\"../../lib\");e.exports=function(t){try{if(\"object\"==typeof t&&null!==t&&t.getTime)return a.ms2DateTime(t);if(\"string\"!=typeof t&&!r(t))return\"\";t=t.toString().replace(/['\"%,$# ]/g,\"\")}catch(e){a.error(e,t)}return t}},{\"../../lib\":89,\"fast-isnumeric\":11}],115:[function(t,e,n){\"use strict\";e.exports={idRegex:{x:/^x([2-9]|[1-9][0-9]+)?$/,y:/^y([2-9]|[1-9][0-9]+)?$/},attrRegex:{x:/^xaxis([2-9]|[1-9][0-9]+)?$/,y:/^yaxis([2-9]|[1-9][0-9]+)?$/},BADNUM:void 0,xAxisMatch:/^xaxis[0-9]*$/,yAxisMatch:/^yaxis[0-9]*$/,AX_ID_PATTERN:/^[xyz][0-9]*$/,AX_NAME_PATTERN:/^[xyz]axis[0-9]*$/,DBLCLICKDELAY:300,MINDRAG:8,MINSELECT:12,MINZOOM:20,DRAGGERSIZE:20,MAXDIST:20,YANGLE:60,HOVERARROWSIZE:6,HOVERTEXTPAD:3,HOVERFONTSIZE:13,HOVERFONT:\"Arial, sans-serif\",HOVERMINTIME:50,BENDPX:1.5,REDRAWDELAY:50}},{}],116:[function(t,e,n){\"use strict\";function r(t,e){var n,r=t.range[e],a=Math.abs(r-t.range[1-e]);return\"date\"===t.type?u.ms2DateTime(r,a):\"log\"===t.type?(n=Math.ceil(Math.max(0,-Math.log(a)/Math.LN10))+3,l.format(\".\"+n+\"g\")(Math.pow(10,r))):(n=Math.floor(Math.log(Math.abs(r))/Math.LN10)-Math.floor(Math.log(a)/Math.LN10)+4,l.format(\".\"+String(n)+\"g\")(r))}function a(t,e){return t?\"nsew\"===t?\"pan\"===e?\"move\":\"crosshair\":t.toLowerCase()+\"-resize\":\"pointer\"}function o(t){l.select(t).selectAll(\".zoombox,.js-zoombox-backdrop,.js-zoombox-menu,.zoombox-corners\").remove()}function i(t){var e=[\"lasso\",\"select\"];return-1!==e.indexOf(t)}var l=t(\"d3\"),s=t(\"tinycolor2\"),c=t(\"../../plotly\"),u=t(\"../../lib\"),f=t(\"../../lib/svg_text_utils\"),d=t(\"../../components/color\"),h=t(\"../../components/drawing\"),p=t(\"../../lib/setcursor\"),g=t(\"../../components/dragelement\"),v=t(\"./axes\"),m=t(\"./select\"),y=t(\"./constants\"),x=!0;e.exports=function(t,e,n,l,b,_,w,k){function M(t,e){for(var n=0;n<t.length;n++)if(!t[n].fixedrange)return e;return\"\"}function A(t){t[0]=Number(t[0]),t[1]=Number(t[1])}function L(e,n,r){var a=nt.getBoundingClientRect();at=n-a.left,ot=r-a.top,it={l:at,r:at,w:0,t:ot,b:ot,h:0},lt=t._hmpixcount?t._hmlumcount/t._hmpixcount:s(t._fullLayout.plot_bgcolor).getLuminance(),st=\"M0,0H\"+H+\"V\"+V+\"H0V0\",ct=!1,ut=\"xy\",ft=ht.append(\"path\").attr(\"class\",\"zoombox\").style({fill:lt>.2?\"rgba(0,0,0,0)\":\"rgba(255,255,255,0)\",\"stroke-width\":0}).attr(\"transform\",\"translate(\"+pt+\", \"+gt+\")\").attr(\"d\",st+\"Z\"),dt=ht.append(\"path\").attr(\"class\",\"zoombox-corners\").style({fill:d.background,stroke:d.defaultLine,\"stroke-width\":1,opacity:0}).attr(\"transform\",\"translate(\"+pt+\", \"+gt+\")\").attr(\"d\",\"M0,0Z\"),T();for(var o=0;o<Q.length;o++)A(Q[o].range)}function T(){ht.selectAll(\".select-outline\").remove()}function z(t,e){var n=Math.max(0,Math.min(H,t+at)),r=Math.max(0,Math.min(V,e+ot)),a=Math.abs(n-at),o=Math.abs(r-ot),i=Math.floor(Math.min(o,a,Y)/2);it.l=Math.min(at,n),it.r=Math.max(at,n),it.t=Math.min(ot,r),it.b=Math.max(ot,r),!J||o<Math.min(Math.max(.6*a,Z),Y)?Z>a?(ut=\"\",it.r=it.l,it.t=it.b,dt.attr(\"d\",\"M0,0Z\")):(it.t=0,it.b=V,ut=\"x\",dt.attr(\"d\",\"M\"+(it.l-.5)+\",\"+(ot-Y-.5)+\"h-3v\"+(2*Y+1)+\"h3ZM\"+(it.r+.5)+\",\"+(ot-Y-.5)+\"h3v\"+(2*Y+1)+\"h-3Z\")):!W||a<Math.min(.6*o,Y)?(it.l=0,it.r=H,ut=\"y\",dt.attr(\"d\",\"M\"+(at-Y-.5)+\",\"+(it.t-.5)+\"v-3h\"+(2*Y+1)+\"v3ZM\"+(at-Y-.5)+\",\"+(it.b+.5)+\"v3h\"+(2*Y+1)+\"v-3Z\")):(ut=\"xy\",dt.attr(\"d\",\"M\"+(it.l-3.5)+\",\"+(it.t-.5+i)+\"h3v\"+-i+\"h\"+i+\"v-3h-\"+(i+3)+\"ZM\"+(it.r+3.5)+\",\"+(it.t-.5+i)+\"h-3v\"+-i+\"h\"+-i+\"v-3h\"+(i+3)+\"ZM\"+(it.r+3.5)+\",\"+(it.b+.5-i)+\"h-3v\"+i+\"h\"+-i+\"v3h\"+(i+3)+\"ZM\"+(it.l-3.5)+\",\"+(it.b+.5-i)+\"h3v\"+i+\"h\"+i+\"v3h-\"+(i+3)+\"Z\")),it.w=it.r-it.l,it.h=it.b-it.t,ft.attr(\"d\",st+\"M\"+it.l+\",\"+it.t+\"v\"+it.h+\"h\"+it.w+\"v-\"+it.h+\"h-\"+it.w+\"Z\"),ct||(ft.transition().style(\"fill\",lt>.2?\"rgba(0,0,0,0.4)\":\"rgba(255,255,255,0.3)\").duration(200),dt.transition().style(\"opacity\",1).duration(200),ct=!0)}function S(t,e,n){var r,a,o;for(r=0;r<t.length;r++)a=t[r],a.fixedrange||(o=a.range,a.range=[o[0]+(o[1]-o[0])*e,o[0]+(o[1]-o[0])*n])}function E(e,n){return Math.min(it.h,it.w)<2*Z?(2===n&&D(),o(t)):(\"xy\"!==ut&&\"x\"!==ut||S(F,it.l/H,it.r/H),\"xy\"!==ut&&\"y\"!==ut||S(B,(V-it.b)/V,(V-it.t)/V),o(t),I(ut),void(x&&t.data&&t._context.showTips&&(u.notifier(\"Double-click to<br>zoom back out\",\"long\"),x=!1)))}function C(e,n){var a=1===(w+k).length;if(e)I();else if(2!==n||a){if(1===n&&a){var o=w?B[0]:F[0],i=\"s\"===w||\"w\"===k?0:1,l=o._name+\".range[\"+i+\"]\",s=r(o,i),u=\"left\",d=\"middle\";if(o.fixedrange)return;w?(d=\"n\"===w?\"top\":\"bottom\",\"right\"===o.side&&(u=\"right\")):\"e\"===k&&(u=\"right\"),et.call(f.makeEditable,null,{immediate:!0,background:j.paper_bgcolor,text:String(s),fill:o.tickfont?o.tickfont.color:\"#444\",horizontalAlign:u,verticalAlign:d}).on(\"edit\",function(e){var n=\"category\"===o.type?o.c2l(e):o.d2l(e);void 0!==n&&c.relayout(t,l,n)})}}else D()}function O(e){function n(t,e,n){if(!t.fixedrange){A(t.range);var r=t.range,a=r[0]+(r[1]-r[0])*e;t.range=[a+(r[0]-a)*n,a+(r[1]-a)*n]}}if(t._context.scrollZoom||j._enablescrollzoom){var r=t.querySelector(\".plotly\");if(!(r.scrollHeight-r.clientHeight>10||r.scrollWidth-r.clientWidth>10)){clearTimeout(mt);var a=-e.deltaY;if(isFinite(a)||(a=e.wheelDelta/10),!isFinite(a))return void u.log(\"Did not find wheel motion attributes: \",e);var o,i=Math.exp(-Math.min(Math.max(a,-20),20)/100),l=xt.draglayer.select(\".nsewdrag\").node().getBoundingClientRect(),s=(e.clientX-l.left)/l.width,c=vt[0]+vt[2]*s,f=(l.bottom-e.clientY)/l.height,d=vt[1]+vt[3]*(1-f);if(k){for(o=0;o<F.length;o++)n(F[o],s,i);vt[2]*=i,vt[0]=c-vt[2]*s}if(w){for(o=0;o<B.length;o++)n(B[o],f,i);vt[3]*=i,vt[1]=d-vt[3]*(1-f)}return R(vt),N(w,k),mt=setTimeout(function(){vt=[0,0,H,V],I()},yt),u.pauseEvent(e)}}}function P(t,e){function n(t,e){for(var n=0;n<t.length;n++){var r=t[n];r.fixedrange||(r.range=[r._r[0]-e/r._m,r._r[1]-e/r._m])}}function r(t){return 1-(t>=0?Math.min(t,.9):1/(1/Math.max(t,-.3)+3.222))}function a(t,e,n){for(var a=1-e,o=0,i=0;i<t.length;i++){var l=t[i];l.fixedrange||(o=i,l.range[e]=l._r[a]+(l._r[e]-l._r[a])/r(n/l._length))}return t[o]._length*(t[o]._r[e]-t[o].range[e])/(t[o]._r[e]-t[o]._r[a])}return\"ew\"===W||\"ns\"===J?(W&&n(F,t),J&&n(B,e),R([W?-t:0,J?-e:0,H,V]),void N(J,W)):(\"w\"===W?t=a(F,0,t):\"e\"===W?t=a(F,1,-t):W||(t=0),\"n\"===J?e=a(B,1,e):\"s\"===J?e=a(B,0,-e):J||(e=0),R([\"w\"===W?t:0,\"n\"===J?e:0,H-t,V-e]),void N(J,W))}function N(e,n){function r(t){for(o=0;o<t.length;o++)t[o].fixedrange||i.push(t[o]._id)}function a(r,a){var l;for(o=0;o<r.length;o++)l=r[o],(n&&-1!==i.indexOf(l.xref)||e&&-1!==i.indexOf(l.yref))&&a.draw(t,o)}var o,i=[];for(n&&r(F),e&&r(B),o=0;o<i.length;o++)v.doTicks(t,i[o],!0);a(j.annotations||[],c.Annotations),a(j.shapes||[],c.Shapes),a(j.images||[],c.Images)}function D(){var e,n,r,a=t._context.doubleClick,o=(W?F:[]).concat(J?B:[]),i={};if(\"autosize\"===a)for(n=0;n<o.length;n++)e=o[n],e.fixedrange||(i[e._name+\".autorange\"]=!0);else if(\"reset\"===a)for(n=0;n<o.length;n++)e=o[n],e._rangeInitial?(r=e._rangeInitial.slice(),i[e._name+\".range[0]\"]=r[0],i[e._name+\".range[1]\"]=r[1]):i[e._name+\".autorange\"]=!0;else if(\"reset+autosize\"===a)for(n=0;n<o.length;n++)e=o[n],e.fixedrange||(void 0===e._rangeInitial||e.range[0]===e._rangeInitial[0]&&e.range[1]===e._rangeInitial[1]?i[e._name+\".autorange\"]=!0:(r=e._rangeInitial.slice(),i[e._name+\".range[0]\"]=r[0],i[e._name+\".range[1]\"]=r[1]));t.emit(\"plotly_doubleclick\",null),c.relayout(t,i)}function I(e){for(var n={},r=0;r<Q.length;r++){var a=Q[r];e&&-1===e.indexOf(a._id.charAt(0))||(a._r[0]!==a.range[0]&&(n[a._name+\".range[0]\"]=a.range[0]),a._r[1]!==a.range[1]&&(n[a._name+\".range[1]\"]=a.range[1]),a.range=a._r.slice())}R([0,0,H,V]),c.relayout(t,n)}function R(t){for(var e=j._plots,n=Object.keys(e),r=0;r<n.length;r++){var a=e[n[r]],o=a.x(),i=a.y(),l=k&&-1!==F.indexOf(o)&&!o.fixedrange,s=w&&-1!==B.indexOf(i)&&!i.fixedrange,c=l?o._length/t[2]:1,f=s?i._length/t[3]:1,d=l?t[0]:0,h=s?t[1]:0,p=l?t[0]/t[2]*o._length:0,g=s?t[1]/t[3]*i._length:0,v=o._offset-p,m=i._offset-g;j._defs.selectAll(\"#\"+a.clipId).call(u.setTranslate,d,h).call(u.setScale,1/c,1/f),a.plot.call(u.setTranslate,v,m).call(u.setScale,c,f).selectAll(\".points\").selectAll(\".point\").call(u.setPointGroupScale,1/c,1/f)}}for(var j=t._fullLayout,q=[e].concat(w&&k?e.overlays:[]),F=[e.x()],B=[e.y()],H=F[0]._length,V=B[0]._length,Z=y.MINDRAG,Y=y.MINZOOM,U=w+k===\"nsew\",X=1;X<q.length;X++){var G=q[X].x(),$=q[X].y();-1===F.indexOf(G)&&F.push(G),-1===B.indexOf($)&&B.push($)}var Q=F.concat(B),W=M(F,k),J=M(B,w),K=a(J+W,j.dragmode),tt=w+k+\"drag\",et=e.draglayer.selectAll(\".\"+tt).data([0]);et.enter().append(\"rect\").classed(\"drag\",!0).classed(tt,!0).style({fill:\"transparent\",\"stroke-width\":0}).attr(\"data-subplot\",e.id),et.call(h.setRect,n,l,b,_).call(p,K);var nt=et.node();if(!J&&!W&&!i(j.dragmode))return nt.onmousedown=null,nt.style.pointerEvents=U?\"all\":\"none\",nt;var rt={element:nt,gd:t,plotinfo:e,xaxes:F,yaxes:B,doubleclick:D,prepFn:function(e,n,r){var a=t._fullLayout.dragmode;U?e.shiftKey&&(a=\"pan\"===a?\"zoom\":\"pan\"):a=\"pan\",\"lasso\"===a?rt.minDrag=1:rt.minDrag=void 0,\"zoom\"===a?(rt.moveFn=z,rt.doneFn=E,L(e,n,r)):\"pan\"===a?(rt.moveFn=P,rt.doneFn=C,T()):i(a)&&m(e,n,r,rt,a)}};g.init(rt);var at,ot,it,lt,st,ct,ut,ft,dt,ht=t._fullLayout._zoomlayer,pt=e.x()._offset,gt=e.y()._offset,vt=[0,0,H,V],mt=null,yt=y.REDRAWDELAY,xt=e.mainplot?j._plots[e.mainplot]:e;return w.length*k.length!==1&&(void 0!==nt.onwheel?nt.onwheel=O:void 0!==nt.onmousewheel&&(nt.onmousewheel=" -, -"O)),nt}},{\"../../components/color\":18,\"../../components/dragelement\":39,\"../../components/drawing\":41,\"../../lib\":89,\"../../lib/setcursor\":98,\"../../lib/svg_text_utils\":100,\"../../plotly\":107,\"./axes\":110,\"./constants\":115,\"./select\":123,d3:9,tinycolor2:13}],117:[function(t,e,n){\"use strict\";function r(t,e){for(var n=[],r=t.length;r>0;r--)n.push(e);return n}function a(t,e){for(var n=[],r=0;r<t.length;r++)n.push(t[r].p2c(e));return n}function o(t,e){return function(n){var r=t(n),a=e(n);return Math.sqrt(r*r+a*a)}}function i(t,e,n){if(\"pie\"===n)return void t.emit(\"plotly_hover\",{points:[e]});n||(n=\"xy\");var o=Array.isArray(n)?n:[n],i=t._fullLayout,h=i._plots||[],p=h[n];if(p){var y=p.overlays.map(function(t){return t.id});o=o.concat(y)}for(var b=o.length,M=new Array(b),A=new Array(b),L=0;b>L;L++){var T=o[L],z=h[T];if(z)M[L]=w.getFromId(t,z.xaxis._id),A[L]=w.getFromId(t,z.yaxis._id);else{var S=i[T]._subplot;M[L]=S.xaxis,A[L]=S.yaxis}}var E=e.hovermode||i.hovermode;if(-1===[\"x\",\"y\",\"closest\"].indexOf(E)||!t.calcdata||t.querySelector(\".zoombox\")||t._dragging)return _.unhoverRaw(t,e);var C,O,P,N,D,I,R,j,q,F,B,H,V=[],Z=[];if(Array.isArray(e))for(E=\"array\",P=0;P<e.length;P++)D=t.calcdata[e[P].curveNumber||0],Z.push(D);else{for(N=0;N<t.calcdata.length;N++)D=t.calcdata[N],I=D[0].trace,-1!==o.indexOf(l(I))&&Z.push(D);var Y,U;if(e.target&&\"clientX\"in e&&\"clientY\"in e){if(m.triggerHandler(t,\"plotly_beforehover\",e)===!1)return;var X=e.target.getBoundingClientRect();if(Y=e.clientX-X.left,U=e.clientY-X.top,0>Y||Y>X.width||0>U||U>X.height)return _.unhoverRaw(t,e)}else Y=\"xpx\"in e?e.xpx:M[0]._length/2,U=\"ypx\"in e?e.ypx:A[0]._length/2;if(C=\"xval\"in e?r(o,e.xval):a(M,Y),O=\"yval\"in e?r(o,e.yval):a(A,U),!g(C[0])||!g(O[0]))return v.warn(\"Plotly.Fx.hover failed\",e,t),_.unhoverRaw(t,e)}var G=1/0;for(N=0;N<Z.length;N++)if(D=Z[N],D&&D[0]&&D[0].trace&&D[0].trace.visible===!0){if(I=D[0].trace,R=o.indexOf(l(I)),j=E,B={cd:D,trace:I,xa:M[R],ya:A[R],name:t.data.length>1||-1!==I.hoverinfo.indexOf(\"name\")?I.name:void 0,index:!1,distance:Math.min(G,k.MAXDIST),color:x.defaultLine,x0:void 0,x1:void 0,y0:void 0,y1:void 0,xLabelVal:void 0,yLabelVal:void 0,zLabelVal:void 0,text:void 0},H=V.length,\"array\"===j){var $=e[N];\"pointNumber\"in $?(B.index=$.pointNumber,j=\"closest\"):(j=\"\",\"xval\"in $&&(q=$.xval,j=\"x\"),\"yval\"in $&&(F=$.yval,j=j?\"closest\":\"y\"))}else q=C[R],F=O[R];if(I._module&&I._module.hoverPoints){var Q=I._module.hoverPoints(B,q,F,j);if(Q)for(var W,J=0;J<Q.length;J++)W=Q[J],g(W.x0)&&g(W.y0)&&V.push(s(W,E))}else v.log(\"Unrecognized trace type in hover:\",I);\"closest\"===E&&V.length>H&&(V.splice(0,H),G=V[0].distance)}if(0===V.length)return _.unhoverRaw(t,e);var K=\"y\"===E&&Z.length>1;V.sort(function(t,e){return t.distance-e.distance});var tt=x.combine(i.plot_bgcolor||x.background,i.paper_bgcolor),et={hovermode:E,rotateLabels:K,bgColor:tt,container:i._hoverlayer,outerContainer:i._paperdiv},nt=c(V,et);u(V,K?\"xa\":\"ya\"),f(nt,K);var rt=t._hoverdata,at=[];for(P=0;P<V.length;P++){var ot=V[P],it={data:ot.trace._input,fullData:ot.trace,curveNumber:ot.trace.index,pointNumber:ot.index,x:ot.xVal,y:ot.yVal,xaxis:ot.xa,yaxis:ot.ya};void 0!==ot.zLabelVal&&(it.z=ot.zLabelVal),at.push(it)}t._hoverdata=at,d(t,e,rt)&&(rt&&t.emit(\"plotly_unhover\",{points:rt}),t.emit(\"plotly_hover\",{points:t._hoverdata,xaxes:M,yaxes:A,xvals:C,yvals:O}))}function l(t){return t.subplot||t.xaxis+t.yaxis}function s(t,e){t.posref=\"y\"===e?(t.x0+t.x1)/2:(t.y0+t.y1)/2,t.x0=v.constrain(t.x0,0,t.xa._length),t.x1=v.constrain(t.x1,0,t.xa._length),t.y0=v.constrain(t.y0,0,t.ya._length),t.y1=v.constrain(t.y1,0,t.ya._length);var n;if(void 0!==t.xLabelVal){n=\"log\"===t.xa.type&&t.xLabelVal<=0;var r=w.tickText(t.xa,t.xa.c2l(n?-t.xLabelVal:t.xLabelVal),\"hover\");n?0===t.xLabelVal?t.xLabel=\"0\":t.xLabel=\"-\"+r.text:t.xLabel=r.text,t.xVal=t.xa.c2d(t.xLabelVal)}if(void 0!==t.yLabelVal){n=\"log\"===t.ya.type&&t.yLabelVal<=0;var a=w.tickText(t.ya,t.ya.c2l(n?-t.yLabelVal:t.yLabelVal),\"hover\");n?0===t.yLabelVal?t.yLabel=\"0\":t.yLabel=\"-\"+a.text:t.yLabel=a.text,t.yVal=t.ya.c2d(t.yLabelVal)}if(void 0!==t.zLabelVal&&(t.zLabel=String(t.zLabelVal)),!(isNaN(t.xerr)||\"log\"===t.xa.type&&t.xerr<=0)){var o=w.tickText(t.xa,t.xa.c2l(t.xerr),\"hover\").text;void 0!==t.xerrneg?t.xLabel+=\" +\"+o+\" / -\"+w.tickText(t.xa,t.xa.c2l(t.xerrneg),\"hover\").text:t.xLabel+=\" ± \"+o,\"x\"===e&&(t.distance+=1)}if(!(isNaN(t.yerr)||\"log\"===t.ya.type&&t.yerr<=0)){var i=w.tickText(t.ya,t.ya.c2l(t.yerr),\"hover\").text;void 0!==t.yerrneg?t.yLabel+=\" +\"+i+\" / -\"+w.tickText(t.ya,t.ya.c2l(t.yerrneg),\"hover\").text:t.yLabel+=\" ± \"+i,\"y\"===e&&(t.distance+=1)}var l=t.trace.hoverinfo;return\"all\"!==l&&(l=l.split(\"+\"),-1===l.indexOf(\"x\")&&(t.xLabel=void 0),-1===l.indexOf(\"y\")&&(t.yLabel=void 0),-1===l.indexOf(\"z\")&&(t.zLabel=void 0),-1===l.indexOf(\"text\")&&(t.text=void 0),-1===l.indexOf(\"name\")&&(t.name=void 0)),t}function c(t,e){var n,r,a=e.hovermode,o=e.rotateLabels,i=e.bgColor,l=e.container,s=e.outerContainer,c=t[0],u=c.xa,f=c.ya,d=\"y\"===a?\"yLabel\":\"xLabel\",g=c[d],v=(String(g)||\"\").split(\" \")[0],m=s.node().getBoundingClientRect(),_=m.top,w=m.width,M=m.height,A=c.distance<=k.MAXDIST&&(\"x\"===a||\"y\"===a);for(n=0;n<t.length;n++){r=t[n].trace.hoverinfo;var T=r.split(\"+\");if(-1===T.indexOf(\"all\")&&-1===T.indexOf(a)){A=!1;break}}var z=l.selectAll(\"g.axistext\").data(A?[0]:[]);z.enter().append(\"g\").classed(\"axistext\",!0),z.exit().remove(),z.each(function(){var e=h.select(this),n=e.selectAll(\"path\").data([0]),r=e.selectAll(\"text\").data([0]);n.enter().append(\"path\").style({fill:x.defaultLine,\"stroke-width\":\"1px\",stroke:x.background}),r.enter().append(\"text\").call(b.font,N,P,x.background).attr(\"data-notex\",1),r.text(g).call(y.convertToTspans).call(b.setPosition,0,0).selectAll(\"tspan.line\").call(b.setPosition,0,0),e.attr(\"transform\",\"\");var o=r.node().getBoundingClientRect();if(\"x\"===a){r.attr(\"text-anchor\",\"middle\").call(b.setPosition,0,\"top\"===u.side?_-o.bottom-C-O:_-o.top+C+O).selectAll(\"tspan.line\").attr({x:r.attr(\"x\"),y:r.attr(\"y\")});var i=\"top\"===u.side?\"-\":\"\";n.attr(\"d\",\"M0,0L\"+C+\",\"+i+C+\"H\"+(O+o.width/2)+\"v\"+i+(2*O+o.height)+\"H-\"+(O+o.width/2)+\"V\"+i+C+\"H-\"+C+\"Z\"),e.attr(\"transform\",\"translate(\"+(u._offset+(c.x0+c.x1)/2)+\",\"+(f._offset+(\"top\"===u.side?0:f._length))+\")\")}else{r.attr(\"text-anchor\",\"right\"===f.side?\"start\":\"end\").call(b.setPosition,(\"right\"===f.side?1:-1)*(O+C),_-o.top-o.height/2).selectAll(\"tspan.line\").attr({x:r.attr(\"x\"),y:r.attr(\"y\")});var l=\"right\"===f.side?\"\":\"-\";n.attr(\"d\",\"M0,0L\"+l+C+\",\"+C+\"V\"+(O+o.height/2)+\"h\"+l+(2*O+o.width)+\"V-\"+(O+o.height/2)+\"H\"+l+C+\"V-\"+C+\"Z\"),e.attr(\"transform\",\"translate(\"+(u._offset+(\"right\"===f.side?u._length:0))+\",\"+(f._offset+(c.y0+c.y1)/2)+\")\")}t=t.filter(function(t){return void 0!==t.zLabelVal||(t[d]||\"\").split(\" \")[0]===v})});var S=l.selectAll(\"g.hovertext\").data(t,function(t){return[t.trace.index,t.index,t.x0,t.y0,t.name,t.attr,t.xa,t.ya||\"\"].join(\",\")});return S.enter().append(\"g\").classed(\"hovertext\",!0).each(function(){var t=h.select(this);t.append(\"rect\").call(x.fill,x.addOpacity(i,.8)),t.append(\"text\").classed(\"name\",!0).call(b.font,N,P),t.append(\"path\").style(\"stroke-width\",\"1px\"),t.append(\"text\").classed(\"nums\",!0).call(b.font,N,P)}),S.exit().remove(),S.each(function(t){var e=h.select(this).attr(\"transform\",\"\"),n=\"\",r=\"\",l=x.opacity(t.color)?t.color:x.defaultLine,s=x.combine(l,i),c=p(s).getBrightness()>128?\"#000\":x.background;if(t.name&&void 0===t.zLabelVal){var u=document.createElement(\"p\");u.innerHTML=t.name,n=u.textContent||\"\",n.length>15&&(n=n.substr(0,12)+\"...\")}void 0!==t.extraText&&(r+=t.extraText),void 0!==t.zLabel?(void 0!==t.xLabel&&(r+=\"x: \"+t.xLabel+\"<br>\"),void 0!==t.yLabel&&(r+=\"y: \"+t.yLabel+\"<br>\"),r+=(r?\"z: \":\"\")+t.zLabel):A&&t[a+\"Label\"]===g?r=t[(\"x\"===a?\"y\":\"x\")+\"Label\"]||\"\":void 0===t.xLabel?void 0!==t.yLabel&&(r=t.yLabel):r=void 0===t.yLabel?t.xLabel:\"(\"+t.xLabel+\", \"+t.yLabel+\")\",t.text&&!Array.isArray(t.text)&&(r+=(r?\"<br>\":\"\")+t.text),\"\"===r&&(\"\"===n&&e.remove(),r=n);var f=e.select(\"text.nums\").style(\"fill\",c).call(b.setPosition,0,0).text(r).attr(\"data-notex\",1).call(y.convertToTspans);f.selectAll(\"tspan.line\").call(b.setPosition,0,0);var d=e.select(\"text.name\"),v=0;n&&n!==r?(d.style(\"fill\",s).text(n).call(b.setPosition,0,0).attr(\"data-notex\",1).call(y.convertToTspans),d.selectAll(\"tspan.line\").call(b.setPosition,0,0),v=d.node().getBoundingClientRect().width+2*O):(d.remove(),e.select(\"rect\").remove()),e.select(\"path\").style({fill:s,stroke:c});var m,k,T=f.node().getBoundingClientRect(),z=t.xa._offset+(t.x0+t.x1)/2,S=t.ya._offset+(t.y0+t.y1)/2,E=Math.abs(t.x1-t.x0),P=Math.abs(t.y1-t.y0),N=T.width+C+O+v;t.ty0=_-T.top,t.bx=T.width+2*O,t.by=T.height+2*O,t.anchor=\"start\",t.txwidth=T.width,t.tx2width=v,t.offset=0,o?(t.pos=z,m=M>=S+P/2+N,k=S-P/2-N>=0,\"top\"!==t.idealAlign&&m||!k?m?(S+=P/2,t.anchor=\"start\"):t.anchor=\"middle\":(S-=P/2,t.anchor=\"end\")):(t.pos=S,m=w>=z+E/2+N,k=z-E/2-N>=0,\"left\"!==t.idealAlign&&m||!k?m?(z+=E/2,t.anchor=\"start\"):t.anchor=\"middle\":(z-=E/2,t.anchor=\"end\")),f.attr(\"text-anchor\",t.anchor),v&&d.attr(\"text-anchor\",t.anchor),e.attr(\"transform\",\"translate(\"+z+\",\"+S+\")\"+(o?\"rotate(\"+L+\")\":\"\"))}),S}function u(t,e){function n(t){var e=t[0],n=t[t.length-1];if(a=e.pmin-e.pos-e.dp+e.size,o=n.pos+n.dp+n.size-e.pmax,a>.01){for(l=t.length-1;l>=0;l--)t[l].dp+=a;r=!1}if(!(.01>o)){if(-.01>a){for(l=t.length-1;l>=0;l--)t[l].dp-=o;r=!1}if(r){var c=0;for(i=0;i<t.length;i++)s=t[i],s.pos+s.dp+s.size>e.pmax&&c++;for(i=t.length-1;i>=0&&!(0>=c);i--)s=t[i],s.pos>e.pmax-1&&(s.del=!0,c--);for(i=0;i<t.length&&!(0>=c);i++)if(s=t[i],s.pos<e.pmin+1)for(s.del=!0,c--,o=2*s.size,l=t.length-1;l>=0;l--)t[l].dp-=o;for(i=t.length-1;i>=0&&!(0>=c);i--)s=t[i],s.pos+s.dp+s.size>e.pmax&&(s.del=!0,c--)}}}for(var r,a,o,i,l,s,c,u=0,f=t.map(function(t,n){var r=t[e];return[{i:n,dp:0,pos:t.pos,posref:t.posref,size:t.by*(\"x\"===r._id.charAt(0)?z:1)/2,pmin:r._offset,pmax:r._offset+r._length}]}).sort(function(t,e){return t[0].posref-e[0].posref});!r&&u<=t.length;){for(u++,r=!0,i=0;i<f.length-1;){var d=f[i],h=f[i+1" -, -"],p=d[d.length-1],g=h[0];if(a=p.pos+p.dp+p.size-g.pos-g.dp+g.size,a>.01&&p.pmin===g.pmin&&p.pmax===g.pmax){for(l=h.length-1;l>=0;l--)h[l].dp+=a;for(d.push.apply(d,h),f.splice(i+1,1),c=0,l=d.length-1;l>=0;l--)c+=d[l].dp;for(o=c/d.length,l=d.length-1;l>=0;l--)d[l].dp-=o;r=!1}else i++}f.forEach(n)}for(i=f.length-1;i>=0;i--){var v=f[i];for(l=v.length-1;l>=0;l--){var m=v[l],y=t[m.i];y.offset=m.dp,y.del=m.del}}}function f(t,e){t.each(function(t){var n=h.select(this);if(t.del)return void n.remove();var r=\"end\"===t.anchor?-1:1,a=n.select(\"text.nums\"),o={start:1,end:-1,middle:0}[t.anchor],i=o*(C+O),l=i+o*(t.txwidth+O),s=0,c=t.offset;\"middle\"===t.anchor&&(i-=t.tx2width/2,l-=t.tx2width/2),e&&(c*=-E,s=t.offset*S),n.select(\"path\").attr(\"d\",\"middle\"===t.anchor?\"M-\"+t.bx/2+\",-\"+t.by/2+\"h\"+t.bx+\"v\"+t.by+\"h-\"+t.bx+\"Z\":\"M0,0L\"+(r*C+s)+\",\"+(C+c)+\"v\"+(t.by/2-C)+\"h\"+r*t.bx+\"v-\"+t.by+\"H\"+(r*C+s)+\"V\"+(c-C)+\"Z\"),a.call(b.setPosition,i+s,c+t.ty0-t.by/2+O).selectAll(\"tspan.line\").attr({x:a.attr(\"x\"),y:a.attr(\"y\")}),t.tx2width&&(n.select(\"text.name, text.name tspan.line\").call(b.setPosition,l+o*O+s,c+t.ty0-t.by/2+O),n.select(\"rect\").call(b.setRect,l+(o-1)*t.tx2width/2+s,c-t.by/2-1,t.tx2width,t.by+2))})}function d(t,e,n){if(!e.target)return!1;if(!n||n.length!==t._hoverdata.length)return!0;for(var r=n.length-1;r>=0;r--){var a=n[r],o=t._hoverdata[r];if(a.curveNumber!==o.curveNumber||String(a.pointNumber)!==String(o.pointNumber))return!0}return!1}var h=t(\"d3\"),p=t(\"tinycolor2\"),g=t(\"fast-isnumeric\"),v=t(\"../../lib\"),m=t(\"../../lib/events\"),y=t(\"../../lib/svg_text_utils\"),x=t(\"../../components/color\"),b=t(\"../../components/drawing\"),_=t(\"../../components/dragelement\"),w=t(\"./axes\"),k=t(\"./constants\"),M=t(\"./dragbox\"),A=e.exports={};A.unhover=_.unhover,A.layoutAttributes={dragmode:{valType:\"enumerated\",values:[\"zoom\",\"pan\",\"select\",\"lasso\",\"orbit\",\"turntable\"],dflt:\"zoom\"},hovermode:{valType:\"enumerated\",values:[\"x\",\"y\",\"closest\",!1]}},A.supplyLayoutDefaults=function(t,e,n){function r(n,r){return v.coerce(t,e,A.layoutAttributes,n,r)}r(\"dragmode\");var a;if(e._has(\"cartesian\")){var o=e._isHoriz=A.isHoriz(n);a=o?\"y\":\"x\"}else a=\"closest\";r(\"hovermode\",a)},A.isHoriz=function(t){for(var e=!0,n=0;n<t.length;n++){var r=t[n];if(\"h\"!==r.orientation){e=!1;break}}return e},A.init=function(t){var e=t._fullLayout;if(e._has(\"cartesian\")&&!t._context.staticPlot){var n=Object.keys(e._plots||{}).sort(function(t,n){if((e._plots[t].mainplot&&!0)===(e._plots[n].mainplot&&!0)){var r=t.split(\"y\"),a=n.split(\"y\");return r[0]===a[0]?Number(r[1]||1)-Number(a[1]||1):Number(r[0]||1)-Number(a[0]||1)}return e._plots[t].mainplot?1:-1});n.forEach(function(n){var r=e._plots[n];if(e._has(\"cartesian\")){var a=r.x(),o=r.y(),i=(a._linepositions[n]||[])[3],l=(o._linepositions[n]||[])[3],s=k.DRAGGERSIZE;if(g(i)&&\"top\"===a.side&&(i-=s),g(l)&&\"right\"!==o.side&&(l-=s),!r.mainplot){var c=M(t,r,0,0,a._length,o._length,\"ns\",\"ew\");c.onmousemove=function(r){A.hover(t,r,n),e._lasthover=c,e._hoversubplot=n},c.onmouseout=function(e){t._dragging||_.unhover(t,e)},c.onclick=function(e){A.click(t,e)},M(t,r,-s,-s,s,s,\"n\",\"w\"),M(t,r,a._length,-s,s,s,\"n\",\"e\"),M(t,r,-s,o._length,s,s,\"s\",\"w\"),M(t,r,a._length,o._length,s,s,\"s\",\"e\")}g(i)&&(\"free\"===a.anchor&&(i-=e._size.h*(1-o.domain[1])),M(t,r,.1*a._length,i,.8*a._length,s,\"\",\"ew\"),M(t,r,0,i,.1*a._length,s,\"\",\"w\"),M(t,r,.9*a._length,i,.1*a._length,s,\"\",\"e\")),g(l)&&(\"free\"===o.anchor&&(l-=e._size.w*a.domain[0]),M(t,r,l,.1*o._length,s,.8*o._length,\"ns\",\"\"),M(t,r,l,.9*o._length,s,.1*o._length,\"s\",\"\"),M(t,r,l,0,s,.1*o._length,\"n\",\"\"))}});var r=e._hoverlayer.node();r.onmousemove=function(n){n.target=e._lasthover,A.hover(t,n,e._hoversubplot)},r.onclick=function(n){n.target=e._lasthover,A.click(t,n)},r.onmousedown=function(t){e._lasthover.onmousedown(t)}}};var L=k.YANGLE,T=Math.PI*L/180,z=1/Math.sin(T),S=Math.cos(T),E=Math.sin(T),C=k.HOVERARROWSIZE,O=k.HOVERTEXTPAD,P=k.HOVERFONTSIZE,N=k.HOVERFONT;A.hover=function(t,e,n){return\"string\"==typeof t&&(t=document.getElementById(t)),void 0===t._lastHoverTime&&(t._lastHoverTime=0),void 0!==t._hoverTimer&&(clearTimeout(t._hoverTimer),t._hoverTimer=void 0),Date.now()>t._lastHoverTime+k.HOVERMINTIME?(i(t,e,n),void(t._lastHoverTime=Date.now())):void(t._hoverTimer=setTimeout(function(){i(t,e,n),t._lastHoverTime=Date.now(),t._hoverTimer=void 0},k.HOVERMINTIME))},A.getDistanceFunction=function(t,e,n,r){return\"closest\"===t?r||o(e,n):\"x\"===t?e:n},A.getClosest=function(t,e,n){if(n.index!==!1)n.index>=0&&n.index<t.length?n.distance=0:n.index=!1;else for(var r=0;r<t.length;r++){var a=e(t[r]);a<=n.distance&&(n.index=r,n.distance=a)}return n},A.loneHover=function(t,e){var n={color:t.color||x.defaultLine,x0:t.x0||t.x||0,x1:t.x1||t.x||0,y0:t.y0||t.y||0,y1:t.y1||t.y||0,xLabel:t.xLabel,yLabel:t.yLabel,zLabel:t.zLabel,text:t.text,name:t.name,idealAlign:t.idealAlign,trace:{index:0,hoverinfo:\"\"},xa:{_offset:0},ya:{_offset:0},index:0},r=h.select(e.container),a=e.outerContainer?h.select(e.outerContainer):r,o={hovermode:\"closest\",rotateLabels:!1,bgColor:e.bgColor||x.background,container:r,outerContainer:a},i=c([n],o);return f(i,o.rotateLabels),i.node()},A.loneUnhover=function(t){var e=t instanceof h.selection?t:h.select(t);e.selectAll(\"g.hovertext\").remove()},A.click=function(t,e){t._hoverdata&&e&&e.target&&(t.emit(\"plotly_click\",{points:t._hoverdata}),e.stopImmediatePropagation&&e.stopImmediatePropagation())},A.inbox=function(t,e){return 0>t*e||0===t?k.MAXDIST*(.6-.3/Math.max(3,Math.abs(t-e))):1/0}},{\"../../components/color\":18,\"../../components/dragelement\":39,\"../../components/drawing\":41,\"../../lib\":89,\"../../lib/events\":87,\"../../lib/svg_text_utils\":100,\"./axes\":110,\"./constants\":115,\"./dragbox\":116,d3:9,\"fast-isnumeric\":11,tinycolor2:13}],118:[function(t,e,n){\"use strict\";var r=t(\"../plots\"),a=t(\"./constants\");n.name=\"cartesian\",n.attr=[\"xaxis\",\"yaxis\"],n.idRoot=[\"x\",\"y\"],n.idRegex=a.idRegex,n.attrRegex=a.attrRegex,n.attributes=t(\"./attributes\"),n.plot=function(t){function e(t,e){for(var n=[],r=0;r<t.length;r++){var a=t[r],o=a[0].trace;o.xaxis+o.yaxis===e&&n.push(a)}return n}function n(t,e){for(var n=[],r=0;r<t.length;r++){var a=t[r],o=a[0].trace;o._module===e&&o.visible===!0&&n.push(a)}return n}for(var a=t._fullLayout,o=r.getSubplotIds(a,\"cartesian\"),i=t.calcdata,l=a._modules,s=0;s<o.length;s++){var c=o[s],u=a._plots[c],f=e(i,c);u.plot&&u.plot.selectAll(\"g.trace\").remove();for(var d=0;d<l.length;d++){var h=l[d];if(\"cartesian\"===h.basePlotModule.name){var p=n(f,h);h.plot(t,u,p)}}}}},{\"../plots\":130,\"./attributes\":109,\"./constants\":115}],119:[function(t,e,n){\"use strict\";var r=t(\"../font_attributes\"),a=t(\"../../components/color/attributes\"),o=t(\"../../lib/extend\").extendFlat,i=t(\"../../components/rangeslider/attributes\"),l=t(\"../../components/rangeselector/attributes\"),s=t(\"./constants\");e.exports={color:{valType:\"color\",dflt:a.defaultLine},title:{valType:\"string\"},titlefont:o({},r,{}),type:{valType:\"enumerated\",values:[\"-\",\"linear\",\"log\",\"date\",\"category\"],dflt:\"-\"},autorange:{valType:\"enumerated\",values:[!0,!1,\"reversed\"],dflt:!0},rangemode:{valType:\"enumerated\",values:[\"normal\",\"tozero\",\"nonnegative\"],dflt:\"normal\"},range:{valType:\"info_array\",items:[{valType:\"number\"},{valType:\"number\"}]},rangeslider:i,rangeselector:l,fixedrange:{valType:\"boolean\",dflt:!1},tickmode:{valType:\"enumerated\",values:[\"auto\",\"linear\",\"array\"]},nticks:{valType:\"integer\",min:0,dflt:0},tick0:{valType:\"number\",dflt:0},dtick:{valType:\"any\",dflt:1},tickvals:{valType:\"data_array\"},ticktext:{valType:\"data_array\"},ticks:{valType:\"enumerated\",values:[\"outside\",\"inside\",\"\"]},mirror:{valType:\"enumerated\",values:[!0,\"ticks\",!1,\"all\",\"allticks\"],dflt:!1},ticklen:{valType:\"number\",min:0,dflt:5},tickwidth:{valType:\"number\",min:0,dflt:1},tickcolor:{valType:\"color\",dflt:a.defaultLine},showticklabels:{valType:\"boolean\",dflt:!0},tickfont:o({},r,{}),tickangle:{valType:\"angle\",dflt:\"auto\"},tickprefix:{valType:\"string\",dflt:\"\"},showtickprefix:{valType:\"enumerated\",values:[\"all\",\"first\",\"last\",\"none\"],dflt:\"all\"},ticksuffix:{valType:\"string\",dflt:\"\"},showticksuffix:{valType:\"enumerated\",values:[\"all\",\"first\",\"last\",\"none\"],dflt:\"all\"},showexponent:{valType:\"enumerated\",values:[\"all\",\"first\",\"last\",\"none\"],dflt:\"all\"},exponentformat:{valType:\"enumerated\",values:[\"none\",\"e\",\"E\",\"power\",\"SI\",\"B\"],dflt:\"B\"},tickformat:{valType:\"string\",dflt:\"\"},hoverformat:{valType:\"string\",dflt:\"\"},showline:{valType:\"boolean\",dflt:!1},linecolor:{valType:\"color\",dflt:a.defaultLine},linewidth:{valType:\"number\",min:0,dflt:1},showgrid:{valType:\"boolean\"},gridcolor:{valType:\"color\",dflt:a.lightLine},gridwidth:{valType:\"number\",min:0,dflt:1},zeroline:{valType:\"boolean\"},zerolinecolor:{valType:\"color\",dflt:a.defaultLine},zerolinewidth:{valType:\"number\",dflt:1},anchor:{valType:\"enumerated\",values:[\"free\",s.idRegex.x.toString(),s.idRegex.y.toString()]},side:{valType:\"enumerated\",values:[\"top\",\"bottom\",\"left\",\"right\"]},overlaying:{valType:\"enumerated\",values:[\"free\",s.idRegex.x.toString(),s.idRegex.y.toString()]},domain:{valType:\"info_array\",items:[{valType:\"number\",min:0,max:1},{valType:\"number\",min:0,max:1}],dflt:[0,1]},position:{valType:\"number\",min:0,max:1,dflt:0},categoryorder:{valType:\"enumerated\",values:[\"trace\",\"category ascending\",\"category descending\",\"array\"],dflt:\"trace\"},categoryarray:{valType:\"data_array\"},_deprecated:{autotick:{valType:\"boolean\"}}}},{\"../../components/color/attributes\":17,\"../../components/rangeselector/attributes\":66,\"../../components/rangeslider/attributes\":73,\"../../lib/extend\":88,\"../font_attributes\":128,\"./constants\":115}],120:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"../plots\"),o=t(\"../../components/color\"),i=t(\"../../components/rangeslider\"),l=t(\"../../components/rangeselector\"),s=t(\"./constants\"),c=t(\"./layout_attributes\"),u=t(\"./axis_defaults\"),f=t(\"./position_defaults\"),d=t(\"./axis_ids\");e.exports=function(t,e,n){function h(t,e){var n=Number(t.substr(5)||1),r=Number(e.substr(5)||1);return n-r}var p,g=Object.keys(t),v=[],m=[],y=[],x=[],b={},_={};for(p=0;" -, -"p<n.length;p++){var w,k,M=n[p];if(a.traceIs(M,\"cartesian\"))w=v,k=m;else{if(!a.traceIs(M,\"gl2d\"))continue;w=y,k=x}var A=d.id2name(M.xaxis),L=d.id2name(M.yaxis);if(A&&-1===w.indexOf(A)&&w.push(A),L&&-1===k.indexOf(L)&&k.push(L),a.traceIs(M,\"2dMap\")&&(b[A]=!0,b[L]=!0),a.traceIs(M,\"oriented\")){var T=\"h\"===M.orientation?L:A;_[T]=!0}}var z=e._has(\"gl3d\")||e._has(\"geo\");if(!z)for(p=0;p<g.length;p++){var S=g[p];-1===y.indexOf(S)&&-1===v.indexOf(S)&&s.xAxisMatch.test(S)?v.push(S):-1===x.indexOf(S)&&-1===m.indexOf(S)&&s.yAxisMatch.test(S)&&m.push(S)}v.length&&m.length&&r.pushUnique(e._basePlotModules,a.subplotsRegistry.cartesian);var E=v.concat(y).sort(h),C=m.concat(x).sort(h),O=E.concat(C),P=o.background;E.length&&C.length&&(P=r.coerce(t,e,a.layoutAttributes,\"plot_bgcolor\"));var N=o.combine(P,e.paper_bgcolor);O.forEach(function(a){function o(t,e){return r.coerce(l,s,c,t,e)}var i=a.charAt(0),l=t[a]||{},s={},h={letter:i,font:e.font,outerTicks:b[a],showGrid:!_[a],name:a,data:n,bgColor:N},p={letter:i,counterAxes:{x:C,y:E}[i].map(d.name2id),overlayableAxes:{x:E,y:C}[i].filter(function(e){return e!==a&&!(t[e]||{}).overlaying}).map(d.name2id)};u(l,s,o,h),f(l,s,o,p),e[a]=s,t[a]||\"-\"===l.type||(t[a]={type:l.type})}),O.forEach(function(n){var r=n.charAt(0),a=t[n],o=e[n],s={x:C,y:E}[r];i.supplyLayoutDefaults(t,e,n,s),\"x\"===r&&\"date\"===o.type&&l.supplyLayoutDefaults(a,o,e,s)})}},{\"../../components/color\":18,\"../../components/rangeselector\":72,\"../../components/rangeslider\":77,\"../../lib\":89,\"../plots\":130,\"./axis_defaults\":111,\"./axis_ids\":112,\"./constants\":115,\"./layout_attributes\":119,\"./position_defaults\":122}],121:[function(t,e,n){\"use strict\";function r(t,e,n){var r,o,i,l,s,c=[],u=n.map(function(e){return e[t]}),f=a.bisector(e).left;for(r=0;r<u.length;r++)for(i=u[r],o=0;o<i.length;o++)l=i[o],null!==l&&void 0!==l&&(s=f(c,l),s<c.length-1&&c[s]===l||c.splice(s,0,l));return c}var a=t(\"d3\");e.exports=function(t,e,n,o){switch(e){case\"array\":return Array.isArray(n)?n.slice():[];case\"category ascending\":\n" -, -"return r(t,a.ascending,o);case\"category descending\":return r(t,a.descending,o);case\"trace\":return[];default:return[]}}},{d3:9}],122:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\"),a=t(\"../../lib\");e.exports=function(t,e,n,o){var i=o.counterAxes||[],l=o.overlayableAxes||[],s=o.letter,c=a.coerce(t,e,{anchor:{valType:\"enumerated\",values:[\"free\"].concat(i),dflt:r(t.position)?\"free\":i[0]||\"free\"}},\"anchor\");\"free\"===c&&n(\"position\"),a.coerce(t,e,{side:{valType:\"enumerated\",values:\"x\"===s?[\"bottom\",\"top\"]:[\"left\",\"right\"],dflt:\"x\"===s?\"bottom\":\"left\"}},\"side\");var u=!1;if(l.length&&(u=a.coerce(t,e,{overlaying:{valType:\"enumerated\",values:[!1].concat(l),dflt:!1}},\"overlaying\")),!u){var f=n(\"domain\");f[0]>f[1]-.01&&(e.domain=[0,1]),a.noneOrAll(t.domain,e.domain,[0,1])}return e}},{\"../../lib\":89,\"fast-isnumeric\":11}],123:[function(t,e,n){\"use strict\";function r(t){return t._id}var a=t(\"../../lib/polygon\"),o=t(\"../../components/color\"),i=t(\"./axes\"),l=t(\"./constants\"),s=a.filter,c=a.tester,u=l.MINSELECT;e.exports=function(t,e,n,a,f){function d(t){var e=\"y\"===t._id.charAt(0)?1:0;return function(n){return t.p2d(n[e])}}function h(t,e){return t-e}var p,g=a.gd._fullLayout._zoomlayer,v=a.element.getBoundingClientRect(),m=a.plotinfo.x()._offset,y=a.plotinfo.y()._offset,x=e-v.left,b=n-v.top,_=x,w=b,k=\"M\"+x+\",\"+b,M=a.xaxes[0]._length,A=a.yaxes[0]._length,L=a.xaxes.map(r),T=a.yaxes.map(r),z=a.xaxes.concat(a.yaxes);\"lasso\"===f&&(p=s([[x,b]],l.BENDPX));var S=g.selectAll(\"path.select-outline\").data([1,2]);S.enter().append(\"path\").attr(\"class\",function(t){return\"select-outline select-outline-\"+t}).attr(\"transform\",\"translate(\"+m+\", \"+y+\")\").attr(\"d\",k+\"Z\");var E,C,O,P,N,D=g.append(\"path\").attr(\"class\",\"zoombox-corners\").style({fill:o.background,stroke:o.defaultLine,\"stroke-width\":1}).attr(\"transform\",\"translate(\"+m+\", \"+y+\")\").attr(\"d\",\"M0,0Z\"),I=[],R=a.gd,j=[];for(E=0;E<R.calcdata.length;E++)if(C=R.calcdata[E],O=C[0].trace,O._module&&O._module.selectPoints)if(a.subplot){if(O.subplot!==a.subplot)continue;I.push({selectPoints:O._module.selectPoints,cd:C,xaxis:a.xaxes[0],yaxis:a.yaxes[0]})}else{if(-1===L.indexOf(O.xaxis))continue;if(-1===T.indexOf(O.yaxis))continue;I.push({selectPoints:O._module.selectPoints,cd:C,xaxis:i.getFromId(R,O.xaxis),yaxis:i.getFromId(R,O.yaxis)})}a.moveFn=function(t,e){var n,r;_=Math.max(0,Math.min(M,t+x)),w=Math.max(0,Math.min(A,e+b));var o=Math.abs(_-x),i=Math.abs(w-b);for(\"select\"===f?(i<Math.min(.6*o,u)?(n=c([[x,0],[x,A],[_,A],[_,0]]),D.attr(\"d\",\"M\"+n.xmin+\",\"+(b-u)+\"h-4v\"+2*u+\"h4ZM\"+(n.xmax-1)+\",\"+(b-u)+\"h4v\"+2*u+\"h-4Z\")):o<Math.min(.6*i,u)?(n=c([[0,b],[0,w],[M,w],[M,b]]),D.attr(\"d\",\"M\"+(x-u)+\",\"+n.ymin+\"v-4h\"+2*u+\"v4ZM\"+(x-u)+\",\"+(n.ymax-1)+\"v4h\"+2*u+\"v-4Z\")):(n=c([[x,b],[x,w],[_,w],[_,b]]),D.attr(\"d\",\"M0,0Z\")),S.attr(\"d\",\"M\"+n.xmin+\",\"+n.ymin+\"H\"+(n.xmax-1)+\"V\"+(n.ymax-1)+\"H\"+n.xmin+\"Z\")):\"lasso\"===f&&(p.addPt([_,w]),n=c(p.filtered),S.attr(\"d\",\"M\"+p.filtered.join(\"L\")+\"Z\")),j=[],E=0;E<I.length;E++)P=I[E],[].push.apply(j,P.selectPoints(P,n));if(N={points:j},\"select\"===f){var l,s=N.range={};for(E=0;E<z.length;E++)r=z[E],l=r._id.charAt(0),s[r._id]=[r.p2d(n[l+\"min\"]),r.p2d(n[l+\"max\"])].sort(h)}else{var g=N.lassoPoints={};for(E=0;E<z.length;E++)r=z[E],g[r._id]=p.filtered.map(d(r))}a.gd.emit(\"plotly_selecting\",N)},a.doneFn=function(t,e){if(D.remove(),t||2!==e)a.gd.emit(\"plotly_selected\",N);else{for(S.remove(),E=0;E<I.length;E++)P=I[E],P.selectPoints(P,!1);R.emit(\"plotly_deselect\",null)}}}},{\"../../components/color\":18,\"../../lib/polygon\":95,\"./axes\":110,\"./constants\":115}],124:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"fast-isnumeric\"),o=t(\"../../lib\"),i=t(\"./constants\"),l=t(\"./clean_datum\"),s=t(\"./axis_ids\");e.exports=function(t){function e(e,n){if(e>0)return Math.log(e)/Math.LN10;if(0>=e&&n&&t.range&&2===t.range.length){var r=t.range[0],a=t.range[1];return.5*(r+a-3*u*Math.abs(r-a))}return i.BADNUM}function n(t){return Math.pow(10,t)}function c(t){return a(t)?Number(t):i.BADNUM}var u=10;if(t.c2l=\"log\"===t.type?e:c,t.l2c=\"log\"===t.type?n:c,t.l2d=function(e){return t.c2d(t.l2c(e))},t.p2d=function(e){return t.l2d(t.p2l(e))},t.setScale=function(){var e,n=t._gd._fullLayout._size;if(t._categories||(t._categories=[]),t.overlaying){var r=s.getFromId(t._gd,t.overlaying);t.domain=r.domain}for(t.range&&2===t.range.length&&t.range[0]!==t.range[1]||(t.range=[-1,1]),e=0;2>e;e++)a(t.range[e])||(t.range[e]=a(t.range[1-e])?t.range[1-e]*(e?10:.1):e?1:-1),t.range[e]<-(Number.MAX_VALUE/2)?t.range[e]=-(Number.MAX_VALUE/2):t.range[e]>Number.MAX_VALUE/2&&(t.range[e]=Number.MAX_VALUE/2);if(\"y\"===t._id.charAt(0)?(t._offset=n.t+(1-t.domain[1])*n.h,t._length=n.h*(t.domain[1]-t.domain[0]),t._m=t._length/(t.range[0]-t.range[1]),t._b=-t._m*t.range[1]):(t._offset=n.l+t.domain[0]*n.w,t._length=n.w*(t.domain[1]-t.domain[0]),t._m=t._length/(t.range[1]-t.range[0]),t._b=-t._m*t.range[0]),!isFinite(t._m)||!isFinite(t._b))throw o.notifier(\"Something went wrong with axis scaling\",\"long\"),t._gd._replotting=!1,new Error(\"axis scaling\")},t.l2p=function(e){return a(e)?r.round(t._b+t._m*e,2):i.BADNUM},t.p2l=function(e){return(e-t._b)/t._m},t.c2p=function(e,n){return t.l2p(t.c2l(e,n))},t.p2c=function(e){return t.l2c(t.p2l(e))},-1!==[\"linear\",\"log\",\"-\"].indexOf(t.type))t.c2d=c,t.d2c=function(t){return t=l(t),a(t)?Number(t):i.BADNUM},t.d2l=function(e,n){return\"log\"===t.type?t.c2l(t.d2c(e),n):t.d2c(e)};else if(\"date\"===t.type){if(t.c2d=function(t){return a(t)?o.ms2DateTime(t):i.BADNUM},t.d2c=function(t){return a(t)?Number(t):o.dateTime2ms(t)},t.d2l=t.d2c,t.range&&t.range.length>1)try{var f=t.range.map(o.dateTime2ms);!a(t.range[0])&&a(f[0])&&(t.range[0]=f[0]),!a(t.range[1])&&a(f[1])&&(t.range[1]=f[1])}catch(d){o.error(d,t.range)}}else\"category\"===t.type&&(t.c2d=function(e){return t._categories[Math.round(e)]},t.d2c=function(e){null!==e&&void 0!==e&&-1===t._categories.indexOf(e)&&t._categories.push(e);var n=t._categories.indexOf(e);return-1===n?i.BADNUM:n},t.d2l=t.d2c);t.makeCalcdata=function(e,n){var r,a,o;if(n in e)for(r=e[n],a=new Array(r.length),o=0;o<r.length;o++)a[o]=t.d2c(r[o]);else{var i=n+\"0\"in e?t.d2c(e[n+\"0\"]):0,l=e[\"d\"+n]?Number(e[\"d\"+n]):1;for(r=e[{x:\"y\",y:\"x\"}[n]],a=new Array(r.length),o=0;o<r.length;o++)a[o]=i+o*l}return a},t._min=[],t._max=[],t._minDtick=null,t._forceTick0=null}},{\"../../lib\":89,\"./axis_ids\":112,\"./clean_datum\":114,\"./constants\":115,d3:9,\"fast-isnumeric\":11}],125:[function(t,e,n){\"use strict\";function r(t){var e=[\"showexponent\",\"showtickprefix\",\"showticksuffix\"],n=e.filter(function(e){return void 0!==t[e]}),r=function(e){return t[e]===t[n[0]]};return n.every(r)||1===n.length?t[n[0]]:void 0}var a=t(\"../../lib\");e.exports=function(t,e,n,o,i){var l=r(t),s=n(\"tickprefix\");s&&n(\"showtickprefix\",l);var c=n(\"ticksuffix\");c&&n(\"showticksuffix\",l);var u=n(\"showticklabels\");if(u){var f=i.font||{},d=e.color===t.color?e.color:f.color;if(a.coerceFont(n,\"tickfont\",{family:f.family,size:f.size,color:d}),n(\"tickangle\"),\"category\"!==o){var h=n(\"tickformat\");h||\"date\"===o||(n(\"showexponent\",l),n(\"exponentformat\"))}}\"category\"===o||i.noHover||n(\"hoverformat\")}},{\"../../lib\":89}],126:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"./layout_attributes\");e.exports=function(t,e,n,o){var i=r.coerce2(t,e,a,\"ticklen\"),l=r.coerce2(t,e,a,\"tickwidth\"),s=r.coerce2(t,e,a,\"tickcolor\",e.color),c=n(\"ticks\",o.outerTicks||i||l||s?\"outside\":\"\");c||(delete e.ticklen,delete e.tickwidth,delete e.tickcolor)}},{\"../../lib\":89,\"./layout_attributes\":119}],127:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\");e.exports=function(t,e,n,a){var o=\"auto\";\"array\"!==t.tickmode||\"log\"!==a&&\"date\"!==a||(t.tickmode=\"auto\"),Array.isArray(t.tickvals)?o=\"array\":t.dtick&&r(t.dtick)&&(o=\"linear\");var i=n(\"tickmode\",o);if(\"auto\"===i)n(\"nticks\");else if(\"linear\"===i)n(\"tick0\"),n(\"dtick\");else{var l=n(\"tickvals\");void 0===l?e.tickmode=\"auto\":n(\"ticktext\")}}},{\"fast-isnumeric\":11}],128:[function(t,e,n){\"use strict\";e.exports={family:{valType:\"string\",noBlank:!0,strict:!0},size:{valType:\"number\",min:1},color:{valType:\"color\"}}},{}],129:[function(t,e,n){\"use strict\";var r=t(\"../plotly\"),a=t(\"./font_attributes\"),o=t(\"../components/color/attributes\"),i=r.Lib.extendFlat;e.exports={font:{family:i({},a.family,{dflt:'\"Open Sans\", verdana, arial, sans-serif'}),size:i({},a.size,{dflt:12}),color:i({},a.color,{dflt:o.defaultLine})},title:{valType:\"string\",dflt:\"Click to enter Plot title\"},titlefont:i({},a,{}),autosize:{valType:\"enumerated\",values:[!0,!1,\"initial\"]},width:{valType:\"number\",min:10,dflt:700},height:{valType:\"number\",min:10,dflt:450},margin:{l:{valType:\"number\",min:0,dflt:80},r:{valType:\"number\",min:0,dflt:80},t:{valType:\"number\",min:0,dflt:100},b:{valType:\"number\",min:0,dflt:80},pad:{valType:\"number\",min:0,dflt:0},autoexpand:{valType:\"boolean\",dflt:!0}},paper_bgcolor:{valType:\"color\",dflt:o.background},plot_bgcolor:{valType:\"color\",dflt:o.background},separators:{valType:\"string\",dflt:\".,\"},hidesources:{valType:\"boolean\",dflt:!1},smith:{valType:\"enumerated\",values:[!1],dflt:!1},showlegend:{valType:\"boolean\"},_composedModules:{\"*\":\"Fx\"},_nestedModules:{xaxis:\"Axes\",yaxis:\"Axes\",scene:\"gl3d\",geo:\"geo\",legend:\"Legend\",annotations:\"Annotations\",shapes:\"Shapes\",images:\"Images\",ternary:\"ternary\",mapbox:\"mapbox\"}}},{\"../components/color/attributes\":17,\"../plotly\":107,\"./font_attributes\":128}],130:[function(t,e,n){\"use strict\";function r(t){return\"object\"==typeof t&&(t=t.type),t}function a(t,e){e.text(\"\");var n=e.append(\"a\").attr({\"xlink:xlink:href\":\"#\",\"class\":\"link--impt link--embedview\",\"font-weight\":\"bold\"}).text(t._context.linkText+\" \"+String.fromCharCode(187));if(t._context.sendData)n.on(\"click\",function(){h.sendDataToCloud(t)});else{var r=window.location.pathname.split(\"/\"),a=window.location.search;n.attr({\"xlink:xlink:show\":\"new\",\"xlink:xlink:href\":\"/\"+r[2].split(\".\")[0]+\"/\"+r[1]+a})}}function o(t,e){for(var n=f.isPlainObject,r=Array.isArray,a=Object.keys(e),i=0;i<a.length;i++){var l=a[i],s=e[l],c=t[l];if(\"_\"===l.charAt(0)||\"function\"==typeof s){if(l in t)co" -, -"ntinue;t[l]=s}else if(r(s)&&r(c))for(var u=0;u<s.length;u++)n(s[u])&&n(c[u])&&o(c[u],s[u]);else n(s)&&n(c)&&(o(c,s),Object.keys(c).length||delete t[l])}}function i(t,e,n){if(Array.isArray(t.transforms))for(var r=t.transforms,a=e.transforms=[],o=0;o<r.length;o++){var i,l=r[o],s=l.type,c=y[s];c||f.warn(\"Unrecognized transform type \"+s+\".\"),c&&c.supplyDefaults?(i=c.supplyDefaults(l,e,n),i.type=s):i=f.extendFlat({},l),a.push(i)}}function l(t,e,n){for(var r=t.transforms,a=[t],o=0;o<r.length;o++){var i=r[o],l=i.type,s=y[l];s&&(a=s.transform(a,{transform:i,fullTrace:t,fullData:e,layout:n}))}return a}var s=t(\"d3\"),c=t(\"fast-isnumeric\"),u=t(\"../plotly\"),f=t(\"../lib\"),d=t(\"../components/color\"),h=e.exports={},p=h.modules={},g=h.allTypes=[],v=h.allCategories={},m=h.subplotsRegistry={},y=h.transformsRegistry={};h.attributes=t(\"./attributes\"),h.attributes.type.values=g,h.fontAttrs=t(\"./font_attributes\"),h.layoutAttributes=t(\"./layout_attributes\"),h.fontWeight=\"normal\",h.register=function(t,e,n,r){if(p[e])return void f.log(\"Type \"+e+\" already registered\");for(var a={},o=0;o<n.length;o++)a[n[o]]=!0,v[n[o]]=!0;p[e]={_module:t,categories:a},r&&Object.keys(r).length&&(p[e].meta=r),g.push(e)},h.getModule=function(t){if(void 0!==t.r)return f.warn(\"Tried to put a polar trace on an incompatible graph of cartesian data. Ignoring this dataset.\",t),!1;var e=p[r(t)];return e?e._module:!1},h.traceIs=function(t,e){if(t=r(t),\"various\"===t)return!1;var n=p[t];return n||(void 0!==t&&f.log(\"Unrecognized trace type \"+t+\".\"),n=p[h.attributes.type.dflt]),!!n.categories[e]},h.registerSubplot=function(t){var e=t.name;return m[e]?void f.log(\"Plot type \"+e+\" already registered.\"):void(m[e]=t)},h.findSubplotIds=function(t,e){var n=[];if(void 0===h.subplotsRegistry[e])return n;for(var r=h.subplotsRegistry[e].attr,a=0;a<t.length;a++){var o=t[a];h.traceIs(o,e)&&-1===n.indexOf(o[r])&&n.push(o[r])}return n},h.getSubplotIds=function(t,e){var n=h.subplotsRegistry[e];if(void 0===n)return[];if(!(\"cartesian\"!==e||t._has&&t._has(\"cartesian\")))return[];if(!(\"gl2d\"!==e||t._has&&t._has(\"gl2d\")))return[];if(\"cartesian\"===e||\"gl2d\"===e)return Object.keys(t._plots||{});for(var r=n.idRegex,a=Object.keys(t),o=[],i=0;i<a.length;i++){var l=a[i];r.test(l)&&o.push(l)}var s=n.idRoot.length;return o.sort(function(t,e){var n=+(t.substr(s)||1),r=+(e.substr(s)||1);return n-r}),o},h.getSubplotData=function(t,e,n){if(void 0===h.subplotsRegistry[e])return[];for(var r,a=h.subplotsRegistry[e].attr,o=[],i=0;i<t.length;i++)if(r=t[i],\"gl2d\"===e&&h.traceIs(r,\"gl2d\")){var l=u.Axes.subplotMatch,s=\"x\"+n.match(l)[1],c=\"y\"+n.match(l)[2];r[a[0]]===s&&r[a[1]]===c&&o.push(r)}else r[a]===n&&o.push(r);return o},h.redrawText=function(t){return t.data&&t.data[0]&&t.data[0].r?void 0:new Promise(function(e){setTimeout(function(){u.Annotations.drawAll(t),u.Legend.draw(t),(t.calcdata||[]).forEach(function(t){t[0]&&t[0].t&&t[0].t.cb&&t[0].t.cb()}),e(h.previousPromises(t))},300)})},h.resize=function(t){return new Promise(function(e,n){t&&\"none\"!==s.select(t).style(\"display\")||n(new Error(\"Resize must be passed a plot div element.\")),t._redrawTimer&&clearTimeout(t._redrawTimer),t._redrawTimer=setTimeout(function(){if((t._fullLayout||{}).autosize){var n=t.changed;t.autoplay=!0,u.relayout(t,{autosize:!0}),t.changed=n,e(t)}},100)})},h.previousPromises=function(t){return(t._promises||[]).length?Promise.all(t._promises).then(function(){t._promises=[]}):void 0},h.addLinks=function(t){var e=t._fullLayout,n=e._paper.selectAll(\"text.js-plot-link-container\").data([0]);n.enter().append(\"text\").classed(\"js-plot-link-container\",!0).style({\"font-family\":'\"Open Sans\", Arial, sans-serif',\"font-size\":\"12px\",fill:d.defaultLine,\"pointer-events\":\"all\"}).each(function(){var t=s.select(this);t.append(\"tspan\").classed(\"js-link-to-tool\",!0),t.append(\"tspan\").classed(\"js-link-spacer\",!0),t.append(\"tspan\").classed(\"js-sourcelinks\",!0)});var r=n.node(),o={y:e._paper.attr(\"height\")-9};document.body.contains(r)&&r.getComputedTextLength()>=e.width-20?(o[\"text-anchor\"]=\"start\",o.x=5):(o[\"text-anchor\"]=\"end\",o.x=e._paper.attr(\"width\")-7),n.attr(o);var i=n.select(\".js-link-to-tool\"),l=n.select(\".js-link-spacer\"),c=n.select(\".js-sourcelinks\");t._context.showSources&&t._context.showSources(t),t._context.showLink&&a(t,i),l.text(i.text()&&c.text()?\" - \":\"\")},h.sendDataToCloud=function(t){t.emit(\"plotly_beforeexport\");var e=window.PLOTLYENV&&window.PLOTLYENV.BASE_URL||\"https://plot.ly\",n=s.select(t).append(\"div\").attr(\"id\",\"hiddenform\").style(\"display\",\"none\"),r=n.append(\"form\").attr({action:e+\"/external\",method:\"post\",target:\"_blank\"}),a=r.append(\"input\").attr({type:\"text\",name:\"data\"});return a.node().value=h.graphJson(t,!1,\"keepdata\"),r.node().submit(),n.remove(),t.emit(\"plotly_afterexport\"),!1},h.supplyDefaults=function(t){var e,n=t._fullLayout||{},r=t._fullLayout={},a=t.layout||{},i=t._fullData||[],l=t._fullData=[],s=t.data||[];h.supplyLayoutGlobalDefaults(a,r),r._dataLength=s.length,h.supplyDataDefaults(s,l,r),r._has=h._hasPlotType.bind(r);var c=r._modules;for(e=0;e<c.length;e++){var f=c[e];f.cleanData&&f.cleanData(l)}if(i.length===s.length)for(e=0;e<l.length;e++)o(l[e],i[e]);h.supplyLayoutModuleDefaults(a,r,l),r._hasCartesian=r._has(\"cartesian\"),r._hasGeo=r._has(\"geo\"),r._hasGL3D=r._has(\"gl3d\"),r._hasGL2D=r._has(\"gl2d\"),r._hasTernary=r._has(\"ternary\"),r._hasPie=r._has(\"pie\"),h.cleanPlot(l,r,i,n),o(r,n),h.doAutoMargin(t);var d=u.Axes.list(t);for(e=0;e<d.length;e++){var p=d[e];p._gd=t,p.setScale()}if((t.calcdata||[]).length===l.length)for(e=0;e<l.length;e++){var g=l[e];(t.calcdata[e][0]||{}).trace=g}},h._hasPlotType=function(t){for(var e=this._basePlotModules||[],n=0;n<e.length;n++){var r=e[n];if(r.name===t)return!0}return!1},h.cleanPlot=function(t,e,n,r){var a,o,i=r._basePlotModules||[];for(a=0;a<i.length;a++){var l=i[a];l.clean&&l.clean(t,e,n,r)}var s=!!r._paper,c=!!r._infolayer;t:for(a=0;a<n.length;a++){var u=n[a],f=u.uid;for(o=0;o<t.length;o++){var d=t[o];if(f===d.uid)continue t}s&&r._paper.selectAll(\".hm\"+f+\",.contour\"+f+\",#clip\"+f).remove(),c&&r._infolayer.selectAll(\".cb\"+f).remove()}},h.supplyDataDefaults=function(t,e,n){function r(t){e.push(t);var n=t._module;n&&(f.pushUnique(a,n),f.pushUnique(o,t._module.basePlotModule),i++)}for(var a=n._modules=[],o=n._basePlotModules=[],i=0,s=0;s<t.length;s++){var c=t[s],u=h.supplyTraceDefaults(c,i,n);if(u.transforms&&u.transforms.length)for(var d=l(u,e,n),p=0;p<d.length;p++){var g=d[p],v=h.supplyTraceDefaults(g,i,n);g.uid=v.uid=u.uid+p,v.index=s,v._input=c,v._fullInput=u,v._expandedIndex=i,v._expandedInput=g,r(v)}else u.index=s,u._input=c,u._expandedIndex=i,r(u)}},h.supplyTraceDefaults=function(t,e,n){function r(e,n){return f.coerce(t,o,h.attributes,e,n)}function a(e,n){return h.traceIs(o,e)?f.coerce(t,o,h.subplotsRegistry[e].attributes,n):void 0}var o={},l=d.defaults[e%d.defaults.length],s=r(\"visible\");r(\"type\"),r(\"uid\");for(var c=Object.keys(m),u=0;u<c.length;u++){var p=c[u];if(-1===[\"cartesian\",\"gl2d\"].indexOf(p)){var g=m[p].attr;g&&a(p,g)}}if(s){var v=h.getModule(o);o._module=v,r(\"hoverinfo\",1===n._dataLength?\"x+y+z+text\":void 0),v&&v.supplyDefaults(t,o,l,n),r(\"name\",\"trace \"+e),h.traceIs(o,\"noOpacity\")||r(\"opacity\"),a(\"cartesian\",\"xaxis\"),a(\"cartesian\",\"yaxis\"),a(\"gl2d\",\"xaxis\"),a(\"gl2d\",\"yaxis\"),h.traceIs(o,\"showLegend\")&&(r(\"showlegend\"),r(\"legendgroup\")),i(t,o,n)}return o},h.supplyLayoutGlobalDefaults=function(t,e){function n(n,r){return f.coerce(t,e,h.layoutAttributes,n,r)}var r=f.coerceFont(n,\"font\");n(\"title\"),f.coerceFont(n,\"titlefont\",{family:r.family,size:Math.round(1.4*r.size),color:r.color});var a=n(\"autosize\",t.width&&t.height?!1:\"initial\");n(\"width\"),n(\"height\"),n(\"margin.l\"),n(\"margin.r\"),n(\"margin.t\"),n(\"margin.b\"),n(\"margin.pad\"),n(\"margin.autoexpand\"),\"initial\"!==a&&h.sanitizeMargins(e),n(\"paper_bgcolor\"),n(\"separators\"),n(\"hidesources\"),n(\"smith\")},h.supplyLayoutModuleDefaults=function(t,e,n){var r,a;u.Axes.supplyLayoutDefaults(t,e,n);var o=e._basePlotModules;for(r=0;r<o.length;r++)a=o[r],\"cartesian\"!==a.name&&a.supplyLayoutDefaults&&a.supplyLayoutDefaults(t,e,n);var i=e._modules;for(r=0;r<i.length;r++)a=i[r],a.supplyLayoutDefaults&&a.supplyLayoutDefaults(t,e,n);var l=[\"Fx\",\"Annotations\",\"Shapes\",\"Legend\",\"Images\"];for(r=0;r<l.length;r++)a=l[r],u[a]&&u[a].supplyLayoutDefaults(t,e,n)},h.purge=function(t){var e=t._fullLayout||{};void 0!==e._glcontainer&&e._glcontainer.remove(),void 0!==e._geocontainer&&e._geocontainer.remove(),e._modeBar&&e._modeBar.destroy(),delete t.data,delete t.layout,delete t._fullData,delete t._fullLayout,delete t.calcdata,delete t.framework,delete t.empty,delete t.fid,delete t.undoqueue,delete t.undonum,delete t.autoplay,delete t.changed,delete t._tester,delete t._testref,delete t._promises,delete t._redrawTimer,delete t._replotting,delete t.firstscatter,delete t.hmlumcount,delete t.hmpixcount,delete t.numboxes,delete t._hoverTimer,delete t._lastHoverTime,t.removeAllListeners&&t.removeAllListeners()},h.style=function(t){for(var e=t._fullLayout._modules,n=0;n<e.length;n++){var r=e[n];r.style&&r.style(t)}},h.sanitizeMargins=function(t){if(t&&t.margin){var e,n=t.width,r=t.height,a=t.margin,o=n-(a.l+a.r),i=r-(a.t+a.b);0>o&&(e=(n-1)/(a.l+a.r),a.l=Math.floor(e*a.l),a.r=Math.floor(e*a.r)),0>i&&(e=(r-1)/(a.t+a.b),a.t=Math.floor(e*a.t),a.b=Math.floor(e*a.b))}},h.autoMargin=function(t,e,n){var r=t._fullLayout;if(r._pushmargin||(r._pushmargin={}),r.margin.autoexpand!==!1){if(n){var a=void 0===n.pad?12:n.pad;n.l+n.r>.5*r.width&&(n.l=n.r=0),n.b+n.t>.5*r.height&&(n.b=n.t=0),r._pushmargin[e]={l:{val:n.x,size:n.l+a},r:{val:n.x,size:n.r+a},b:{val:n.y,size:n.b+a},t:{val:n.y,size:n.t+a}}}else delete r._pushmargin[e];t._replotting||h.doAutoMargin(t)}},h.doAutoMargin=function(t){var e=t._fullLayout;e._size||(e._size={}),e._pushmargin||(e._pushmargin={});var n=e._size,r=JSON.stringify(n),a=Math.max(e.margin.l||0,0),o=Math.max(e.margin.r||0,0),i=Math.max(e.margin.t||0,0),l=Math.max(e.margin.b||0,0),s=e._pushmargin;return e.margin.autoexpand!==!1&&(s.base={l:{val:0,size" -, -":a},r:{val:1,size:o},t:{val:1,size:i},b:{val:0,size:l}},Object.keys(s).forEach(function(t){var n=s[t].l||{},r=s[t].b||{},u=n.val,f=n.size,d=r.val,h=r.size;Object.keys(s).forEach(function(t){if(c(f)&&s[t].r){var n=s[t].r.val,r=s[t].r.size;if(n>u){var p=(f*n+(r-e.width)*u)/(n-u),g=(r*(1-u)+(f-e.width)*(1-n))/(n-u);p>=0&&g>=0&&p+g>a+o&&(a=p,o=g)}}if(c(h)&&s[t].t){var v=s[t].t.val,m=s[t].t.size;if(v>d){var y=(h*v+(m-e.height)*d)/(v-d),x=(m*(1-d)+(h-e.height)*(1-v))/(v-d);y>=0&&x>=0&&y+x>l+i&&(l=y,i=x)}}})})),n.l=Math.round(a),n.r=Math.round(o),n.t=Math.round(i),n.b=Math.round(l),n.p=Math.round(e.margin.pad),n.w=Math.round(e.width)-n.l-n.r,n.h=Math.round(e.height)-n.t-n.b,t._replotting||\"{}\"===r||r===JSON.stringify(e._size)?void 0:u.plot(t)},h.graphJson=function(t,e,n,r,a){function o(t){if(\"function\"==typeof t)return null;if(f.isPlainObject(t)){var e,r,a={};for(e in t)if(\"function\"!=typeof t[e]&&-1===[\"_\",\"[\"].indexOf(e.charAt(0))){if(\"keepdata\"===n){if(\"src\"===e.substr(e.length-3))continue}else if(\"keepstream\"===n){if(r=t[e+\"src\"],\"string\"==typeof r&&r.indexOf(\":\")>0&&!f.isPlainObject(t.stream))continue}else if(\"keepall\"!==n&&(r=t[e+\"src\"],\"string\"==typeof r&&r.indexOf(\":\")>0))continue;a[e]=o(t[e])}return a}return Array.isArray(t)?t.map(o):t&&t.getTime?f.ms2DateTime(t):t}(a&&e&&!t._fullData||a&&!e&&!t._fullLayout)&&h.supplyDefaults(t);var i=a?t._fullData:t.data,l=a?t._fullLayout:t.layout,s={data:(i||[]).map(function(t){var n=o(t);return e&&delete n.fit,n})};return e||(s.layout=o(l)),t.framework&&t.framework.isPolar&&(s=t.framework.getConfig()),\"object\"===r?s:JSON.stringify(s)}},{\"../components/color\":18,\"../lib\":89,\"../plotly\":107,\"./attributes\":108,\"./font_attributes\":128,\"./layout_attributes\":129,d3:9,\"fast-isnumeric\":11}],131:[function(t,e,n){\"use strict\";var r=t(\"../../traces/scatter/attributes\"),a=r.marker;e.exports={r:r.r,t:r.t,marker:{color:a.color,size:a.size,symbol:a.symbol,opacity:a.opacity}}},{\"../../traces/scatter/attributes\":167}],132:[function(t,e,n){\"use strict\";function r(t,e){var n={showline:{valType:\"boolean\"},showticklabels:{valType:\"boolean\"},tickorientation:{valType:\"enumerated\",values:[\"horizontal\",\"vertical\"]},ticklen:{valType:\"number\",min:0},tickcolor:{valType:\"color\"},ticksuffix:{valType:\"string\"},endpadding:{valType:\"number\"},visible:{valType:\"boolean\"}};return o({},e,n)}var a=t(\"../cartesian/layout_attributes\"),o=t(\"../../lib/extend\").extendFlat,i=o({},a.domain,{});e.exports={radialaxis:r(\"radial\",{range:{valType:\"info_array\",items:[{valType:\"number\"},{valType:\"number\"}]},domain:i,orientation:{valType:\"number\"}}),angularaxis:r(\"angular\",{range:{valType:\"info_array\",items:[{valType:\"number\",dflt:0},{valType:\"number\",dflt:360}]},domain:i}),layout:{direction:{valType:\"enumerated\",values:[\"clockwise\",\"counterclockwise\"]},orientation:{valType:\"angle\"}}}},{\"../../lib/extend\":88,\"../cartesian/layout_attributes\":119}],133:[function(t,e,n){var r=t(\"../../plotly\"),a=t(\"d3\"),o=e.exports={version:\"0.2.2\",manager:t(\"./micropolar_manager\")},i=r.Lib.extendDeepAll;o.Axis=function(){function t(t){n=t||n;var c=s.data,f=s.layout;return(\"string\"==typeof n||n.nodeName)&&(n=a.select(n)),n.datum(c).each(function(t,n){function s(t,e){return l(t)%360+f.orientation}var c=t.slice();u={data:o.util.cloneJson(c),layout:o.util.cloneJson(f)};var d=0;c.forEach(function(t,e){t.color||(t.color=f.defaultColorRange[d],d=(d+1)%f.defaultColorRange.length),t.strokeColor||(t.strokeColor=\"LinePlot\"===t.geometry?t.color:a.rgb(t.color).darker().toString()),u.data[e].color=t.color,u.data[e].strokeColor=t.strokeColor,u.data[e].strokeDash=t.strokeDash,u.data[e].strokeSize=t.strokeSize});var h=c.filter(function(t,e){var n=t.visible;return\"undefined\"==typeof n||n===!0}),p=!1,g=h.map(function(t,e){return p=p||\"undefined\"!=typeof t.groupId,t});if(p){var v=a.nest().key(function(t,e){return\"undefined\"!=typeof t.groupId?t.groupId:\"unstacked\"}).entries(g),m=[],y=v.map(function(t,e){if(\"unstacked\"===t.key)return t.values;var n=t.values[0].r.map(function(t,e){return 0});return t.values.forEach(function(t,e,r){t.yStack=[n],m.push(n),n=o.util.sumArrays(t.r,n)}),t.values});h=a.merge(y)}h.forEach(function(t,e){t.t=Array.isArray(t.t[0])?t.t:[t.t],t.r=Array.isArray(t.r[0])?t.r:[t.r]});var x=Math.min(f.width-f.margin.left-f.margin.right,f.height-f.margin.top-f.margin.bottom)/2;x=Math.max(10,x);var b,_=[f.margin.left+x,f.margin.top+x];if(p){var w=a.max(o.util.sumArrays(o.util.arrayLast(h).r[0],o.util.arrayLast(m)));b=[0,w]}else b=a.extent(o.util.flattenArray(h.map(function(t,e){return t.r})));f.radialAxis.domain!=o.DATAEXTENT&&(b[0]=0),r=a.scale.linear().domain(f.radialAxis.domain!=o.DATAEXTENT&&f.radialAxis.domain?f.radialAxis.domain:b).range([0,x]),u.layout.radialAxis.domain=r.domain();var k,M=o.util.flattenArray(h.map(function(t,e){return t.t})),A=\"string\"==typeof M[0];A&&(M=o.util.deduplicate(M),k=M.slice(),M=a.range(M.length),h=h.map(function(t,e){var n=t;return t.t=[M],p&&(n.yStack=t.yStack),n}));var L=h.filter(function(t,e){return\"LinePlot\"===t.geometry||\"DotPlot\"===t.geometry}).length===h.length,T=null===f.needsEndSpacing?A||!L:f.needsEndSpacing,z=f.angularAxis.domain&&f.angularAxis.domain!=o.DATAEXTENT&&!A&&f.angularAxis.domain[0]>=0,S=z?f.angularAxis.domain:a.extent(M),E=Math.abs(M[1]-M[0]);L&&!A&&(E=0);var C=S.slice();T&&A&&(C[1]+=E);var O=f.angularAxis.ticksCount||4;O>8&&(O=O/(O/8)+O%8),f.angularAxis.ticksStep&&(O=(C[1]-C[0])/O);var P=f.angularAxis.ticksStep||(C[1]-C[0])/(O*(f.minorTicks+1));k&&(P=Math.max(Math.round(P),1)),C[2]||(C[2]=P);var N=a.range.apply(this,C);if(N=N.map(function(t,e){return parseFloat(t.toPrecision(12))}),l=a.scale.linear().domain(C.slice(0,2)).range(\"clockwise\"===f.direction?[0,360]:[360,0]),u.layout.angularAxis.domain=l.domain(),u.layout.angularAxis.endPadding=T?E:0,e=a.select(this).select(\"svg.chart-root\"),\"undefined\"==typeof e||e.empty()){var D=\"<svg xmlns='http://www.w3.org/2000/svg' class='chart-root'>' + '<g class='outer-group'>' + '<g class='chart-group'>' + '<circle class='background-circle'></circle>' + '<g class='geometry-group'></g>' + '<g class='radial axis-group'>' + '<circle class='outside-circle'></circle>' + '</g>' + '<g class='angular axis-group'></g>' + '<g class='guides-group'><line></line><circle r='0'></circle></g>' + '</g>' + '<g class='legend-group'></g>' + '<g class='tooltips-group'></g>' + '<g class='title-group'><text></text></g>' + '</g>' + '</svg>\",I=(new DOMParser).parseFromString(D,\"application/xml\"),R=this.appendChild(this.ownerDocument.importNode(I.documentElement,!0));e=a.select(R)}e.select(\".guides-group\").style({\"pointer-events\":\"none\"}),e.select(\".angular.axis-group\").style({\"pointer-events\":\"none\"}),e.select(\".radial.axis-group\").style({\"pointer-events\":\"none\"});var j,q=e.select(\".chart-group\"),F={fill:\"none\",stroke:f.tickColor},B={\"font-size\":f.font.size,\"font-family\":f.font.family,fill:f.font.color,\"text-shadow\":[\"-1px 0px\",\"1px -1px\",\"-1px 1px\",\"1px 1px\"].map(function(t,e){return\" \"+t+\" 0 \"+f.font.outlineColor}).join(\",\")};if(f.showLegend){j=e.select(\".legend-group\").attr({transform:\"translate(\"+[x,f.margin.top]+\")\"}).style({display:\"block\"});var H=h.map(function(t,e){var n=o.util.cloneJson(t);return n.symbol=\"DotPlot\"===t.geometry?t.dotType||\"circle\":\"LinePlot\"!=t.geometry?\"square\":\"line\",n.visibleInLegend=\"undefined\"==typeof t.visibleInLegend||t.visibleInLegend,n.color=\"LinePlot\"===t.geometry?t.strokeColor:t.color,n});o.Legend().config({data:h.map(function(t,e){return t.name||\"Element\"+e}),legendConfig:i({},o.Legend.defaultConfig().legendConfig,{container:j,elements:H,reverseOrder:f.legend.reverseOrder})})();var V=j.node().getBBox();x=Math.min(f.width-V.width-f.margin.left-f.margin.right,f.height-f.margin.top-f.margin.bottom)/2,x=Math.max(10,x),_=[f.margin.left+x,f.margin.top+x],r.range([0,x]),u.layout.radialAxis.domain=r.domain(),j.attr(\"transform\",\"translate(\"+[_[0]+x,_[1]-x]+\")\")}else j=e.select(\".legend-group\").style({display:\"none\"});e.attr({width:f.width,height:f.height}).style({opacity:f.opacity}),q.attr(\"transform\",\"translate(\"+_+\")\").style({cursor:\"crosshair\"});var Z=[(f.width-(f.margin.left+f.margin.right+2*x+(V?V.width:0)))/2,(f.height-(f.margin.top+f.margin.bottom+2*x))/2];if(Z[0]=Math.max(0,Z[0]),Z[1]=Math.max(0,Z[1]),e.select(\".outer-group\").attr(\"transform\",\"translate(\"+Z+\")\"),f.title){var Y=e.select(\"g.title-group text\").style(B).text(f.title),U=Y.node().getBBox();Y.attr({x:_[0]-U.width/2,y:_[1]-x-20})}var X=e.select(\".radial.axis-group\");if(f.radialAxis.gridLinesVisible){var G=X.selectAll(\"circle.grid-circle\").data(r.ticks(5));G.enter().append(\"circle\").attr({\"class\":\"grid-circle\"}).style(F),G.attr(\"r\",r),G.exit().remove()}X.select(\"circle.outside-circle\").attr({r:x}).style(F);var $=e.select(\"circle.background-circle\").attr({r:x}).style({fill:f.backgroundColor,stroke:f.stroke});if(f.radialAxis.visible){var Q=a.svg.axis().scale(r).ticks(5).tickSize(5);X.call(Q).attr({transform:\"rotate(\"+f.radialAxis.orientation+\")\"}),X.selectAll(\".domain\").style(F),X.selectAll(\"g>text\").text(function(t,e){return this.textContent+f.radialAxis.ticksSuffix}).style(B).style({\"text-anchor\":\"start\"}).attr({x:0,y:0,dx:0,dy:0,transform:function(t,e){return\"horizontal\"===f.radialAxis.tickOrientation?\"rotate(\"+-f.radialAxis.orientation+\") translate(\"+[0,B[\"font-size\"]]+\")\":\"translate(\"+[0,B[\"font-size\"]]+\")\"}}),X.selectAll(\"g>line\").style({stroke:\"black\"})}var W=e.select(\".angular.axis-group\").selectAll(\"g.angular-tick\").data(N),J=W.enter().append(\"g\").classed(\"angular-tick\",!0);W.attr({transform:function(t,e){return\"rotate(\"+s(t,e)+\")\"}}).style({display:f.angularAxis.visible?\"block\":\"none\"}),W.exit().remove(),J.append(\"line\").classed(\"grid-line\",!0).classed(\"major\",function(t,e){return e%(f.minorTicks+1)==0}).classed(\"minor\",function(t,e){return!(e%(f.minorTicks+1)==0)}).style(F),J.selectAll(\".minor\").style({stroke:f.minorTickColor}),W.select(\"line.grid-line\").attr({x1:f.tickLength?x-f.tickLength:0,x2:x}).style({display:f.angularAxis.gridLinesVisible?\"block\":\"none\"}),J.append(\"text\"" -, -").classed(\"axis-text\",!0).style(B);var K=W.select(\"text.axis-text\").attr({x:x+f.labelOffset,dy:\".35em\",transform:function(t,e){var n=s(t,e),r=x+f.labelOffset,a=f.angularAxis.tickOrientation;return\"horizontal\"==a?\"rotate(\"+-n+\" \"+r+\" 0)\":\"radial\"==a?270>n&&n>90?\"rotate(180 \"+r+\" 0)\":null:\"rotate(\"+(180>=n&&n>0?-90:90)+\" \"+r+\" 0)\"}}).style({\"text-anchor\":\"middle\",display:f.angularAxis.labelsVisible?\"block\":\"none\"}).text(function(t,e){return e%(f.minorTicks+1)!=0?\"\":k?k[t]+f.angularAxis.ticksSuffix:t+f.angularAxis.ticksSuffix}).style(B);f.angularAxis.rewriteTicks&&K.text(function(t,e){return e%(f.minorTicks+1)!=0?\"\":f.angularAxis.rewriteTicks(this.textContent,e)});var tt=a.max(q.selectAll(\".angular-tick text\")[0].map(function(t,e){return t.getCTM().e+t.getBBox().width}));j.attr({transform:\"translate(\"+[x+tt,f.margin.top]+\")\"});var et=e.select(\"g.geometry-group\").selectAll(\"g\").size()>0,nt=e.select(\"g.geometry-group\").selectAll(\"g.geometry\").data(h);if(nt.enter().append(\"g\").attr({\"class\":function(t,e){return\"geometry geometry\"+e}}),nt.exit().remove(),h[0]||et){var rt=[];h.forEach(function(t,e){var n={};n.radialScale=r,n.angularScale=l,n.container=nt.filter(function(t,n){return n==e}),n.geometry=t.geometry,n.orientation=f.orientation,n.direction=f.direction,n.index=e,rt.push({data:t,geometryConfig:n})});var at=a.nest().key(function(t,e){return\"undefined\"!=typeof t.data.groupId||\"unstacked\"}).entries(rt),ot=[];at.forEach(function(t,e){\"unstacked\"===t.key?ot=ot.concat(t.values.map(function(t,e){return[t]})):ot.push(t.values)}),ot.forEach(function(t,e){var n;n=Array.isArray(t)?t[0].geometryConfig.geometry:t.geometryConfig.geometry;var r=t.map(function(t,e){return i(o[n].defaultConfig(),t)});o[n]().config(r)()})}var it,lt,st=e.select(\".guides-group\"),ct=e.select(\".tooltips-group\"),ut=o.tooltipPanel().config({container:ct,fontSize:8})(),ft=o.tooltipPanel().config({container:ct,fontSize:8})(),dt=o.tooltipPanel().config({container:ct,hasTick:!0})();if(!A){var ht=st.select(\"line\").attr({\n" -, -"x1:0,y1:0,y2:0}).style({stroke:\"grey\",\"pointer-events\":\"none\"});q.on(\"mousemove.angular-guide\",function(t,e){var n=o.util.getMousePos($).angle;ht.attr({x2:-x,transform:\"rotate(\"+n+\")\"}).style({opacity:.5});var r=(n+180+360-f.orientation)%360;it=l.invert(r);var a=o.util.convertToCartesian(x+12,n+180);ut.text(o.util.round(it)).move([a[0]+_[0],a[1]+_[1]])}).on(\"mouseout.angular-guide\",function(t,e){st.select(\"line\").style({opacity:0})})}var pt=st.select(\"circle\").style({stroke:\"grey\",fill:\"none\"});q.on(\"mousemove.radial-guide\",function(t,e){var n=o.util.getMousePos($).radius;pt.attr({r:n}).style({opacity:.5}),lt=r.invert(o.util.getMousePos($).radius);var a=o.util.convertToCartesian(n,f.radialAxis.orientation);ft.text(o.util.round(lt)).move([a[0]+_[0],a[1]+_[1]])}).on(\"mouseout.radial-guide\",function(t,e){pt.style({opacity:0}),dt.hide(),ut.hide(),ft.hide()}),e.selectAll(\".geometry-group .mark\").on(\"mouseover.tooltip\",function(t,n){var r=a.select(this),i=r.style(\"fill\"),l=\"black\",s=r.style(\"opacity\")||1;if(r.attr({\"data-opacity\":s}),\"none\"!=i){r.attr({\"data-fill\":i}),l=a.hsl(i).darker().toString(),r.style({fill:l,opacity:1});var c={t:o.util.round(t[0]),r:o.util.round(t[1])};A&&(c.t=k[t[0]]);var u=\"t: \"+c.t+\", r: \"+c.r,f=this.getBoundingClientRect(),d=e.node().getBoundingClientRect(),h=[f.left+f.width/2-Z[0]-d.left,f.top+f.height/2-Z[1]-d.top];dt.config({color:l}).text(u),dt.move(h)}else i=r.style(\"stroke\"),r.attr({\"data-stroke\":i}),l=a.hsl(i).darker().toString(),r.style({stroke:l,opacity:1})}).on(\"mousemove.tooltip\",function(t,e){return 0!=a.event.which?!1:void(a.select(this).attr(\"data-fill\")&&dt.show())}).on(\"mouseout.tooltip\",function(t,e){dt.hide();var n=a.select(this),r=n.attr(\"data-fill\");r?n.style({fill:r,opacity:n.attr(\"data-opacity\")}):n.style({stroke:n.attr(\"data-stroke\"),opacity:n.attr(\"data-opacity\")})})}),d}var e,n,r,l,s={data:[],layout:{}},c={},u={},f=a.dispatch(\"hover\"),d={};return d.render=function(e){return t(e),this},d.config=function(t){if(!arguments.length)return s;var e=o.util.cloneJson(t);return e.data.forEach(function(t,e){s.data[e]||(s.data[e]={}),i(s.data[e],o.Axis.defaultConfig().data[0]),i(s.data[e],t)}),i(s.layout,o.Axis.defaultConfig().layout),i(s.layout,e.layout),this},d.getLiveConfig=function(){return u},d.getinputConfig=function(){return c},d.radialScale=function(t){return r},d.angularScale=function(t){return l},d.svg=function(){return e},a.rebind(d,f,\"on\"),d},o.Axis.defaultConfig=function(t,e){var n={data:[{t:[1,2,3,4],r:[10,11,12,13],name:\"Line1\",geometry:\"LinePlot\",color:null,strokeDash:\"solid\",strokeColor:null,strokeSize:\"1\",visibleInLegend:!0,opacity:1}],layout:{defaultColorRange:a.scale.category10().range(),title:null,height:450,width:500,margin:{top:40,right:40,bottom:40,left:40},font:{size:12,color:\"gray\",outlineColor:\"white\",family:\"Tahoma, sans-serif\"},direction:\"clockwise\",orientation:0,labelOffset:10,radialAxis:{domain:null,orientation:-45,ticksSuffix:\"\",visible:!0,gridLinesVisible:!0,tickOrientation:\"horizontal\",rewriteTicks:null},angularAxis:{domain:[0,360],ticksSuffix:\"\",visible:!0,gridLinesVisible:!0,labelsVisible:!0,tickOrientation:\"horizontal\",rewriteTicks:null,ticksCount:null,ticksStep:null},minorTicks:0,tickLength:null,tickColor:\"silver\",minorTickColor:\"#eee\",backgroundColor:\"none\",needsEndSpacing:null,showLegend:!0,legend:{reverseOrder:!1},opacity:1}};return n},o.util={},o.DATAEXTENT=\"dataExtent\",o.AREA=\"AreaChart\",o.LINE=\"LinePlot\",o.DOT=\"DotPlot\",o.BAR=\"BarChart\",o.util._override=function(t,e){for(var n in t)n in e&&(e[n]=t[n])},o.util._extend=function(t,e){for(var n in t)e[n]=t[n]},o.util._rndSnd=function(){return 2*Math.random()-1+(2*Math.random()-1)+(2*Math.random()-1)},o.util.dataFromEquation2=function(t,e){var n=e||6,r=a.range(0,360+n,n).map(function(e,n){var r=e*Math.PI/180,a=t(r);return[e,a]});return r},o.util.dataFromEquation=function(t,e,n){var r=e||6,o=[],i=[];a.range(0,360+r,r).forEach(function(e,n){var r=e*Math.PI/180,a=t(r);o.push(e),i.push(a)});var l={t:o,r:i};return n&&(l.name=n),l},o.util.ensureArray=function(t,e){if(\"undefined\"==typeof t)return null;var n=[].concat(t);return a.range(e).map(function(t,e){return n[e]||n[0]})},o.util.fillArrays=function(t,e,n){return e.forEach(function(e,r){t[e]=o.util.ensureArray(t[e],n)}),t},o.util.cloneJson=function(t){return JSON.parse(JSON.stringify(t))},o.util.validateKeys=function(t,e){\"string\"==typeof e&&(e=e.split(\".\"));var n=e.shift();return t[n]&&(!e.length||objHasKeys(t[n],e))},o.util.sumArrays=function(t,e){return a.zip(t,e).map(function(t,e){return a.sum(t)})},o.util.arrayLast=function(t){return t[t.length-1]},o.util.arrayEqual=function(t,e){for(var n=Math.max(t.length,e.length,1);n-- >=0&&t[n]===e[n];);return-2===n},o.util.flattenArray=function(t){for(var e=[];!o.util.arrayEqual(e,t);)e=t,t=[].concat.apply([],t);return t},o.util.deduplicate=function(t){return t.filter(function(t,e,n){return n.indexOf(t)==e})},o.util.convertToCartesian=function(t,e){var n=e*Math.PI/180,r=t*Math.cos(n),a=t*Math.sin(n);return[r,a]},o.util.round=function(t,e){var n=e||2,r=Math.pow(10,n);return Math.round(t*r)/r},o.util.getMousePos=function(t){var e=a.mouse(t.node()),n=e[0],r=e[1],o={};return o.x=n,o.y=r,o.pos=e,o.angle=180*(Math.atan2(r,n)+Math.PI)/Math.PI,o.radius=Math.sqrt(n*n+r*r),o},o.util.duplicatesCount=function(t){for(var e,n={},r={},a=0,o=t.length;o>a;a++)e=t[a],e in n?(n[e]++,r[e]=n[e]):n[e]=1;return r},o.util.duplicates=function(t){return Object.keys(o.util.duplicatesCount(t))},o.util.translator=function(t,e,n,r){if(r){var a=n.slice();n=e,e=a}var o=e.reduce(function(t,e){return\"undefined\"!=typeof t?t[e]:void 0},t);\"undefined\"!=typeof o&&(e.reduce(function(t,n,r){return\"undefined\"!=typeof t?(r===e.length-1&&delete t[n],t[n]):void 0},t),n.reduce(function(t,e,r){return\"undefined\"==typeof t[e]&&(t[e]={}),r===n.length-1&&(t[e]=o),t[e]},t))},o.PolyChart=function(){function t(){var t=n[0].geometryConfig,e=t.container;\"string\"==typeof e&&(e=a.select(e)),e.datum(n).each(function(e,n){function r(e,n){var r=t.radialScale(e[1]),a=(t.angularScale(e[0])+t.orientation)*Math.PI/180;return{r:r,t:a}}function o(t){var e=t.r*Math.cos(t.t),n=t.r*Math.sin(t.t);return{x:e,y:n}}var i=!!e[0].data.yStack,s=e.map(function(t,e){return i?a.zip(t.data.t[0],t.data.r[0],t.data.yStack[0]):a.zip(t.data.t[0],t.data.r[0])}),c=t.angularScale,u=t.radialScale.domain()[0],f={};f.bar=function(n,r,o){var i=e[o].data,l=t.radialScale(n[1])-t.radialScale(0),s=t.radialScale(n[2]||0),u=i.barWidth;a.select(this).attr({\"class\":\"mark bar\",d:\"M\"+[[l+s,-u/2],[l+s,u/2],[s,u/2],[s,-u/2]].join(\"L\")+\"Z\",transform:function(e,n){return\"rotate(\"+(t.orientation+c(e[0]))+\")\"}})},f.dot=function(t,n,i){var l=t[2]?[t[0],t[1]+t[2]]:t,s=a.svg.symbol().size(e[i].data.dotSize).type(e[i].data.dotType)(t,n);a.select(this).attr({\"class\":\"mark dot\",d:s,transform:function(t,e){var n=o(r(l));return\"translate(\"+[n.x,n.y]+\")\"}})};var d=a.svg.line.radial().interpolate(e[0].data.lineInterpolation).radius(function(e){return t.radialScale(e[1])}).angle(function(e){return t.angularScale(e[0])*Math.PI/180});f.line=function(n,r,o){var i=n[2]?s[o].map(function(t,e){return[t[0],t[1]+t[2]]}):s[o];if(a.select(this).each(f.dot).style({opacity:function(t,n){return+e[o].data.dotVisible},fill:v.stroke(n,r,o)}).attr({\"class\":\"mark dot\"}),!(r>0)){var l=a.select(this.parentNode).selectAll(\"path.line\").data([0]);l.enter().insert(\"path\"),l.attr({\"class\":\"line\",d:d(i),transform:function(e,n){return\"rotate(\"+(t.orientation+90)+\")\"},\"pointer-events\":\"none\"}).style({fill:function(t,e){return v.fill(n,r,o)},\"fill-opacity\":0,stroke:function(t,e){return v.stroke(n,r,o)},\"stroke-width\":function(t,e){return v[\"stroke-width\"](n,r,o)},\"stroke-dasharray\":function(t,e){return v[\"stroke-dasharray\"](n,r,o)},opacity:function(t,e){return v.opacity(n,r,o)},display:function(t,e){return v.display(n,r,o)}})}};var h=t.angularScale.range(),p=Math.abs(h[1]-h[0])/s[0].length*Math.PI/180,g=a.svg.arc().startAngle(function(t){return-p/2}).endAngle(function(t){return p/2}).innerRadius(function(e){return t.radialScale(u+(e[2]||0))}).outerRadius(function(e){return t.radialScale(u+(e[2]||0))+t.radialScale(e[1])});f.arc=function(e,n,r){a.select(this).attr({\"class\":\"mark arc\",d:g,transform:function(e,n){return\"rotate(\"+(t.orientation+c(e[0])+90)+\")\"}})};var v={fill:function(t,n,r){return e[r].data.color},stroke:function(t,n,r){return e[r].data.strokeColor},\"stroke-width\":function(t,n,r){return e[r].data.strokeSize+\"px\"},\"stroke-dasharray\":function(t,n,r){return l[e[r].data.strokeDash]},opacity:function(t,n,r){return e[r].data.opacity},display:function(t,n,r){return\"undefined\"==typeof e[r].data.visible||e[r].data.visible?\"block\":\"none\"}},m=a.select(this).selectAll(\"g.layer\").data(s);m.enter().append(\"g\").attr({\"class\":\"layer\"});var y=m.selectAll(\"path.mark\").data(function(t,e){return t});y.enter().append(\"path\").attr({\"class\":\"mark\"}),y.style(v).each(f[t.geometryType]),y.exit().remove(),m.exit().remove()})}var e,n=[o.PolyChart.defaultConfig()],r=a.dispatch(\"hover\"),l={solid:\"none\",dash:[5,2],dot:[2,5]};return t.config=function(t){return arguments.length?(t.forEach(function(t,e){n[e]||(n[e]={}),i(n[e],o.PolyChart.defaultConfig()),i(n[e],t)}),this):n},t.getColorScale=function(){return e},a.rebind(t,r,\"on\"),t},o.PolyChart.defaultConfig=function(){var t={data:{name:\"geom1\",t:[[1,2,3,4]],r:[[1,2,3,4]],dotType:\"circle\",dotSize:64,dotVisible:!1,barWidth:20,color:\"#ffa500\",strokeSize:1,strokeColor:\"silver\",strokeDash:\"solid\",opacity:1,index:0,visible:!0,visibleInLegend:!0},geometryConfig:{geometry:\"LinePlot\",geometryType:\"arc\",direction:\"clockwise\",orientation:0,container:\"body\",radialScale:null,angularScale:null,colorScale:a.scale.category20()}};return t},o.BarChart=function(){return o.PolyChart()},o.BarChart.defaultConfig=function(){var t={geometryConfig:{geometryType:\"bar\"}};return t},o.AreaChart=function(){return o.PolyChart()},o.AreaChart.defaultConfig=function(){var t={geometryConfig:{geometryType:\"arc\"}};return t},o.DotPlot=function(){ret" -, -"urn o.PolyChart()},o.DotPlot.defaultConfig=function(){var t={geometryConfig:{geometryType:\"dot\",dotType:\"circle\"}};return t},o.LinePlot=function(){return o.PolyChart()},o.LinePlot.defaultConfig=function(){var t={geometryConfig:{geometryType:\"line\"}};return t},o.Legend=function(){function t(){var n=e.legendConfig,r=e.data.map(function(t,e){return[].concat(t).map(function(t,r){var a=i({},n.elements[e]);return a.name=t,a.color=[].concat(n.elements[e].color)[r],a})}),o=a.merge(r);o=o.filter(function(t,e){return n.elements[e]&&(n.elements[e].visibleInLegend||\"undefined\"==typeof n.elements[e].visibleInLegend)}),n.reverseOrder&&(o=o.reverse());var l=n.container;(\"string\"==typeof l||l.nodeName)&&(l=a.select(l));var s=o.map(function(t,e){return t.color}),c=n.fontSize,u=null==n.isContinuous?\"number\"==typeof o[0]:n.isContinuous,f=u?n.height:c*o.length,d=l.classed(\"legend-group\",!0),h=d.selectAll(\"svg\").data([0]),p=h.enter().append(\"svg\").attr({width:300,height:f+c,xmlns:\"http://www.w3.org/2000/svg\",\"xmlns:xlink\":\"http://www.w3.org/1999/xlink\",version:\"1.1\"});p.append(\"g\").classed(\"legend-axis\",!0),p.append(\"g\").classed(\"legend-marks\",!0);var g=a.range(o.length),v=a.scale[u?\"linear\":\"ordinal\"]().domain(g).range(s),m=a.scale[u?\"linear\":\"ordinal\"]().domain(g)[u?\"range\":\"rangePoints\"]([0,f]),y=function(t,e){var n=3*e;return\"line\"===t?\"M\"+[[-e/2,-e/12],[e/2,-e/12],[e/2,e/12],[-e/2,e/12]]+\"Z\":-1!=a.svg.symbolTypes.indexOf(t)?a.svg.symbol().type(t).size(n)():a.svg.symbol().type(\"square\").size(n)()};if(u){var x=h.select(\".legend-marks\").append(\"defs\").append(\"linearGradient\").attr({id:\"grad1\",x1:\"0%\",y1:\"0%\",x2:\"0%\",y2:\"100%\"}).selectAll(\"stop\").data(s);x.enter().append(\"stop\"),x.attr({offset:function(t,e){return e/(s.length-1)*100+\"%\"}}).style({\"stop-color\":function(t,e){return t}}),h.append(\"rect\").classed(\"legend-mark\",!0).attr({height:n.height,width:n.colorBandWidth,fill:\"url(#grad1)\"})}else{var b=h.select(\".legend-marks\").selectAll(\"path.legend-mark\").data(o);b.enter().append(\"path\").classed(\"legend-mark\",!0),b.attr({transform:function(t,e){return\"translate(\"+[c/2,m(e)+c/2]+\")\"},d:function(t,e){var n=t.symbol;return y(n,c)},fill:function(t,e){return v(e)}}),b.exit().remove()}var _=a.svg.axis().scale(m).orient(\"right\"),w=h.select(\"g.legend-axis\").attr({transform:\"translate(\"+[u?n.colorBandWidth:c,c/2]+\")\"}).call(_);return w.selectAll(\".domain\").style({fill:\"none\",stroke:\"none\"}),w.selectAll(\"line\").style({fill:\"none\",stroke:u?n.textColor:\"none\"}),w.selectAll(\"text\").style({fill:n.textColor,\"font-size\":n.fontSize}).text(function(t,e){return o[e].name}),t}var e=o.Legend.defaultConfig(),n=a.dispatch(\"hover\");return t.config=function(t){return arguments.length?(i(e,t),this):e},a.rebind(t,n,\"on\"),t},o.Legend.defaultConfig=function(t,e){var n={data:[\"a\",\"b\",\"c\"],legendConfig:{elements:[{symbol:\"line\",color:\"red\"},{symbol:\"square\",color:\"yellow\"},{symbol:\"diamond\",color:\"limegreen\"}],height:150,colorBandWidth:30,fontSize:12,container:\"body\",isContinuous:null,textColor:\"grey\",reverseOrder:!1}};return n},o.tooltipPanel=function(){var t,e,n,r={container:null,hasTick:!1,fontSize:12,color:\"white\",padding:5},l=\"tooltip-\"+o.tooltipPanel.uid++,s=10,c=function(){t=r.container.selectAll(\"g.\"+l).data([0]);var a=t.enter().append(\"g\").classed(l,!0).style({\"pointer-events\":\"none\",display:\"none\"});return n=a.append(\"path\").style({fill:\"white\",\"fill-opacity\":.9}).attr({d:\"M0 0\"}),e=a.append(\"text\").attr({dx:r.padding+s,dy:.3*+r.fontSize}),c};return c.text=function(o){var i=a.hsl(r.color).l,l=i>=.5?\"#aaa\":\"white\",u=i>=.5?\"black\":\"white\",f=o||\"\";e.style({fill:u,\"font-size\":r.fontSize+\"px\"}).text(f);var d=r.padding,h=e.node().getBBox(),p={fill:r.color,stroke:l,\"stroke-width\":\"2px\"},g=h.width+2*d+s,v=h.height+2*d;return n.attr({d:\"M\"+[[s,-v/2],[s,-v/4],[r.hasTick?0:s,0],[s,v/4],[s,v/2],[g,v/2],[g,-v/2]].join(\"L\")+\"Z\"}).style(p),t.attr({transform:\"translate(\"+[s,-v/2+2*d]+\")\"}),t.style({display:\"block\"}),c},c.move=function(e){return t?(t.attr({transform:\"translate(\"+[e[0],e[1]]+\")\"}).style({display:\"block\"}),c):void 0},c.hide=function(){return t?(t.style({display:\"none\"}),c):void 0},c.show=function(){return t?(t.style({display:\"block\"}),c):void 0},c.config=function(t){return i(r,t),c},c},o.tooltipPanel.uid=1,o.adapter={},o.adapter.plotly=function(){var t={};return t.convert=function(t,e){var n={};if(t.data&&(n.data=t.data.map(function(t,n){var r=i({},t),a=[[r,[\"marker\",\"color\"],[\"color\"]],[r,[\"marker\",\"opacity\"],[\"opacity\"]],[r,[\"marker\",\"line\",\"color\"],[\"strokeColor\"]],[r,[\"marker\",\"line\",\"dash\"],[\"strokeDash\"]],[r,[\"marker\",\"line\",\"width\"],[\"strokeSize\"]],[r,[\"marker\",\"symbol\"],[\"dotType\"]],[r,[\"marker\",\"size\"],[\"dotSize\"]],[r,[\"marker\",\"barWidth\"],[\"barWidth\"]],[r,[\"line\",\"interpolation\"],[\"lineInterpolation\"]],[r,[\"showlegend\"],[\"visibleInLegend\"]]];return a.forEach(function(t,n){o.util.translator.apply(null,t.concat(e))}),e||delete r.marker,e&&delete r.groupId,e?(\"LinePlot\"===r.geometry?(r.type=\"scatter\",r.dotVisible===!0?(delete r.dotVisible,r.mode=\"lines+markers\"):r.mode=\"lines\"):\"DotPlot\"===r.geometry?(r.type=\"scatter\",r.mode=\"markers\"):\"AreaChart\"===r.geometry?r.type=\"area\":\"BarChart\"===r.geometry&&(r.type=\"bar\"),delete r.geometry):(\"scatter\"===r.type?\"lines\"===r.mode?r.geometry=\"LinePlot\":\"markers\"===r.mode?r.geometry=\"DotPlot\":\"lines+markers\"===r.mode&&(r.geometry=\"LinePlot\",r.dotVisible=!0):\"area\"===r.type?r.geometry=\"AreaChart\":\"bar\"===r.type&&(r.geometry=\"BarChart\"),delete r.mode,delete r.type),r}),!e&&t.layout&&\"stack\"===t.layout.barmode)){var r=o.util.duplicates(n.data.map(function(t,e){return t.geometry}));n.data.forEach(function(t,e){var a=r.indexOf(t.geometry);-1!=a&&(n.data[e].groupId=a)})}if(t.layout){var l=i({},t.layout),s=[[l,[\"plot_bgcolor\"],[\"backgroundColor\"]],[l,[\"showlegend\"],[\"showLegend\"]],[l,[\"radialaxis\"],[\"radialAxis\"]],[l,[\"angularaxis\"],[\"angularAxis\"]],[l.angularaxis,[\"showline\"],[\"gridLinesVisible\"]],[l.angularaxis,[\"showticklabels\"],[\"labelsVisible\"]],[l.angularaxis,[\"nticks\"],[\"ticksCount\"]],[l.angularaxis,[\"tickorientation\"],[\"tickOrientation\"]],[l.angularaxis,[\"ticksuffix\"],[\"ticksSuffix\"]],[l.angularaxis,[\"range\"],[\"domain\"]],[l.angularaxis,[\"endpadding\"],[\"endPadding\"]],[l.radialaxis,[\"showline\"],[\"gridLinesVisible\"]],[l.radialaxis,[\"tickorientation\"],[\"tickOrientation\"]],[l.radialaxis,[\"ticksuffix\"],[\"ticksSuffix\"]],[l.radialaxis,[\"range\"],[\"domain\"]],[l.angularAxis,[\"showline\"],[\"gridLinesVisible\"]],[l.angularAxis,[\"showticklabels\"],[\"labelsVisible\"]],[l.angularAxis,[\"nticks\"],[\"ticksCount\"]],[l.angularAxis,[\"tickorientation\"],[\"tickOrientation\"]],[l.angularAxis,[\"ticksuffix\"],[\"ticksSuffix\"]],[l.angularAxis,[\"range\"],[\"domain\"]],[l.angularAxis,[\"endpadding\"],[\"endPadding\"]],[l.radialAxis,[\"showline\"],[\"gridLinesVisible\"]],[l.radialAxis,[\"tickorientation\"],[\"tickOrientation\"]],[l.radialAxis,[\"ticksuffix\"],[\"ticksSuffix\"]],[l.radialAxis,[\"range\"],[\"domain\"]],[l.font,[\"outlinecolor\"],[\"outlineColor\"]],[l.legend,[\"traceorder\"],[\"reverseOrder\"]],[l,[\"labeloffset\"],[\"labelOffset\"]],[l,[\"defaultcolorrange\"],[\"defaultColorRange\"]]];if(s.forEach(function(t,n){o.util.translator.apply(null,t.concat(e))}),e?(\"undefined\"!=typeof l.tickLength&&(l.angularaxis.ticklen=l.tickLength,delete l.tickLength),l.tickColor&&(l.angularaxis.tickcolor=l.tickColor,delete l.tickColor)):(l.angularAxis&&\"undefined\"!=typeof l.angularAxis.ticklen&&(l.tickLength=l.angularAxis.ticklen),l.angularAxis&&\"undefined\"!=typeof l.angularAxis.tickcolor&&(l.tickColor=l.angularAxis.tickcolor)),l.legend&&\"boolean\"!=typeof l.legend.reverseOrder&&(l.legend.reverseOrder=\"normal\"!=l.legend.reverseOrder),l.legend&&\"boolean\"==typeof l.legend.traceorder&&(l.legend.traceorder=l.legend.traceorder?\"reversed\":\"normal\",delete l.legend.reverseOrder),l.margin&&\"undefined\"!=typeof l.margin.t){var c=[\"t\",\"r\",\"b\",\"l\",\"pad\"],u=[\"top\",\"right\",\"bottom\",\"left\",\"pad\"],f={};a.entries(l.margin).forEach(function(t,e){f[u[c.indexOf(t.key)]]=t.value}),l.margin=f}e&&(delete l.needsEndSpacing,delete l.minorTickColor,delete l.minorTicks,delete l.angularaxis.ticksCount,delete l.angularaxis.ticksCount,delete l.angularaxis.ticksStep,delete l.angularaxis.rewriteTicks,delete l.angularaxis.nticks,delete l.radialaxis.ticksCount,delete l.radialaxis.ticksCount,delete l.radialaxis.ticksStep,delete l.radialaxis.rewriteTicks,delete l.radialaxis.nticks),n.layout=l}return n},t}},{\"../../plotly\":107,\"./micropolar_manager\":134,d3:9}],134:[function(t,e,n){\"use strict\";var r=t(\"../../plotly\"),a=t(\"d3\"),o=t(\"./undo_manager\"),i=e.exports={},l=r.Lib.extendDeepAll;i.framework=function(t){function e(e,o){return o&&(f=o),a.select(a.select(f).node().parentNode).selectAll(\".svg-container>*:not(.chart-root)\").remove(),n=n?l(n,e):e,c||(c=r.micropolar.Axis()),u=r.micropolar.adapter.plotly().convert(n),c.config(u).render(f),t.data=n.data,t.layout=n.layout,i.fillLayout(t),n}var n,s,c,u,f,d=new o;return e.isPolar=!0,e.svg=function(){return c.svg()},e.getConfig=function(){return n},e.getLiveConfig=function(){return r.micropolar.adapter.plotly().convert(c.getLiveConfig(),!0)},e.getLiveScales=function(){return{t:c.angularScale(),r:c.radialScale()}},e.setUndoPoint=function(){var t=this,e=r.micropolar.util.cloneJson(n);!function(e,n){d.add({undo:function(){n&&t(n)},redo:function(){t(e)}})}(e,s),s=r.micropolar.util.cloneJson(e)},e.undo=function(){d.undo()},e.redo=function(){d.redo()},e},i.fillLayout=function(t){var e=a.select(t).selectAll(\".plot-container\"),n=e.selectAll(\".svg-container\"),o=t.framework&&t.framework.svg&&t.framework.svg(),i={width:800,height:600,paper_bgcolor:r.Color.background,_container:e,_paperdiv:n,_paper:o};t._fullLayout=l(i,t.layout)}},{\"../../plotly\":107,\"./undo_manager\":135,d3:9}],135:[function(t,e,n){\"use strict\";e.exports=function(){function t(t,e){return t?(a=!0,t[e](),a=!1,this):this}var e,n=[],r=-1,a=!1;return{add:function(t){return a?this:(n.splice(r+1,n.length-r),n.push(t),r=n.length-1,this)},setCallback:function(t){e=t},undo:function(){var a=n[r];return a?(t(a,\"undo\"),r-=1,e&&e(a.undo),thi" -, -"s):this},redo:function(){var a=n[r+1];return a?(t(a,\"redo\"),r+=1,e&&e(a.redo),this):this},clear:function(){n=[],r=-1},hasUndo:function(){return-1!==r},hasRedo:function(){return r<n.length-1},getCommands:function(){return n},getPreviousCommand:function(){return n[r-1]},getIndex:function(){return r}}}},{}],136:[function(t,e,n){\"use strict\";function r(t){var e;switch(t){case\"themes__thumb\":e={autosize:!0,width:150,height:150,title:\"\",showlegend:!1,margin:{l:5,r:5,t:5,b:5,pad:0},annotations:[]};break;case\"thumbnail\":e={title:\"\",hidesources:!0,showlegend:!1,borderwidth:0,bordercolor:\"\",margin:{l:1,r:1,t:1,b:1,pad:0},annotations:[]};break;default:e={}}return e}function a(t){var e=[\"xaxis\",\"yaxis\",\"zaxis\"];return e.indexOf(t.slice(0,5))>-1}var o=t(\"../plotly\"),i=o.Lib.extendFlat,l=o.Lib.extendDeep;e.exports=function(t,e){t.framework&&t.framework.isPolar&&(t=t.framework.getConfig());var n,s=t.data,c=t.layout,u=l([],s),f=l({},c,r(e.tileClass));if(e.width&&(f.width=e.width),e.height&&(f.height=e.height),\"thumbnail\"===e.tileClass||\"themes__thumb\"===e.tileClass){f.annotations=[];var d=Object.keys(f);for(n=0;n<d.length;n++)a(d[n])&&(f[d[n]].title=\"\");for(n=0;n<u.length;n++){var h=u[n];h.showscale=!1,h.marker&&(h.marker.showscale=!1),\"pie\"===h.type&&(h.textposition=\"none\")}}if(Array.isArray(e.annotations))for(n=0;n<e.annotations.length;n++)f.annotations.push(e.annotations[n]);var p=o.Plots.getSubplotIds(f,\"gl3d\");if(p.length){var g={};for(\"thumbnail\"===e.tileClass&&(g={title:\"\",showaxeslabels:!1,showticklabels:!1,linetickenable:!1}),n=0;n<p.length;n++){var v=p[n];i(f[v].xaxis,g),i(f[v].yaxis,g),i(f[v].zaxis,g),f[v]._scene=null}}var m=document.createElement(\"div\");e.tileClass&&(m.className=e.tileClass);var y={td:m,layout:f,data:u,config:{staticPlot:void 0===e.staticPlot?!0:e.staticPlot,plotGlPixelRatio:void 0===e.plotGlPixelRatio?2:e.plotGlPixelRatio,displaylogo:e.displaylogo||!1,showLink:e.showLink||!1,showTips:e.showTips||!1}};return\"transparent\"!==e.setBackground&&(y.config.setBackground=e.setBackground||\"opaque\"),y.td.defaultLayout=r(e.tileClass),y}},{\"../plotly\":107}],137:[function(t,e,n){\"use strict\";function r(t,e){return e=e||{},e.format=e.format||\"png\",new Promise(function(n,r){t._snapshotInProgress&&r(new Error(\"Snapshotting already in progress.\")),o.isIE()&&\"svg\"!==e.format&&r(new Error(\"Sorry IE does not support downloading from canvas. Try {format:'svg'} instead.\")),t._snapshotInProgress=!0;var l=a(t,e),s=e.filename||t.fn||\"newplot\";s+=\".\"+e.format,l.then(function(e){return t._snapshotInProgress=!1,i(e,s)}).then(function(t){n(t)}).catch(function(e){t._snapshotInProgress=!1,r(e)})})}var a=t(\"../plot_api/to_image\"),o=t(\"../lib\"),i=t(\"./filesaver\");e.exports=r},{\"../lib\":89,\"../plot_api/to_image\":105,\"./filesaver\":138}],138:[function(t,e,n){\"use strict\";var r=function(t,e){var n=document.createElement(\"a\"),r=\"download\"in n,a=/Version\\/[\\d\\.]+.*Safari/.test(navigator.userAgent),o=new Promise(function(o,i){\"undefined\"!=typeof navigator&&/MSIE [1-9]\\./.test(navigator.userAgent)&&i(new Error(\"IE < 10 unsupported\")),a&&(document.location.href=\"data:application/octet-stream\"+t.slice(t.search(/[,;]/)),o(e)),e||(e=\"download\"),r&&(n.href=t,n.download=e,document.body.appendChild(n),n.click(),document.body.removeChild(n),o(e)),\"undefined\"!=typeof navigator&&navigator.msSaveBlob&&(navigator.msSaveBlob(new Blob([t]),e),o(e)),i(new Error(\"download error\"))});return o};e.exports=r},{}],139:[function(t,e,n){\"use strict\";function r(t){return t._has&&(t._has(\"gl3d\")||t._has(\"gl2d\"))?500:0}function a(t){return t.data&&t.data[0]&&t.data[0].r?void 0:function(){(t.calcdata||[]).forEach(function(t){t[0]&&t[0].t&&t[0].t.cb&&t[0].t.cb()})}}var o={getDelay:r,getRedrawFunc:a,clone:t(\"./cloneplot\"),toSVG:t(\"./tosvg\"),svgToImg:t(\"./svgtoimg\"),toImage:t(\"./toimage\"),downloadImage:t(\"./download\")};e.exports=o},{\"./cloneplot\":136,\"./download\":137,\"./svgtoimg\":140,\"./toimage\":141,\"./tosvg\":142}],140:[function(t,e,n){\"use strict\";function r(t){var e=t.emitter||new o,n=new Promise(function(r,o){var i=window.Image,l=t.svg,s=t.format||\"png\";if(a.isIE()&&(l=l.replace(/\"/gi,\"'\"),l=l.replace(/(\\('#)(.*)('\\))/gi,'(\"$2\")'),l=l.replace(/(\\\\')/gi,'\"'),\"svg\"!==s)){var c=new Error(\"Sorry IE does not support downloading from canvas. Try {format:'svg'} instead.\");return o(c),t.promise?n:e.emit(\"error\",c)}var u=t.canvas,f=u.getContext(\"2d\"),d=new i,h=\"data:image/svg+xml,\"+encodeURIComponent(l);u.height=t.height||150,u.width=t.width||300,d.onload=function(){var n;switch(\"svg\"!==s&&f.drawImage(d,0,0),s){case\"jpeg\":n=u.toDataURL(\"image/jpeg\");break;case\"png\":n=u.toDataURL(\"image/png\");break;case\"webp\":n=u.toDataURL(\"image/webp\");break;case\"svg\":n=h;break;default:if(o(new Error(\"Image format is not jpeg, png or svg\")),!t.promise)return e.emit(\"error\",\"Image format is not jpeg, png or svg\")}r(n),t.promise||e.emit(\"success\",n)},d.onerror=function(n){return o(n),t.promise?void 0:e.emit(\"error\",n)},d.src=h});return t.promise?n:e}var a=t(\"../lib\"),o=t(\"events\").EventEmitter;e.exports=r},{\"../lib\":89,events:7}],141:[function(t,e,n){\"use strict\";function r(t,e){function n(){var t=r.getDelay(c._fullLayout);setTimeout(function(){var t=o.Snapshot.toSVG(c),n=document.createElement(\"canvas\");n.id=i.randstr(),l=o.Snapshot.svgToImg({format:e.format,width:c._fullLayout.width,height:c._fullLayout.height,canvas:n,emitter:l,svg:t}),l.clean=function(){c&&document.body.removeChild(c)}},t)}var r=o.Snapshot,l=new a,s=r.clone(t,{format:\"png\"}),c=s.td;c.style.position=\"absolute\",c.style.left=\"-5000px\",document.body.appendChild(c);var u=r.getRedrawFunc(c);return o.plot(c,s.data,s.layout,s.config).then(u).then(n).catch(function(t){l.emit(\"error\",t)}),l}var a=t(\"events\").EventEmitter,o=t(\"../plotly\"),i=t(\"../lib\");e.exports=r},{\"../lib\":89,\"../plotly\":107,events:7}],142:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"../lib/svg_text_utils\"),o=t(\"../components/drawing\"),i=t(\"../components/color\"),l=t(\"../constants/xmlns_namespaces\");e.exports=function(t,e){var n,s=t._fullLayout,c=s._paper,u=s._toppaper;c.insert(\"rect\",\":first-child\").call(o.setRect,0,0,s.width,s.height).call(i.fill,s.paper_bgcolor);var f=s._basePlotModules||[];for(n=0;n<f.length;n++){var d=f[n];d.toSVG&&d.toSVG(t)}if(u){var h=u.node().childNodes,p=Array.prototype.slice.call(h);for(n=0;n<p.length;n++){var g=p[n];g.childNodes.length&&c.node().appendChild(g)}}s._draggers&&s._draggers.remove(),c.node().style.background=\"\",c.selectAll(\"text\").attr(\"data-unformatted\",null).each(function(){var t=r.select(this);if(\"hidden\"===t.style(\"visibility\"))return void t.remove();var e=t.style(\"font-family\");e&&-1!==e.indexOf('\"')&&t.style(\"font-family\",e.replace(/\"/g,\"TOBESTRIPPED\"))}),\"pdf\"!==e&&\"eps\"!==e||c.selectAll(\"#MathJax_SVG_glyphs path\").attr(\"stroke-width\",0),c.node().setAttributeNS(l.xmlns,\"xmlns\",l.svg),c.node().setAttributeNS(l.xmlns,\"xmlns:xlink\",l.xlink);var v=(new window.XMLSerializer).serializeToString(c.node());return v=a.html_entity_decode(v),v=a.xml_entity_encode(v),v=v.replace(/(\"TOBESTRIPPED)|(TOBESTRIPPED\")/g,\"'\")}},{\"../components/color\":18,\"../components/drawing\":41,\"../constants/xmlns_namespaces\":82,\"../lib/svg_text_utils\":100,d3:9}],143:[function(t,e,n){\"use strict\";var r=t(\"../../lib\").mergeArray;e.exports=function(t){var e=t[0].trace,n=e.marker,a=n.line;r(e.text,t,\"tx\"),r(n.opacity,t,\"mo\"),r(n.color,t,\"mc\"),r(a.color,t,\"mlc\"),r(a.width,t,\"mlw\")}},{\"../../lib\":89}],144:[function(t,e,n){\"use strict\";var r=t(\"../scatter/attributes\"),a=t(\"../../components/colorscale/color_attributes\"),o=t(\"../../lib/extend\").extendFlat,i=r.marker,l=i.line,s=o({},l.width,{dflt:0}),c=o({},{width:s},a(\"marker.line\")),u=o({},{showscale:i.showscale,line:c},a(\"marker\"));e.exports={x:r.x,x0:r.x0,dx:r.dx,y:r.y,y0:r.y0,dy:r.dy,text:r.text,orientation:{valType:\"enumerated\",values:[\"v\",\"h\"]},marker:u,r:r.r,t:r.t,_nestedModules:{error_y:\"ErrorBars\",error_x:\"ErrorBars\",\"marker.colorbar\":\"Colorbar\"},_deprecated:{bardir:{valType:\"enumerated\",values:[\"v\",\"h\"]}}}},{\"../../components/colorscale/color_attributes\":26,\"../../lib/extend\":88,\"../scatter/attributes\":167}],145:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\"),a=t(\"../../plots/cartesian/axes\"),o=t(\"../../components/colorscale/has_colorscale\"),i=t(\"../../components/colorscale/calc\");e.exports=function(t,e){var n,l,s,c=a.getFromId(t,e.xaxis||\"x\"),u=a.getFromId(t,e.yaxis||\"y\"),f=e.orientation||(e.x&&!e.y?\"h\":\"v\");\"h\"===f?(l=c.makeCalcdata(e,\"x\"),n=u.makeCalcdata(e,\"y\")):(l=u.makeCalcdata(e,\"y\"),n=c.makeCalcdata(e,\"x\"));var d=Math.min(n.length,l.length),h=[];for(s=0;d>s;s++)r(n[s])&&h.push({p:n[s],s:l[s],b:0});return o(e,\"marker\")&&i(e,e.marker.color,\"marker\",\"c\"),o(e,\"marker.line\")&&i(e,e.marker.line.color,\"marker.line\",\"c\"),h}},{\"../../components/colorscale/calc\":25,\"../../components/colorscale/has_colorscale\":31,\"../../plots/cartesian/axes\":110,\"fast-isnumeric\":11}],146:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"../../components/color\"),o=t(\"../scatter/xy_defaults\"),i=t(\"../bar/style_defaults\"),l=t(\"../../components/errorbars/defaults\"),s=t(\"./attributes\");e.exports=function(t,e,n,c){function u(n,a){return r.coerce(t,e,s,n,a)}var f=o(t,e,u);return f?(u(\"orientation\",e.x&&!e.y?\"h\":\"v\"),u(\"text\"),i(t,e,u,n,c),l(t,e,a.defaultLine,{axis:\"y\"}),void l(t,e,a.defaultLine,{axis:\"x\",inherit:\"y\"})):void(e.visible=!1)}},{\"../../components/color\":18,\"../../components/errorbars/defaults\":46,\"../../lib\":89,\"../bar/style_defaults\":154,\"../scatter/xy_defaults\":188,\"./attributes\":144}],147:[function(t,e,n){\"use strict\";var r=t(\"../../plots/cartesian/graph_interact\"),a=t(\"../../components/errorbars\"),o=t(\"../../components/color\");e.exports=function(t,e,n,i){var l,s=t.cd,c=s[0].trace,u=s[0].t,f=t.xa,d=t.ya,h=\"closest\"===i?u.barwidth/2:u.dbar*(1-f._gd._fullLayout.bargap)/2;l=\"closest\"!==i?function(t){return t.p}:\"h\"===c.orientation?function(t){return t.y}:function(t){return t.x};var p,g;\"h\"===c.orientation?(p=function(t){return r.inbox(t.b-e,t.x-e)+(t.x-e)/(t.x-t.b)},g=function(t){var e=l(t)-n;ret" -, -"urn r.inbox(e-h,e+h)}):(g=function(t){return r.inbox(t.b-n,t.y-n)+(t.y-n)/(t.y-t.b)},p=function(t){var n=l(t)-e;return r.inbox(n-h,n+h)});var v=r.getDistanceFunction(i,p,g);if(r.getClosest(s,v,t),t.index!==!1){var m=s[t.index],y=m.mcc||c.marker.color,x=m.mlcc||c.marker.line.color,b=m.mlw||c.marker.line.width;return o.opacity(y)?t.color=y:o.opacity(x)&&b&&(t.color=x),\"h\"===c.orientation?(t.x0=t.x1=f.c2p(m.x,!0),t.xLabelVal=m.s,t.y0=d.c2p(l(m)-h,!0),t.y1=d.c2p(l(m)+h,!0),t.yLabelVal=m.p):(t.y0=t.y1=d.c2p(m.y,!0),t.yLabelVal=m.s,t.x0=f.c2p(l(m)-h,!0),t.x1=f.c2p(l(m)+h,!0),t.xLabelVal=m.p),m.tx&&(t.text=m.tx),a.hoverInfo(m,c,t),[t]}}},{\"../../components/color\":18,\"../../components/errorbars\":47,\"../../plots/cartesian/graph_interact\":117}],148:[function(t,e,n){\"use strict\";var r={};r.attributes=t(\"./attributes\"),r.layoutAttributes=t(\"./layout_attributes\"),r.supplyDefaults=t(\"./defaults\"),r.supplyLayoutDefaults=t(\"./layout_defaults\"),r.calc=t(\"./calc\"),r.setPositions=t(\"./set_positions\"),r.colorbar=t(\"../scatter/colorbar\"),r.arraysToCalcdata=t(\"./arrays_to_calcdata\"),r.plot=t(\"./plot\"),r.style=t(\"./style\"),r.hoverPoints=t(\"./hover\"),r.moduleType=\"trace\",r.name=\"bar\",r.basePlotModule=t(\"../../plots/cartesian\"),r.categories=[\"cartesian\",\"bar\",\"oriented\",\"markerColorscale\",\"errorBarsOK\",\"showLegend\"],r.meta={},e.exports=r},{\"../../plots/cartesian\":118,\"../scatter/colorbar\":170,\"./arrays_to_calcdata\":143,\"./attributes\":144,\"./calc\":145,\"./defaults\":146,\"./hover\":147,\"./layout_attributes\":149,\"./layout_defaults\":150,\"./plot\":151,\"./set_positions\":152,\"./style\":153}],149:[function(t,e,n){\"use strict\";e.exports={barmode:{valType:\"enumerated\",values:[\"stack\",\"group\",\"overlay\",\"relative\"],dflt:\"group\"},barnorm:{valType:\"enumerated\",values:[\"\",\"fraction\",\"percent\"],dflt:\"\"},bargap:{valType:\"number\",min:0,max:1},bargroupgap:{valType:\"number\",min:0,max:1,dflt:0}}},{}],150:[function(t,e,n){\"use strict\";var r=t(\"../../plots/plots\"),a=t(\"../../plots/cartesian/axes\"),o=t(\"../../lib\"),i=t(\"./layout_attributes\");\n" -, -"e.exports=function(t,e,n){function l(n,r){return o.coerce(t,e,i,n,r)}for(var s=!1,c=!1,u=!1,f={},d=0;d<n.length;d++){var h=n[d];if(r.traceIs(h,\"bar\")){if(s=!0,\"overlay\"!==t.barmode&&\"stack\"!==t.barmode){var p=h.xaxis+h.yaxis;f[p]&&(u=!0),f[p]=!0}if(h.visible&&\"histogram\"===h.type){var g=a.getFromId({_fullLayout:e},h[\"v\"===h.orientation?\"xaxis\":\"yaxis\"]);\"category\"!==g.type&&(c=!0)}}}if(s){var v=l(\"barmode\");\"overlay\"!==v&&l(\"barnorm\"),l(\"bargap\",c&&!u?0:.2),l(\"bargroupgap\")}}},{\"../../lib\":89,\"../../plots/cartesian/axes\":110,\"../../plots/plots\":130,\"./layout_attributes\":149}],151:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"fast-isnumeric\"),o=t(\"../../lib\"),i=t(\"../../components/color\"),l=t(\"../../components/errorbars\"),s=t(\"./arrays_to_calcdata\");e.exports=function(t,e,n){var c=e.x(),u=e.y(),f=t._fullLayout,d=e.plot.select(\".barlayer\").selectAll(\"g.trace.bars\").data(n).enter().append(\"g\").attr(\"class\",\"trace bars\");d.append(\"g\").attr(\"class\",\"points\").each(function(e){var n=e[0].t,l=e[0].trace;s(e),r.select(this).selectAll(\"path\").data(o.identity).enter().append(\"path\").each(function(e){function o(t){return 0===f.bargap&&0===f.bargroupgap?r.round(Math.round(t)-m,2):t}function s(t,e){return Math.abs(t-e)>=2?o(t):t>e?Math.ceil(t):Math.floor(t)}var d,h,p,g;if(\"h\"===l.orientation?(p=u.c2p(n.poffset+e.p,!0),g=u.c2p(n.poffset+e.p+n.barwidth,!0),d=c.c2p(e.b,!0),h=c.c2p(e.s+e.b,!0)):(d=c.c2p(n.poffset+e.p,!0),h=c.c2p(n.poffset+e.p+n.barwidth,!0),g=u.c2p(e.s+e.b,!0),p=u.c2p(e.b,!0)),!(a(d)&&a(h)&&a(p)&&a(g)&&d!==h&&p!==g))return void r.select(this).remove();var v=(e.mlw+1||l.marker.line.width+1||(e.trace?e.trace.marker.line.width:0)+1)-1,m=r.round(v/2%1,2);if(!t._context.staticPlot){var y=i.opacity(e.mc||l.marker.color),x=1>y||v>.01?o:s;d=x(d,h),h=x(h,d),p=x(p,g),g=x(g,p)}r.select(this).attr(\"d\",\"M\"+d+\",\"+p+\"V\"+g+\"H\"+h+\"V\"+p+\"Z\")})}),d.call(l.plot,e)}},{\"../../components/color\":18,\"../../components/errorbars\":47,\"../../lib\":89,\"./arrays_to_calcdata\":143,d3:9,\"fast-isnumeric\":11}],152:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\"),a=t(\"../../plots/plots\"),o=t(\"../../plots/cartesian/axes\"),i=t(\"../../lib\");e.exports=function(t,e){var n,l,s=t._fullLayout,c=e.x(),u=e.y();[\"v\",\"h\"].forEach(function(f){function d(e){function n(t){t[p]=t.p+d}var r=[];e.forEach(function(e){t.calcdata[e].forEach(function(t){r.push(t.p)})});var a=i.distinctVals(r),l=a.vals,c=a.minDiff,u=!1,f=[];\"group\"===s.barmode&&e.forEach(function(e){u||(t.calcdata[e].forEach(function(t){u||f.forEach(function(e){Math.abs(t.p-e)<c&&(u=!0)})}),u||t.calcdata[e].forEach(function(t){f.push(t.p)}))}),o.minDtick(v,c,l[0],u),o.expand(v,l,{vpad:c/2}),c*=1-s.bargap,u&&(c/=h.length);for(var d,g=0;g<e.length;g++){var m=t.calcdata[e[g]][0].t;m.barwidth=c*(1-s.bargroupgap),m.poffset=((u?(2*g+1-e.length)*c:0)-m.barwidth)/2,m.dbar=a.minDiff,d=m.poffset+m.barwidth/2,t.calcdata[e[g]].forEach(n)}}var h=[],p={v:\"x\",h:\"y\"}[f],g={v:\"y\",h:\"x\"}[f],v=e[p](),m=e[g]();if(t._fullData.forEach(function(t,e){t.visible===!0&&a.traceIs(t,\"bar\")&&t.orientation===f&&t.xaxis===c._id&&t.yaxis===u._id&&h.push(e)}),h.length){\"overlay\"===s.barmode?h.forEach(function(t){d([t])}):d(h);var y=\"stack\"===s.barmode,x=\"relative\"===s.barmode,b=s.barnorm;if(y||x||b){var _,w,k,M=m.l2c(m.c2l(0)),A=M,L={},T=t.calcdata[h[0]][0].t.barwidth/100,z=0,S=!0;for(n=0;n<h.length;n++)for(w=t.calcdata[h[n]],l=0;l<w.length;l++)if(r(w[l].s)){z=Math.round(w[l].p/T),x&&w[l].s<0&&(z=\"-\"+z);var E=L[z]||0;(y||x)&&(w[l].b=E),_=w[l].b+w[l].s,L[z]=E+w[l].s,(y||x)&&(w[l][g]=_,!b&&r(m.c2l(_))&&(M=Math.max(M,_),A=Math.min(A,_)))}if(b){var C=\"fraction\"===b?1:100,O=!1,P=C/1e9;for(S=!1,A=0,M=y?C:0,n=0;n<h.length;n++)for(w=t.calcdata[h[n]],l=0;l<w.length;l++)O=x&&w[l].s<0,z=Math.round(w[l].p/T),O&&(z=\"-\"+z),k=C/L[z],O&&(k*=-1),w[l].b*=k,w[l].s*=k,_=w[l].b+w[l].s,w[l][g]=_,r(m.c2l(_))&&(A-P>_&&(S=!0,A=_),_>M+P&&(S=!0,M=_))}o.expand(m,[A,M],{tozero:!0,padded:S})}else{var N=function(t){return t[g]=t.s,t.s};for(n=0;n<h.length;n++)o.expand(m,t.calcdata[h[n]].map(N),{tozero:!0,padded:!0})}}})}},{\"../../lib\":89,\"../../plots/cartesian/axes\":110,\"../../plots/plots\":130,\"fast-isnumeric\":11}],153:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"../../components/color\"),o=t(\"../../components/drawing\"),i=t(\"../../components/errorbars\");e.exports=function(t){var e=r.select(t).selectAll(\"g.trace.bars\"),n=e.size(),l=t._fullLayout;e.style(\"opacity\",function(t){return t[0].trace.opacity}).each(function(t){(\"stack\"===l.barmode&&n>1||0===l.bargap&&0===l.bargroupgap&&!t[0].trace.marker.line.width)&&r.select(this).attr(\"shape-rendering\",\"crispEdges\")}),e.selectAll(\"g.points\").each(function(t){var e=t[0].trace,n=e.marker,i=n.line,l=(e._input||{}).marker||{},s=o.tryColorscale(n,l,\"\"),c=o.tryColorscale(n,l,\"line.\");r.select(this).selectAll(\"path\").each(function(t){var e,o,l=(t.mlw+1||i.width+1)-1,u=r.select(this);e=\"mc\"in t?t.mcc=s(t.mc):Array.isArray(n.color)?a.defaultLine:n.color,u.style(\"stroke-width\",l+\"px\").call(a.fill,e),l&&(o=\"mlc\"in t?t.mlcc=c(t.mlc):Array.isArray(i.color)?a.defaultLine:i.color,u.call(a.stroke,o))})}),e.call(i.style)}},{\"../../components/color\":18,\"../../components/drawing\":41,\"../../components/errorbars\":47,d3:9}],154:[function(t,e,n){\"use strict\";var r=t(\"../../components/color\"),a=t(\"../../components/colorscale/has_colorscale\"),o=t(\"../../components/colorscale/defaults\");e.exports=function(t,e,n,i,l){n(\"marker.color\",i),a(t,\"marker\")&&o(t,e,l,n,{prefix:\"marker.\",cLetter:\"c\"}),n(\"marker.line.color\",r.defaultLine),a(t,\"marker.line\")&&o(t,e,l,n,{prefix:\"marker.line.\",cLetter:\"c\"}),n(\"marker.line.width\")}},{\"../../components/color\":18,\"../../components/colorscale/defaults\":28,\"../../components/colorscale/has_colorscale\":31}],155:[function(t,e,n){\"use strict\";var r=t(\"../../components/color/attributes\"),a=t(\"../../plots/font_attributes\"),o=t(\"../../plots/attributes\"),i=t(\"../../lib/extend\").extendFlat;e.exports={labels:{valType:\"data_array\"},label0:{valType:\"number\",dflt:0},dlabel:{valType:\"number\",dflt:1},values:{valType:\"data_array\"},marker:{colors:{valType:\"data_array\"},line:{color:{valType:\"color\",dflt:r.defaultLine,arrayOk:!0},width:{valType:\"number\",min:0,dflt:0,arrayOk:!0}}},text:{valType:\"data_array\"},scalegroup:{valType:\"string\",dflt:\"\"},textinfo:{valType:\"flaglist\",flags:[\"label\",\"text\",\"value\",\"percent\"],extras:[\"none\"]},hoverinfo:i({},o.hoverinfo,{flags:[\"label\",\"text\",\"value\",\"percent\",\"name\"]}),textposition:{valType:\"enumerated\",values:[\"inside\",\"outside\",\"auto\",\"none\"],dflt:\"auto\",arrayOk:!0},textfont:i({},a,{}),insidetextfont:i({},a,{}),outsidetextfont:i({},a,{}),domain:{x:{valType:\"info_array\",items:[{valType:\"number\",min:0,max:1},{valType:\"number\",min:0,max:1}],dflt:[0,1]},y:{valType:\"info_array\",items:[{valType:\"number\",min:0,max:1},{valType:\"number\",min:0,max:1}],dflt:[0,1]}},hole:{valType:\"number\",min:0,max:1,dflt:0},sort:{valType:\"boolean\",dflt:!0},direction:{valType:\"enumerated\",values:[\"clockwise\",\"counterclockwise\"],dflt:\"counterclockwise\"},rotation:{valType:\"number\",min:-360,max:360,dflt:0},pull:{valType:\"number\",min:0,max:1,dflt:0,arrayOk:!0}}},{\"../../components/color/attributes\":17,\"../../lib/extend\":88,\"../../plots/attributes\":108,\"../../plots/font_attributes\":128}],156:[function(t,e,n){\"use strict\";function r(t,e){for(var n=[],r=0;r<t.length;r++){var a=t[r],o=a[0].trace;o._module===e&&o.visible===!0&&n.push(a)}return n}var a=t(\"../../plots/plots\");n.name=\"pie\",n.plot=function(t){var e=a.getModule(\"pie\"),n=r(t.calcdata,e);n.length&&e.plot(t,n)},n.clean=function(t,e,n,r){var a=r._has&&r._has(\"pie\"),o=e._has&&e._has(\"pie\");a&&!o&&r._pielayer.selectAll(\"g.trace\").remove()}},{\"../../plots/plots\":130}],157:[function(t,e,n){\"use strict\";function r(t){if(!s){var e=i.defaults;s=e.slice();var n;for(n=0;n<e.length;n++)s.push(o(e[n]).lighten(20).toHexString());for(n=0;n<i.defaults.length;n++)s.push(o(e[n]).darken(20).toHexString())}return s[t%s.length]}var a=t(\"fast-isnumeric\"),o=t(\"tinycolor2\"),i=t(\"../../components/color\"),l=t(\"./helpers\");e.exports=function(t,e){var n,s,c,u,f,d,h=e.values,p=e.labels,g=[],v=t._fullLayout,m=v._piecolormap,y={},x=!1,b=0,_=v.hiddenlabels||[];if(e.dlabel)for(p=new Array(h.length),n=0;n<h.length;n++)p[n]=String(e.label0+n*e.dlabel);for(n=0;n<h.length;n++)s=h[n],a(s)&&(s=+s,0>s||(c=p[n],void 0!==c&&\"\"!==c||(c=n),c=String(c),void 0===y[c]&&(y[c]=!0,u=o(e.marker.colors[n]),u.isValid()?(u=i.addOpacity(u,u.getAlpha()),m[c]||(m[c]=u)):m[c]?u=m[c]:(u=!1,x=!0),f=-1!==_.indexOf(c),f||(b+=s),g.push({v:s,label:c,color:u,i:n,hidden:f}))));if(e.sort&&g.sort(function(t,e){return e.v-t.v}),x)for(n=0;n<g.length;n++)d=g[n],d.color===!1&&(m[d.label]=d.color=r(v._piedefaultcolorcount),v._piedefaultcolorcount++);if(g[0]&&(g[0].vTotal=b),e.textinfo&&\"none\"!==e.textinfo){var w,k=-1!==e.textinfo.indexOf(\"label\"),M=-1!==e.textinfo.indexOf(\"text\"),A=-1!==e.textinfo.indexOf(\"value\"),L=-1!==e.textinfo.indexOf(\"percent\"),T=v.separators;for(n=0;n<g.length;n++)d=g[n],w=k?[d.label]:[],M&&e.text[d.i]&&w.push(e.text[d.i]),A&&w.push(l.formatPieValue(d.v,T)),L&&w.push(l.formatPiePercent(d.v/b,T)),d.text=w.join(\"<br>\")}return g};var s},{\"../../components/color\":18,\"./helpers\":159,\"fast-isnumeric\":11,tinycolor2:13}],158:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"./attributes\");e.exports=function(t,e,n,o){function i(n,o){return r.coerce(t,e,a,n,o)}var l=r.coerceFont,s=i(\"values\");if(!Array.isArray(s)||!s.length)return void(e.visible=!1);var c=i(\"labels\");Array.isArray(c)||(i(\"label0\"),i(\"dlabel\"));var u=i(\"marker.line.width\");u&&i(\"marker.line.color\");var f=i(\"marker.colors\");Array.isArray(f)||(e.marker.colors=[]),i(\"scalegroup\");var d=i(\"text\"),h=i(\"textinfo\",Array.isArray(d)?\"text+percent\":\"percent\");if(i(\"hoverinfo\",1===o._dataLength?\"label+text+value+percent\":void 0),h&&\"none\"!==h){var p=i(\"textposition\"),g=Array.isArray(p)||\"auto\"===p,v=g||\"inside\"===p,m=g||\"outside\"===p;if(v||m){var y=l(i,\"textfont\",o.font);v&&l(i,\"insidetextfont\",y),m&&l(i,\"outsidetextfont\",y)}}i(\"domain.x\"),i(\"domain.y\"),i(\"hol" -, -"e\"),i(\"sort\"),i(\"direction\"),i(\"rotation\"),i(\"pull\")}},{\"../../lib\":89,\"./attributes\":155}],159:[function(t,e,n){\"use strict\";var r=t(\"../../lib\");n.formatPiePercent=function(t,e){var n=(100*t).toPrecision(3);return-1!==n.lastIndexOf(\".\")&&(n=n.replace(/[.]?0+$/,\"\")),r.numSeparate(n,e)+\"%\"},n.formatPieValue=function(t,e){var n=t.toPrecision(10);return-1!==n.lastIndexOf(\".\")&&(n=n.replace(/[.]?0+$/,\"\")),r.numSeparate(n,e)}},{\"../../lib\":89}],160:[function(t,e,n){\"use strict\";var r={};r.attributes=t(\"./attributes\"),r.supplyDefaults=t(\"./defaults\"),r.supplyLayoutDefaults=t(\"./layout_defaults\"),r.layoutAttributes=t(\"./layout_attributes\"),r.calc=t(\"./calc\"),r.plot=t(\"./plot\"),r.style=t(\"./style\"),r.styleOne=t(\"./style_one\"),r.moduleType=\"trace\",r.name=\"pie\",r.basePlotModule=t(\"./base_plot\"),r.categories=[\"pie\",\"showLegend\"],r.meta={},e.exports=r},{\"./attributes\":155,\"./base_plot\":156,\"./calc\":157,\"./defaults\":158,\"./layout_attributes\":161,\"./layout_defaults\":162,\"./plot\":163,\"./style\":164,\"./style_one\":165}],161:[function(t,e,n){\"use strict\";e.exports={hiddenlabels:{valType:\"data_array\"}}},{}],162:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"./layout_attributes\");e.exports=function(t,e){function n(n,o){return r.coerce(t,e,a,n,o)}n(\"hiddenlabels\")}},{\"../../lib\":89,\"./layout_attributes\":161}],163:[function(t,e,n){\"use strict\";function r(t,e,n){var r=Math.sqrt(t.width*t.width+t.height*t.height),o=t.width/t.height,i=Math.PI*Math.min(e.v/n.vTotal,.5),l=1-n.trace.hole,s=a(e,n),c={scale:s*n.r*2/r,rCenter:1-s,rotate:0};if(c.scale>=1)return c;var u=o+1/(2*Math.tan(i)),f=n.r*Math.min(1/(Math.sqrt(u*u+.5)+u),l/(Math.sqrt(o*o+l/2)+o)),d={scale:2*f/t.height,rCenter:Math.cos(f/n.r)-f*o/n.r,rotate:(180/Math.PI*e.midangle+720)%180-90},h=1/o,p=h+1/(2*Math.tan(i)),g=n.r*Math.min(1/(Math.sqrt(p*p+.5)+p),l/(Math.sqrt(h*h+l/2)+h)),v={scale:2*g/t.width,rCenter:Math.cos(g/n.r)-g/o/n.r,rotate:(180/Math.PI*e.midangle+810)%180-90},m=v.scale>d.scale?v:d;return c.scale<1&&m.scale>c.scale?m:c}function a(t,e){if(t.v===e.vTotal&&!e.trace.hole)return 1;var n=Math.PI*Math.min(t.v/e.vTotal,.5);return Math.min(1/(1+1/Math.sin(n)),(1-e.trace.hole)/2)}function o(t,e){var n=e.pxmid[0],r=e.pxmid[1],a=t.width/2,o=t.height/2;return 0>n&&(a*=-1),0>r&&(o*=-1),{scale:1,rCenter:1,rotate:0,x:a+Math.abs(o)*(a>0?1:-1)/2,y:o/(1+n*n/(r*r)),outside:!0}}function i(t,e){function n(t,e){return t.pxmid[1]-e.pxmid[1]}function r(t,e){return e.pxmid[1]-t.pxmid[1]}function a(t,n){n||(n={});var r,a,o,l,d,h,g=n.labelExtraY+(i?n.yLabelMax:n.yLabelMin),v=i?t.yLabelMin:t.yLabelMax,m=i?t.yLabelMax:t.yLabelMin,y=t.cyFinal+c(t.px0[1],t.px1[1]),x=g-v;if(x*f>0&&(t.labelExtraY=x),Array.isArray(e.pull))for(a=0;a<p.length;a++)o=p[a],o===t||(e.pull[t.i]||0)>=e.pull[o.i]||((t.pxmid[1]-o.pxmid[1])*f>0?(l=o.cyFinal+c(o.px0[1],o.px1[1]),x=l-v-t.labelExtraY,x*f>0&&(t.labelExtraY+=x)):(m+t.labelExtraY-y)*f>0&&(r=3*u*Math.abs(a-p.indexOf(t)),d=o.cxFinal+s(o.px0[0],o.px1[0]),h=d+r-(t.cxFinal+t.pxmid[0])-t.labelExtraX,h*u>0&&(t.labelExtraX+=h)))}var o,i,l,s,c,u,f,d,h,p,g,v,m;for(i=0;2>i;i++)for(l=i?n:r,c=i?Math.max:Math.min,f=i?1:-1,o=0;2>o;o++){for(s=o?Math.max:Math.min,u=o?1:-1,d=t[i][o],d.sort(l),h=t[1-i][o],p=h.concat(d),v=[],g=0;g<d.length;g++)void 0!==d[g].yLabelMid&&v.push(d[g]);for(m=!1,g=0;i&&g<h.length;g++)if(void 0!==h[g].yLabelMid){m=h[g];break}for(g=0;g<v.length;g++){var y=g&&v[g-1];m&&!g&&(y=m),a(v[g],y)}}}function l(t,e){var n,r,a,o,i,l,s,u,f,d,h=[];for(a=0;a<t.length;a++){if(i=t[a][0],l=i.trace,n=e.w*(l.domain.x[1]-l.domain.x[0]),r=e.h*(l.domain.y[1]-l.domain.y[0]),s=l.tiltaxis*Math.PI/180,u=l.pull,Array.isArray(u))for(u=0,o=0;o<l.pull.length;o++)l.pull[o]>u&&(u=l.pull[o]);i.r=Math.min(n/c(l.tilt,Math.sin(s),l.depth),r/c(l.tilt,Math.cos(s),l.depth))/(2+2*u),i.cx=e.l+e.w*(l.domain.x[1]+l.domain.x[0])/2,i.cy=e.t+e.h*(2-l.domain.y[1]-l.domain.y[0])/2,l.scalegroup&&-1===h.indexOf(l.scalegroup)&&h.push(l.scalegroup)}for(o=0;o<h.length;o++){for(d=1/0,f=h[o],a=0;a<t.length;a++)i=t[a][0],i.trace.scalegroup===f&&(d=Math.min(d,i.r*i.r/i.vTotal));for(a=0;a<t.length;a++)i=t[a][0],i.trace.scalegroup===f&&(i.r=Math.sqrt(d*i.vTotal))}}function s(t){function e(t){var e=f.r*Math.sin(t),n=-f.r*Math.cos(t);return h?[e*(1-l*r*r)+n*i*l,e*i*l+n*(1-l*a*a),Math.sin(o)*(n*a-e*r)]:[e,n]}var n,r,a,o,i,l,s,c,u,f=t[0],d=f.trace,h=d.tilt,p=d.rotation*Math.PI/180,g=2*Math.PI/f.vTotal,v=\"px0\",m=\"px1\";if(\"counterclockwise\"===d.direction){for(s=0;s<t.length&&t[s].hidden;s++);if(s===t.length)return;p+=g*t[s].v,g*=-1,v=\"px1\",m=\"px0\"}for(h&&(o=h*Math.PI/180,n=d.tiltaxis*Math.PI/180,i=Math.sin(n)*Math.cos(n),l=1-Math.cos(o),r=Math.sin(n),a=Math.cos(n)),u=e(p),s=0;s<t.length;s++)c=t[s],c.hidden||(c[v]=u,p+=g*c.v/2,c.pxmid=e(p),c.midangle=p,p+=g*c.v/2,u=e(p),c[m]=u,c.largeArc=c.v>f.vTotal/2?1:0)}function c(t,e,n){if(!t)return 1;var r=Math.sin(t*Math.PI/180);return Math.max(.01,n*r*Math.abs(e)+2*Math.sqrt(1-r*r*e*e))}var u=t(\"d3\"),f=t(\"../../plots/cartesian/graph_interact\"),d=t(\"../../components/color\"),h=t(\"../../components/drawing\"),p=t(\"../../lib/svg_text_utils\"),g=t(\"./helpers\");e.exports=function(t,e){var n=t._fullLayout;l(e,n._size);var c=n._pielayer.selectAll(\"g.trace\").data(e);c.enter().append(\"g\").attr({\"stroke-linejoin\":\"round\",\"class\":\"trace\"}),c.exit().remove(),c.order(),c.each(function(e){var l=u.select(this),c=e[0],v=c.trace,m=0,y=(v.depth||0)*c.r*Math.sin(m)/2,x=v.tiltaxis||0,b=x*Math.PI/180,_=[y*Math.sin(b),y*Math.cos(b)],w=c.r*Math.cos(m),k=l.selectAll(\"g.part\").data(v.tilt?[\"top\",\"sides\"]:[\"top\"]);k.enter().append(\"g\").attr(\"class\",function(t){return t+\" part\"}),k.exit().remove(),k.order(),s(e),l.selectAll(\".top\").each(function(){var l=u.select(this).selectAll(\"g.slice\").data(e);l.enter().append(\"g\").classed(\"slice\",!0),l.exit().remove();var s=[[[],[]],[[],[]]],m=!1;l.each(function(i){function l(e){var r=t._fullLayout,o=t._fullData[v.index],l=o.hoverinfo;if(\"all\"===l&&(l=\"label+text+value+percent+name\"),!t._dragging&&r.hovermode!==!1&&\"none\"!==l&&l){var s=a(i,c),u=k+i.pxmid[0]*(1-s),d=M+i.pxmid[1]*(1-s),h=n.separators,p=[];-1!==l.indexOf(\"label\")&&p.push(i.label),o.text&&o.text[i.i]&&-1!==l.indexOf(\"text\")&&p.push(o.text[i.i]),-1!==l.indexOf(\"value\")&&p.push(g.formatPieValue(i.v,h)),-1!==l.indexOf(\"percent\")&&p.push(g.formatPiePercent(i.v/c.vTotal,h)),f.loneHover({x0:u-s*c.r,x1:u+s*c.r,y:d,text:p.join(\"<br>\"),name:-1!==l.indexOf(\"name\")?o.name:void 0,color:i.color,idealAlign:i.pxmid[0]<0?\"left\":\"right\"},{container:r._hoverlayer.node(),outerContainer:r._paper.node()}),f.hover(t,e,\"pie\"),T=!0}}function d(e){t.emit(\"plotly_unhover\",{points:[e]}),T&&(f.loneUnhover(n._hoverlayer.node()),T=!1)}function y(){t._hoverdata=[i],t._hoverdata.trace=e.trace,f.click(t,{target:!0})}function b(t,e,n,r){return\"a\"+r*c.r+\",\"+r*w+\" \"+x+\" \"+i.largeArc+(n?\" 1 \":\" 0 \")+r*(e[0]-t[0])+\",\"+r*(e[1]-t[1])}if(i.hidden)return void u.select(this).selectAll(\"path,g\").remove();s[i.pxmid[1]<0?0:1][i.pxmid[0]<0?0:1].push(i);var k=c.cx+_[0],M=c.cy+_[1],A=u.select(this),L=A.selectAll(\"path.surface\").data([i]),T=!1;if(L.enter().append(\"path\").classed(\"surface\",!0).style({\"pointer-events\":\"all\"}),A.select(\"path.textline\").remove(),A.on(\"mouseover\",l).on(\"mouseout\",d).on(\"click\",y),v.pull){var z=+(Array.isArray(v.pull)?v.pull[i.i]:v.pull)||0;z>0&&(k+=z*i.pxmid[0],M+=z*i.pxmid[1])}i.cxFinal=k,i.cyFinal=M;var S=v.hole;if(i.v===c.vTotal){var E=\"M\"+(k+i.px0[0])+\",\"+(M+i.px0[1])+b(i.px0,i.pxmid,!0,1)+b(i.pxmid,i.px0,!0,1)+\"Z\";S?L.attr(\"d\",\"M\"+(k+S*i.px0[0])+\",\"+(M+S*i.px0[1])+b(i.px0,i.pxmid,!1,S)+b(i.pxmid,i.px0,!1,S)+\"Z\"+E):L.attr(\"d\",E)}else{var C=b(i.px0,i.px1,!0,1);if(S){var O=1-S;L.attr(\"d\",\"M\"+(k+S*i.px1[0])+\",\"+(M+S*i.px1[1])+b(i.px1,i.px0,!1,S)+\"l\"+O*i.px0[0]+\",\"+O*i.px0[1]+C+\"Z\")}else L.attr(\"d\",\"M\"+k+\",\"+M+\"l\"+i.px0[0]+\",\"+i.px0[1]+C+\"Z\")}var P=Array.isArray(v.textposition)?v.textposition[i.i]:v.textposition,N=A.selectAll(\"g.slicetext\").data(i.text&&\"none\"!==P?[0]:[]);N.enter().append(\"g\").classed(\"slicetext\",!0),N.exit().remove(),N.each(function(){var t=u.select(this).selectAll(\"text\").data([0]);t.enter().append(\"text\").attr(\"data-notex\",1),t.exit().remove(),t.text(i.text).attr({\"class\":\"slicetext\",transform:\"\",\"data-bb\":\"\",\"text-anchor\":\"middle\",x:0,y:0}).call(h.font,\"outside\"===P?v.outsidetextfont:v.insidetextfont).call(p.convertToTspans),t.selectAll(\"tspan.line\").attr({x:0,y:0});var e,n=h.bBox(t.node());\"outside\"===P?e=o(n,i):(e=r(n,i,c),\"auto\"===P&&e.scale<1&&(t.call(h.font,v.outsidetextfont),v.outsidetextfont.family===v.insidetextfont.family&&v.outsidetextfont.size===v.insidetextfont.size||(t.attr({\"data-bb\":\"\"}),n=h.bBox(t.node())),e=o(n,i)));var a=k+i.pxmid[0]*e.rCenter+(e.x||0),l=M+i.pxmid[1]*e.rCenter+(e.y||0);e.outside&&(i.yLabelMin=l-n.height/2,i.yLabelMid=l,i.yLabelMax=l+n.height/2,i.labelExtraX=0,i.labelExtraY=0,m=!0),t.attr(\"transform\",\"translate(\"+a+\",\"+l+\")\"+(e.scale<1?\"scale(\"+e.scale+\")\":\"\")+(e.rotate?\"rotate(\"+e.rotate+\")\":\"\")+\"translate(\"+-(n.left+n.right)/2+\",\"+-(n.top+n.bottom)/2+\")\")})}),m&&i(s,v),l.each(function(t){if(t.labelExtraX||t.labelExtraY){var e=u.select(this),n=e.select(\"g.slicetext text\");n.attr(\"transform\",\"translate(\"+t.labelExtraX+\",\"+t.labelExtraY+\")\"+n.attr(\"transform\"));var r=t.cxFinal+t.pxmid[0],a=t.cyFinal+t.pxmid[1],o=\"M\"+r+\",\"+a,i=(t.yLabelMax-t.yLabelMin)*(t.pxmid[0]<0?-1:1)/4;if(t.labelExtraX){var l=t.labelExtraX*t.pxmid[1]/t.pxmid[0],s=t.yLabelMid+t.labelExtraY-(t.cyFinal+t.pxmid[1]);o+=Math.abs(l)>Math.abs(s)?\"l\"+s*t.pxmid[0]/t.pxmid[1]+\",\"+s+\"H\"+(r+t.labelExtraX+i):\"l\"+t.labelExtraX+\",\"+l+\"v\"+(s-l)+\"h\"+i}else o+=\"V\"+(t.yLabelMid+t.labelExtraY)+\"h\"+i;e.append(\"path\").classed(\"textline\",!0).call(d.stroke,v.outsidetextfont.color).attr({\"stroke-width\":Math.min(2,v.outsidetextfont.size/8),d:o,fill:\"none\"})}})})}),setTimeout(function(){c.selectAll(\"tspan\").each(function(){var t=u.select(this);t.attr(\"dy\")&&t.attr(\"dy\",t.attr(\"dy\"))})},0)}},{\"../../components/color\":18,\"../../components/drawing\":41,\"../../lib/svg_text_utils\":100,\"../../plots/cartesian/graph_interact\":117,\"./helpers" -, -"\":159,d3:9}],164:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"./style_one\");e.exports=function(t){t._fullLayout._pielayer.selectAll(\".trace\").each(function(t){var e=t[0],n=e.trace,o=r.select(this);o.style({opacity:n.opacity}),o.selectAll(\".top path.surface\").each(function(t){r.select(this).call(a,t,n)})})}},{\"./style_one\":165,d3:9}],165:[function(t,e,n){\"use strict\";var r=t(\"../../components/color\");e.exports=function(t,e,n){var a=n.marker.line.color;Array.isArray(a)&&(a=a[e.i]||r.defaultLine);var o=n.marker.line.width||0;Array.isArray(o)&&(o=o[e.i]||0),t.style({\"stroke-width\":o,fill:e.color}).call(r.stroke,a)}},{\"../../components/color\":18}],166:[function(t,e,n){\"use strict\";var r=t(\"../../lib\");e.exports=function(t){var e=t[0].trace,n=e.marker;if(r.mergeArray(e.text,t,\"tx\"),r.mergeArray(e.textposition,t,\"tp\"),e.textfont&&(r.mergeArray(e.textfont.size,t,\"ts\"),r.mergeArray(e.textfont.color,t,\"tc\"),r.mergeArray(e.textfont.family,t,\"tf\")),n&&n.line){var a=n.line;r.mergeArray(n.opacity,t,\"mo\"),r.mergeArray(n.symbol,t,\"mx\"),r.mergeArray(n.color,t,\"mc\"),r.mergeArray(a.color,t,\"mlc\"),r.mergeArray(a.width,t,\"mlw\")}}},{\"../../lib\":89}],167:[function(t,e,n){\"use strict\";var r=t(\"../../components/colorscale/color_attributes\"),a=t(\"../../components/drawing\"),o=(t(\"./constants\"),t(\"../../lib/extend\").extendFlat);e.exports={x:{valType:\"data_array\"},x0:{valType:\"any\",dflt:0},dx:{valType:\"number\",dflt:1},y:{valType:\"data_array\"},y0:{valType:\"any\",dflt:0},dy:{valType:\"number\",dflt:1},text:{valType:\"string\",dflt:\"\",arrayOk:!0},mode:{valType:\"flaglist\",flags:[\"lines\",\"markers\",\"text\"],extras:[\"none\"]},hoveron:{valType:\"flaglist\",flags:[\"points\",\"fills\"]},line:{color:{valType:\"color\"},width:{valType:\"number\",min:0,dflt:2},shape:{valType:\"enumerated\",values:[\"linear\",\"spline\",\"hv\",\"vh\",\"hvh\",\"vhv\"],dflt:\"linear\"},smoothing:{valType:\"number\",min:0,max:1.3,dflt:1},dash:{valType:\"string\",values:[\"solid\",\"dot\",\"dash\",\"longdash\",\"dashdot\",\"longdashdot\"],dflt:\"solid\"}},connectgaps:{valType:\"boolean\",dflt:!1},fill:{valType:\"enumerated\",values:[\"none\",\"tozeroy\",\"tozerox\",\"tonexty\",\"tonextx\",\"toself\",\"tonext\"],dflt:\"none\"},fillcolor:{valType:\"color\"},marker:o({},{symbol:{valType:\"enumerated\",values:a.symbolList,dflt:\"circle\",arrayOk:!0},opacity:{valType:\"number\",min:0,max:1,arrayOk:!0},size:{valType:\"number\",min:0,dflt:6,arrayOk:!0},maxdisplayed:{valType:\"number\",min:0,dflt:0},sizeref:{valType:\"number\",dflt:1},sizemin:{valType:\"number\",min:0,dflt:0},sizemode:{valType:\"enumerated\",values:[\"diameter\",\"area\"],dflt:\"diameter\"},showscale:{valType:\"boolean\",dflt:!1},line:o({},{width:{valType:\"number\",min:0,arrayOk:!0}},r(\"marker.line\"))},r(\"marker\")),textposition:{valType:\"enumerated\",values:[\"top left\",\"top center\",\"top right\",\"middle left\",\"middle center\",\"middle right\",\"bottom left\",\"bottom center\",\"bottom right\"],dflt:\"middle center\",arrayOk:!0},textfont:{family:{valType:\"string\",noBlank:!0,strict:!0,arrayOk:!0},size:{valType:\"number\",min:1,arrayOk:!0},color:{valType:\"color\",arrayOk:!0}},r:{valType:\"data_array\"},t:{valType:\"data_array\"},_nestedModules:{error_y:\"ErrorBars\",error_x:\"ErrorBars\",\"marker.colorbar\":\"Colorbar\"}}},{\"../../components/colorscale/color_attributes\":26,\"../../components/drawing\":41,\"../../lib/extend\":88,\"./constants\":172}],168:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\"),a=t(\"../../plots/cartesian/axes\"),o=t(\"../../lib\"),i=t(\"./subtypes\"),l=t(\"./colorscale_calc\");e.exports=function(t,e){var n,s,c,u=a.getFromId(t,e.xaxis||\"x\"),f=a.getFromId(t,e.yaxis||\"y\"),d=u.makeCalcdata(e,\"x\"),h=f.makeCalcdata(e,\"y\"),p=Math.min(d.length,h.length);u._minDtick=0,f._minDtick=0,d.length>p&&d.splice(p,d.length-p),h.length>p&&h.splice(p,h.length-p);var g={padded:!0},v={padded:!0};if(i.hasMarkers(e)){if(n=e.marker,s=n.size,Array.isArray(s)){var m={type:\"linear\"};a.setConvert(m),s=m.makeCalcdata(e.marker,\"size\"),s.length>p&&s.splice(p,s.length-p)}var y,x=1.6*(e.marker.sizeref||1);y=\"area\"===e.marker.sizemode?function(t){return Math.max(Math.sqrt((t||0)/x),3)}:function(t){return Math.max((t||0)/x,3)},g.ppad=v.ppad=Array.isArray(s)?s.map(y):y(s)}l(e),!(\"tozerox\"===e.fill||\"tonextx\"===e.fill&&t.firstscatter)||d[0]===d[p-1]&&h[0]===h[p-1]?e.error_y.visible||-1===[\"tonexty\",\"tozeroy\"].indexOf(e.fill)&&(i.hasMarkers(e)||i.hasText(e))||(g.padded=!1,g.ppad=0):g.tozero=!0,!(\"tozeroy\"===e.fill||\"tonexty\"===e.fill&&t.firstscatter)||d[0]===d[p-1]&&h[0]===h[p-1]?-1!==[\"tonextx\",\"tozerox\"].indexOf(e.fill)&&(v.padded=!1):v.tozero=!0,a.expand(u,d,g),a.expand(f,h,v);var b=new Array(p);for(c=0;p>c;c++)b[c]=r(d[c])&&r(h[c])?{x:d[c],y:h[c]}:{x:!1,y:!1};return void 0!==typeof s&&o.mergeArray(s,b,\"ms\"),t.firstscatter=!1,b}},{\"../../lib\":89,\"../../plots/cartesian/axes\":110,\"./colorscale_calc\":171,\"./subtypes\":186,\"fast-isnumeric\":11}],169:[function(t,e,n){\"use strict\";e.exports=function(t){var e,n,r,a,o;for(e=0;e<t.length;e++)if(n=t[e],r=n.fill,\"none\"!==r&&\"scatter\"===n.type&&(n.opacity=void 0,\"tonexty\"===r||\"tonextx\"===r))for(a=e-1;a>=0;a--)if(o=t[a],\"scatter\"===o.type&&o.xaxis===n.xaxis&&o.yaxis===n.yaxis){o.opacity=void 0;break}}},{}],170:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"fast-isnumeric\"),o=t(\"../../lib\"),i=t(\"../../plots/plots\"),l=t(\"../../components/colorscale/get_scale\"),s=t(\"../../components/colorbar/draw\");e.exports=function(t,e){var n=e[0].trace,c=n.marker,u=\"cb\"+n.uid;if(t._fullLayout._infolayer.selectAll(\".\"+u).remove(),void 0===c||!c.showscale)return void i.autoMargin(t,u);var f=l(c.colorscale),d=c.color,h=c.cmin,p=c.cmax;a(h)||(h=o.aggNums(Math.min,null,d)),a(p)||(p=o.aggNums(Math.max,null,d));var g=e[0].t.cb=s(t,u);g.fillcolor(r.scale.linear().domain(f.map(function(t){return h+t[0]*(p-h)})).range(f.map(function(t){return t[1]}))).filllevels({start:h,end:p,size:(p-h)/254}).options(c.colorbar)()}},{\"../../components/colorbar/draw\":21,\"../../components/colorscale/get_scale\":30,\"../../lib\":89,\"../../plots/plots\":130,d3:9,\"fast-isnumeric\":11}],171:[function(t,e,n){\"use strict\";var r=t(\"../../components/colorscale/has_colorscale\"),a=t(\"../../components/colorscale/calc\"),o=t(\"./subtypes\");e.exports=function(t){o.hasLines(t)&&r(t,\"line\")&&a(t,t.line.color,\"line\",\"c\"),o.hasMarkers(t)&&(r(t,\"marker\")&&a(t,t.marker.color,\"marker\",\"c\"),r(t,\"marker.line\")&&a(t,t.marker.line.color,\"marker.line\",\"c\"))}},{\"../../components/colorscale/calc\":25,\"../../components/colorscale/has_colorscale\":31,\"./subtypes\":186}],172:[function(t,e,n){\"use strict\";e.exports={PTS_LINESONLY:20}},{}],173:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"./attributes\"),o=t(\"./constants\"),i=t(\"./subtypes\"),l=t(\"./xy_defaults\"),s=t(\"./marker_defaults\"),c=t(\"./line_defaults\"),u=t(\"./line_shape_defaults\"),f=t(\"./text_defaults\"),d=t(\"./fillcolor_defaults\"),h=t(\"../../components/errorbars/defaults\");e.exports=function(t,e,n,p){function g(n,o){return r.coerce(t,e,a,n,o)}var v=l(t,e,g),m=v<o.PTS_LINESONLY?\"lines+markers\":\"lines\";if(!v)return void(e.visible=!1);g(\"text\"),g(\"mode\",m),i.hasLines(e)&&(c(t,e,n,p,g),u(t,e,g),g(\"connectgaps\")),i.hasMarkers(e)&&s(t,e,n,p,g),i.hasText(e)&&f(t,e,p,g);var y=[];(i.hasMarkers(e)||i.hasText(e))&&(g(\"marker.maxdisplayed\"),y.push(\"points\")),g(\"fill\"),\"none\"!==e.fill&&(d(t,e,n,g),i.hasLines(e)||u(t,e,g)),\"tonext\"!==e.fill&&\"toself\"!==e.fill||y.push(\"fills\"),g(\"hoveron\",y.join(\"+\")||\"points\"),h(t,e,n,{axis:\"y\"}),h(t,e,n,{axis:\"x\",inherit:\"y\"})}},{\"../../components/errorbars/defaults\":46,\"../../lib\":89,\"./attributes\":167,\"./constants\":172,\"./fillcolor_defaults\":174,\"./line_defaults\":178,\"./line_shape_defaults\":180,\"./marker_defaults\":182,\"./subtypes\":186,\"./text_defaults\":187,\"./xy_defaults\":188}],174:[function(t,e,n){\"use strict\";var r=t(\"../../components/color\");e.exports=function(t,e,n,a){var o=!1;if(e.marker){var i=e.marker.color,l=(e.marker.line||{}).color;i&&!Array.isArray(i)?o=i:l&&!Array.isArray(l)&&(o=l)}a(\"fillcolor\",r.addOpacity((e.line||{}).color||o||n,.5))}},{\"../../components/color\":18}],175:[function(t,e,n){\"use strict\";var r=t(\"../../components/color\"),a=t(\"./subtypes\");e.exports=function(t,e){var n,o;if(\"lines\"===t.mode)return n=t.line.color,n&&r.opacity(n)?n:t.fillcolor;if(\"none\"===t.mode)return t.fill?t.fillcolor:\"\";var i=e.mcc||(t.marker||{}).color,l=e.mlcc||((t.marker||{}).line||{}).color;return o=i&&r.opacity(i)?i:l&&r.opacity(l)&&(e.mlw||((t.marker||{}).line||{}).width)?l:\"\",o?r.opacity(o)<.3?r.addOpacity(o,.3):o:(n=(t.line||{}).color,n&&r.opacity(n)&&a.hasLines(t)&&t.line.width?n:t.fillcolor)}},{\"../../components/color\":18,\"./subtypes\":186}],176:[function(t,e,n){\"use strict\";var r=t(\"../../lib\"),a=t(\"../../plots/cartesian/graph_interact\"),o=t(\"../../plots/cartesian/constants\"),i=t(\"../../components/errorbars\"),l=t(\"./get_trace_color\"),s=t(\"../../components/color\");e.exports=function(t,e,n,c){var u=t.cd,f=u[0].trace,d=t.xa,h=t.ya,p=d.c2p(e),g=h.c2p(n),v=[p,g];if(-1!==f.hoveron.indexOf(\"points\")){var m=function(t){var e=Math.max(3,t.mrc||0);return Math.max(Math.abs(d.c2p(t.x)-p)-e,1-3/e)},y=function(t){var e=Math.max(3,t.mrc||0);return Math.max(Math.abs(h.c2p(t.y)-g)-e,1-3/e)},x=function(t){var e=Math.max(3,t.mrc||0),n=d.c2p(t.x)-p,r=h.c2p(t.y)-g;return Math.max(Math.sqrt(n*n+r*r)-e,1-3/e)},b=a.getDistanceFunction(c,m,y,x);if(a.getClosest(u,b,t),t.index!==!1){var _=u[t.index],w=d.c2p(_.x,!0),k=h.c2p(_.y,!0),M=_.mrc||1;return r.extendFlat(t,{color:l(f,_),x0:w-M,x1:w+M,xLabelVal:_.x,y0:k-M,y1:k+M,yLabelVal:_.y}),_.tx?t.text=_.tx:f.text&&(t.text=f.text),i.hoverInfo(_,f,t),[t]}}if(-1!==f.hoveron.indexOf(\"fills\")&&f._polygons){var A,L,T,z,S,E,C,O,P,N=f._polygons,D=[],I=!1,R=1/0,j=-(1/0),q=1/0,F=-(1/0);for(A=0;A<N.length;A++)T=N[A],T.contains(v)&&(I=!I,D.push(T),q=Math.min(q,T.ymin),F=Math.max(F,T.ymax));if(I){q=Math.max(q,0),F=Math.min(F,h._length);var B=(q+F)/2;for(A=0;A<D.length;A++)for(z=D[A].pts,L=1;L<z.length;L++)O=z[L-1][1],P=z[L][1],O>B!=P>=B&&(E=z[L-1][0],C=z[L][0],S=E+(C-E)*(B-O)/(P-O),R=Math.min(R,S),j=Math.max(j,S));R=Math.max(R,0),j=Math.min(j,d._length);var H=s.defaultLine;return s.opacity(f.fillcolor)?H" -, -"=f.fillcolor:s.opacity((f.line||{}).color)&&(H=f.line.color),r.extendFlat(t,{distance:o.MAXDIST+10,x0:R,x1:j,y0:B,y1:B,color:H}),delete t.index,f.text&&!Array.isArray(f.text)?t.text=String(f.text):t.text=f.name,[t]}}}},{\"../../components/color\":18,\"../../components/errorbars\":47,\"../../lib\":89,\"../../plots/cartesian/constants\":115,\"../../plots/cartesian/graph_interact\":117,\"./get_trace_color\":175}],177:[function(t,e,n){\"use strict\";var r={},a=t(\"./subtypes\");r.hasLines=a.hasLines,r.hasMarkers=a.hasMarkers,r.hasText=a.hasText,r.isBubble=a.isBubble,r.attributes=t(\"./attributes\"),r.supplyDefaults=t(\"./defaults\"),r.cleanData=t(\"./clean_data\"),r.calc=t(\"./calc\"),r.arraysToCalcdata=t(\"./arrays_to_calcdata\"),r.plot=t(\"./plot\"),r.colorbar=t(\"./colorbar\"),r.style=t(\"./style\"),r.hoverPoints=t(\"./hover\"),r.selectPoints=t(\"./select\"),r.moduleType=\"trace\",r.name=\"scatter\",r.basePlotModule=t(\"../../plots/cartesian\"),r.categories=[\"cartesian\",\"symbols\",\"markerColorscale\",\"errorBarsOK\",\"showLegend\"],r.meta={},e.exports=r},{\"../../plots/cartesian\":118,\"./arrays_to_calcdata\":166,\"./attributes\":167,\"./calc\":168,\"./clean_data\":169,\"./colorbar\":170,\"./defaults\":173,\"./hover\":176,\"./plot\":183,\"./select\":184,\"./style\":185,\"./subtypes\":186}],178:[function(t,e,n){\"use strict\";var r=t(\"../../components/colorscale/has_colorscale\"),a=t(\"../../components/colorscale/defaults\");e.exports=function(t,e,n,o,i){var l=(t.marker||{}).color;if(i(\"line.color\",n),r(t,\"line\"))a(t,e,o,i,{prefix:\"line.\",cLetter:\"c\"});else{var s=(Array.isArray(l)?!1:l)||n;i(\"line.color\",s)}i(\"line.width\"),i(\"line.dash\")}},{\"../../components/colorscale/defaults\":28,\"../../components/colorscale/has_colorscale\":31}],179:[function(t,e,n){\"use strict\";var r=t(\"../../plots/cartesian/axes\");e.exports=function(t,e){function n(e){var n=w.c2p(t[e].x),r=k.c2p(t[e].y);return n===z||r===z?!1:[n,r]}function a(t){var e=t[0]/w._length,n=t[1]/k._length;return(1+10*Math.max(0,-e,e-1,-n,n-1))*A}function o(t,e){var n=t[0]-e[0],r=t[1]-e[1];return Math.sqrt(n*n+r*r);\n" -"}var i,l,s,c,u,f,d,h,p,g,v,m,y,x,b,_,w=e.xaxis,k=e.yaxis,M=e.connectGaps,A=e.baseTolerance,L=e.linear,T=[],z=r.BADNUM,S=.2,E=new Array(t.length),C=0;for(i=0;i<t.length;i++)if(l=n(i)){for(C=0,E[C++]=l,i++;i<t.length;i++){if(c=n(i),!c){if(M)continue;break}if(L){if(d=o(c,l),!(d<a(c)*S)){for(p=[(c[0]-l[0])/d,(c[1]-l[1])/d],u=l,v=d,m=x=b=0,h=!1,s=c,i++;i<t.length;i++){if(f=n(i),!f){if(M)continue;break}if(g=[f[0]-l[0],f[1]-l[1]],_=g[0]*p[1]-g[1]*p[0],x=Math.min(x,_),b=Math.max(b,_),b-x>a(f))break;s=f,y=g[0]*p[0]+g[1]*p[1],y>v?(v=y,c=f,h=!1):m>y&&(m=y,u=f,h=!0)}if(h?(E[C++]=c,s!==u&&(E[C++]=u)):(u!==l&&(E[C++]=u),s!==c&&(E[C++]=c)),E[C++]=s,i>=t.length||!f)break;E[C++]=f,l=f}}else E[C++]=c}T.push(E.slice(0,C))}return T}},{\"../../plots/cartesian/axes\":110}],180:[function(t,e,n){\"use strict\";e.exports=function(t,e,n){var r=n(\"line.shape\");\"spline\"===r&&n(\"line.smoothing\")}},{}],181:[function(t,e,n){\"use strict\";var r=t(\"fast-isnumeric\");e.exports=function(t){var e=t.marker,n=e.sizeref||1,a=e.sizemin||0,o=\"area\"===e.sizemode?function(t){return Math.sqrt(t/n)}:function(t){return t/n};return function(t){var e=o(t/2);return r(e)&&e>0?Math.max(e,a):0}}},{\"fast-isnumeric\":11}],182:[function(t,e,n){\"use strict\";var r=t(\"../../components/color\"),a=t(\"../../components/colorscale/has_colorscale\"),o=t(\"../../components/colorscale/defaults\"),i=t(\"./subtypes\");e.exports=function(t,e,n,l,s){var c,u=i.isBubble(t),f=(t.line||{}).color;f&&(n=f),s(\"marker.symbol\"),s(\"marker.opacity\",u?.7:1),s(\"marker.size\"),s(\"marker.color\",n),a(t,\"marker\")&&o(t,e,l,s,{prefix:\"marker.\",cLetter:\"c\"}),c=f&&!Array.isArray(f)&&e.marker.color!==f?f:u?r.background:r.defaultLine,s(\"marker.line.color\",c),a(t,\"marker.line\")&&o(t,e,l,s,{prefix:\"marker.line.\",cLetter:\"c\"}),s(\"marker.line.width\",u?1:0),u&&(s(\"marker.sizeref\"),s(\"marker.sizemin\"),s(\"marker.sizemode\"))}},{\"../../components/color\":18,\"../../components/colorscale/defaults\":28,\"../../components/colorscale/has_colorscale\":31,\"./subtypes\":186}],183:[function(t,e,n){\"use strict\";function r(t,e,n){var r=e.x(),o=e.y(),i=a.extent(r.range.map(r.l2c)),l=a.extent(o.range.map(o.l2c));n.forEach(function(t,e){var r=t[0].trace;if(c.hasMarkers(r)){var a=r.marker.maxdisplayed;if(0!==a){var o=t.filter(function(t){return t.x>=i[0]&&t.x<=i[1]&&t.y>=l[0]&&t.y<=l[1]}),s=Math.ceil(o.length/a),u=0;n.forEach(function(t,n){var r=t[0].trace;c.hasMarkers(r)&&r.marker.maxdisplayed>0&&e>n&&u++});var f=Math.round(u*s/3+Math.floor(u/3)*s/7.1);t.forEach(function(t){delete t.vis}),o.forEach(function(t,e){0===Math.round((e+f)%s)&&(t.vis=!0)})}}})}var a=t(\"d3\"),o=t(\"../../lib\"),i=t(\"../../components/drawing\"),l=t(\"../../components/errorbars\"),s=t(\"../../lib/polygon\").tester,c=t(\"./subtypes\"),u=t(\"./arrays_to_calcdata\"),f=t(\"./line_points\");e.exports=function(t,e,n){function d(t){return t.filter(function(t){return t.vis})}r(t,e,n);var h=e.x(),p=e.y(),g=e.plot.select(\".scatterlayer\").selectAll(\"g.trace.scatter\").data(n);g.enter().append(\"g\").attr(\"class\",\"trace scatter\").style(\"stroke-miterlimit\",2),g.call(l.plot,e);var v,m,y,x,b=\"\",_=[];g.each(function(t){var e=t[0].trace,n=e.line,r=a.select(this);if(e.visible===!0&&(m=e.fill.charAt(e.fill.length-1),\"x\"!==m&&\"y\"!==m&&(m=\"\"),t[0].node3=r,u(t),c.hasLines(e)||\"none\"!==e.fill)){var o,l,d,g,w,k=\"\",M=\"\";v=\"tozero\"===e.fill.substr(0,6)||\"toself\"===e.fill||\"to\"===e.fill.substr(0,2)&&!b?r.append(\"path\").classed(\"js-fill\",!0):null,x&&(y=x.datum(t)),x=r.append(\"path\").classed(\"js-fill\",!0),-1!==[\"hv\",\"vh\",\"hvh\",\"vhv\"].indexOf(n.shape)?(d=i.steps(n.shape),g=i.steps(n.shape.split(\"\").reverse().join(\"\"))):d=g=\"spline\"===n.shape?function(t){var e=t[t.length-1];return t[0][0]===e[0]&&t[0][1]===e[1]?i.smoothclosed(t.slice(1),n.smoothing):i.smoothopen(t,n.smoothing)}:function(t){return\"M\"+t.join(\"L\")},w=function(t){return g(t.reverse())};var A,L=f(t,{xaxis:h,yaxis:p,connectGaps:e.connectgaps,baseTolerance:Math.max(n.width||1,3)/4,linear:\"linear\"===n.shape}),T=e._polygons=new Array(L.length);for(A=0;A<L.length;A++)e._polygons[A]=s(L[A]);if(L.length){var z=L[0][0],S=L[L.length-1],E=S[S.length-1];for(A=0;A<L.length;A++){var C=L[A];o=d(C),l=w(C),k?m?(k+=\"L\"+o.substr(1),M=l+(\"L\"+M.substr(1))):(k+=\"Z\"+o,M=l+\"Z\"+M):(k=o,M=l),c.hasLines(e)&&C.length>1&&r.append(\"path\").classed(\"js-line\",!0).style(\"vector-effect\",\"non-scaling-stroke\").attr(\"d\",o)}v?z&&E&&(m?(\"y\"===m?z[1]=E[1]=p.c2p(0,!0):\"x\"===m&&(z[0]=E[0]=h.c2p(0,!0)),v.attr(\"d\",k+\"L\"+E+\"L\"+z+\"Z\")):v.attr(\"d\",k+\"Z\")):\"tonext\"===e.fill.substr(0,6)&&k&&b&&(\"tonext\"===e.fill?y.attr(\"d\",k+\"Z\"+b+\"Z\"):y.attr(\"d\",k+\"L\"+b.substr(1)+\"Z\"),e._polygons=e._polygons.concat(_)),b=M,_=T}}}),g.selectAll(\"path:not([d])\").remove(),g.append(\"g\").attr(\"class\",\"points\").each(function(t){var e=t[0].trace,n=a.select(this),r=c.hasMarkers(e),l=c.hasText(e);!r&&!l||e.visible!==!0?n.remove():(r&&n.selectAll(\"path.point\").data(e.marker.maxdisplayed?d:o.identity).enter().append(\"path\").classed(\"point\",!0).call(i.translatePoints,h,p),l&&n.selectAll(\"g\").data(e.marker.maxdisplayed?d:o.identity).enter().append(\"g\").append(\"text\").call(i.translatePoints,h,p))})}},{\"../../components/drawing\":41,\"../../components/errorbars\":47,\"../../lib\":89,\"../../lib/polygon\":95,\"./arrays_to_calcdata\":166,\"./line_points\":179,\"./subtypes\":186,d3:9}],184:[function(t,e,n){\"use strict\";var r=t(\"./subtypes\"),a=.2;e.exports=function(t,e){var n,o,i,l,s=t.cd,c=t.xaxis,u=t.yaxis,f=[],d=s[0].trace,h=d.index,p=d.marker,g=!r.hasMarkers(d)&&!r.hasText(d);if(d.visible===!0&&!g){var v=Array.isArray(p.opacity)?1:p.opacity;if(e===!1)for(n=0;n<s.length;n++)s[n].dim=0;else for(n=0;n<s.length;n++)o=s[n],i=c.c2p(o.x),l=u.c2p(o.y),e.contains([i,l])?(f.push({curveNumber:h,pointNumber:n,x:o.x,y:o.y}),o.dim=0):o.dim=1;return s[0].node3.selectAll(\"path.point\").style(\"opacity\",function(t){return((t.mo+1||v+1)-1)*(t.dim?a:1)}),s[0].node3.selectAll(\"text\").style(\"opacity\",function(t){return t.dim?a:1}),f}}},{\"./subtypes\":186}],185:[function(t,e,n){\"use strict\";var r=t(\"d3\"),a=t(\"../../components/drawing\"),o=t(\"../../components/errorbars\");e.exports=function(t){var e=r.select(t).selectAll(\"g.trace.scatter\");e.style(\"opacity\",function(t){return t[0].trace.opacity}),e.selectAll(\"g.points\").each(function(t){r.select(this).selectAll(\"path.point\").call(a.pointStyle,t.trace||t[0].trace),r.select(this).selectAll(\"text\").call(a.textPointStyle,t.trace||t[0].trace)}),e.selectAll(\"g.trace path.js-line\").call(a.lineGroupStyle),e.selectAll(\"g.trace path.js-fill\").call(a.fillGroupStyle),e.call(o.style)}},{\"../../components/drawing\":41,\"../../components/errorbars\":47,d3:9}],186:[function(t,e,n){\"use strict\";e.exports={hasLines:function(t){return t.visible&&t.mode&&-1!==t.mode.indexOf(\"lines\")},hasMarkers:function(t){return t.visible&&t.mode&&-1!==t.mode.indexOf(\"markers\")},hasText:function(t){return t.visible&&t.mode&&-1!==t.mode.indexOf(\"text\")},isBubble:function(t){return\"object\"==typeof t.marker&&Array.isArray(t.marker.size)}}},{}],187:[function(t,e,n){\"use strict\";var r=t(\"../../lib\");e.exports=function(t,e,n,a){a(\"textposition\"),r.coerceFont(a,\"textfont\",n.font)}},{\"../../lib\":89}],188:[function(t,e,n){\"use strict\";e.exports=function(t,e,n){var r,a=n(\"x\"),o=n(\"y\");if(a)o?(r=Math.min(a.length,o.length),r<a.length&&(e.x=a.slice(0,r)),r<o.length&&(e.y=o.slice(0,r))):(r=a.length,n(\"y0\"),n(\"dy\"));else{if(!o)return 0;r=e.y.length,n(\"x0\"),n(\"dx\")}return r}},{}]},{},[5])(5)}); </script>\n" -" </head>\n" -" <body>\n" -" <div id=\"header\">\n" -" <label>plot:</label>\n" -" <div class=\"select\">\n" -" <span class=\"arr\"></span>\n" -, -" <select id=\"chooser\">\n" -" <option value=\"summary\">summary</option>\n" -" {% for run in runs %}\n" -" <option value=\"{$loop.index0}\">samples\n" -" {% for param in run.params %}\n" -" | {$param.name}={$param.value}\n" -" {% endfor %}\n" -" </option>\n" -" {% endfor %}\n" -" </select>\n" -" </div>\n" -" <div class=\"is-sorted\">\n" -" <input id=\"is-sorted\" type=\"checkbox\"/>\n" -" <label for=\"is-sorted\">sorted</label>\n" -" </div>\n" -" </div>\n" -" <div id=\"plot\"></div>\n" -" <div id=\"footer\">Generated with <a href=\"http://flamingdangerzone.com/nonius\">nonius</a></div>\n" -" <script type=\"text/javascript\"> !function () {\n" -" var data = {\n" -" title: '{$title}',\n" -" units: '{$units}',\n" -" logarithmic: {$logarithmic},\n" -" param: '{$runparam}',\n" -" runs: [\n" -" {% for run in runs %}{\n" -" params: {\n" -" {% for param in run.params %}'{$param.name}': '{$param.value}',\n" -" {% endfor %}\n" -" },\n" -" benchmarks: [\n" -" {% for benchmark in run.benchmarks %}{\n" -" name: '{$benchmark.name}',\n" -" {%if benchmark.data %}\n" -" mean: {$benchmark.data.mean},\n" -" stddev: {$benchmark.data.stddev},\n" -" samples: [\n" -" {% for sample in benchmark.data.samples %}{$sample}, {% endfor %}\n" -" ],\n" -" {% endif %}\n" -" },{% endfor %}\n" -" ]\n" -" },{% endfor %}\n" -" ]\n" -" };\n" -" var origOrder = data.runs[0].benchmarks.map(function (_, i) { return i; })\n" -" var sortOrder = computeSortedOrder();\n" -" var plotdiv = document.getElementById(\"plot\");\n" -" window.addEventListener(\"resize\", function() {\n" -" Plotly.Plots.resize(plotdiv);\n" -" });\n" -"\n" -" var chooser = document.getElementById(\"chooser\");\n" -" chooser.addEventListener(\"change\", choosePlot);\n" -" chooser.addEventListener(\"blur\", chooser.focus.bind(chooser));\n" -" chooser.focus();\n" -"\n" -" var isSortedBox = document.getElementById(\"is-sorted\");\n" -" isSortedBox.addEventListener(\"change\", choosePlot);\n" -"\n" -" var legendStyle = {\n" -" font: { family: 'monospace' },\n" -" borderwidth: 2,\n" -" bordercolor: 'black'\n" -" }\n" -"\n" -" function zeroes(count) {\n" -" var arr = []\n" -" while (count --> 0) arr.push(0)\n" -" return arr\n" -" }\n" -"\n" -" function computeSortedOrder() {\n" -" // We sort each run. Then we compute the \"points\" of each\n" -" // benchmark as the sum of the positions of this benchmkark on\n" -" // each run. This gives us a rough indication of which\n" -" // benchmark is best -- the lower the points, the better.\n" -" var runsOrder = data.runs.map(function (r) {\n" -" order = r.benchmarks.map(function (_, i) { return i; })\n" -" order.sort(function (a, b) {\n" -" return r.benchmarks[a].mean - r.benchmarks[b].mean\n" -" })\n" -" return order\n" -" })\n" -" var length = data.runs[0].benchmarks.length\n" -" var points = runsOrder.reduce(function (acc, r) {\n" -" r.forEach(function (elem, idx) {\n" -" acc[elem] += idx\n" -" })\n" -" return acc\n" -" }, zeroes(length))\n" -" var order = data.runs[0].benchmarks.map(function (_, i) { return i; })\n" -" order.sort(function (a, b) {\n" -" return points[a] - points[b]\n" -" })\n" -" return order\n" -" }\n" -"\n" -" function choosePlot() {\n" -" var plot = chooser.options[chooser.selectedIndex].value\n" -" var order = isSortedBox.checked ? sortOrder : origOrder\n" -" if (plot == 'summary') {\n" -" if (data.runs.length > 1) {\n" -" plotSummary(order);\n" -" } else {\n" -" plotSingleSummary(order);\n" -" }\n" -" } else {\n" -" plotSamples(plot, order);\n" -" }\n" -" }\n" -"\n" -" function plotSamples(plot, order) {\n" -" var run = data.runs[plot];\n" -" var traces = order.map(function (i) {\n" -" var b = run.benchmarks[i]\n" -" return {\n" -" name: b.name,\n" -" type: 'scatter',\n" -" mode: 'markers',\n" -" marker: { symbol: i },\n" -" y: b.samples,\n" -" x: b.samples && b.samples.map(function (_, i) { return i; })\n" -" }\n" -" });\n" -" var layout = {\n" -" title: data.title,\n" -" showLegend: true,\n" -" xaxis: { title: 'Measurement' },\n" -" yaxis: {\n" -" title: 'Time (' + data.units + ')',\n" -" rangemode: 'tozero',\n" -" zeroline: true\n" -" },\n" -" legend: legendStyle\n" -" };\n" -" Plotly.newPlot(plotdiv, traces, layout);\n" -" }\n" -"\n" -" function plotSummary(order) {\n" -" var traces = order.map(function (i) {\n" -" return {\n" -" name: data.runs[0].benchmarks[i].name,\n" -" type: 'scatter',\n" -" marker: { symbol: i },\n" -" x: data.runs.map(function (r) { return r.params[data.param]; }),\n" -" y: data.runs.map(function (r) { return r.benchmarks[i].mean; }),\n" -" error_y: {\n" -" type: 'data',\n" -" array: data.runs.map(function (r) { return r.benchmarks[i].stddev; }),\n" -" visible: true\n" -" }\n" -" }\n" -" });\n" -" var layout = {\n" -" title: data.title,\n" -" showLegend: true,\n" -" xaxis: {\n" -" title: data.param,\n" -" type: data.logarithmic ? 'log' : '',\n" -" },\n" -" yaxis: {\n" -" title: 'Time (' + data.units + ')',\n" -" rangemode: 'tozero',\n" -" zeroline: true,\n" -" type: data.logarithmic ? 'log' : '',\n" -" },\n" -" legend: legendStyle\n" -" };\n" -" Plotly.newPlot(plotdiv, traces, layout);\n" -" }\n" -"\n" -" function plotSingleSummary(order) {\n" -" var traces = order.map(function (i) {\n" -" var b = data.runs[0].benchmarks[i]\n" -" return {\n" -" type: 'bar',\n" -" name: b.name,\n" -" x: [ data.title ],\n" -" y: [ b.mean ],\n" -" error_y: {\n" -" type: 'data',\n" -" array: [ b.stddev ],\n" -" visible: true\n" -" }\n" -" }\n" -" });\n" -" var layout = {\n" -" title: data.title,\n" -" showLegend: true,\n" -" xaxis: {\n" -" title: '',\n" -" showticklabels: false,\n" -" },\n" -" yaxis: {\n" -" title: 'Time (' + data.units + ')',\n" -" rangemode: 'tozero',\n" -" zeroline: true\n" -" },\n" -" legend: legendStyle\n" -" };\n" -" Plotly.newPlot(plotdiv, traces, layout);\n" -" }\n" -"\n" -" choosePlot();\n" -"}();\n" -" </script>\n" -" </body>\n" -"</html>\n" - }; - static std::string const the_template = []() -> std::string { - std::string s; - for(auto part : template_parts) { - s += part; - } - return s; - }(); - return the_template; - } - - std::string description() override { - return "outputs an HTML file with a single interactive chart of all benchmarks"; - } - - void do_configure(configuration& cfg) override { - cfg.no_analysis = false; - title = cfg.title; - n_samples = cfg.samples; - verbose = cfg.verbose; - logarithmic = cfg.params.run && cfg.params.run->op == "*"; - run_param = cfg.params.run ? cfg.params.run->name : ""; - } - - void do_warmup_start() override { - if(verbose) progress_stream() << "warming up\n"; - } - void do_estimate_clock_resolution_start() override { - if(verbose) progress_stream() << "estimating clock resolution\n"; - } - void do_estimate_clock_cost_start() override { - if(verbose) progress_stream() << "estimating cost of a clock call\n"; - } - - void do_params_start(parameters const& params) override { - if(verbose) progress_stream() << "\n\nnew parameter round\n" << params; - runs.emplace_back(); - runs.back().params = params; - } - void do_benchmark_start(std::string const& name) override { - if(verbose) progress_stream() << "\nbenchmarking " << name << "\n"; - runs.back().data.push_back({name, {}, {}}); - } - - void do_measurement_start(execution_plan<fp_seconds> plan) override { - progress_stream() << std::setprecision(7); - progress_stream().unsetf(std::ios::floatfield); - if(verbose) progress_stream() << "collecting " << n_samples << " samples, " << plan.iterations_per_sample << " iterations each, in estimated " << detail::pretty_duration(plan.estimated_duration) << "\n"; - } - void do_measurement_complete(std::vector<fp_seconds> const& samples) override { - runs.back().data.back().samples = samples; - } - void do_analysis_complete(sample_analysis<fp_seconds> const& analysis) override { - runs.back().data.back().analysis = analysis; - } - void do_benchmark_failure(std::exception_ptr) override { - error_stream() << runs.back().data.back().name << " failed to run successfully\n"; - } - - void do_suite_complete() override { - if(verbose) progress_stream() << "\ngenerating HTML report\n"; - - auto&& templ = template_string(); - auto magnitude = ideal_magnitude(); - - cpptempl::data_map map; - map["title"] = escape(title); - map["units"] = detail::units_for_magnitude(magnitude); - map["logarithmic"] = logarithmic; - map["runparam"] = run_param; - for (auto&& r : runs) { - cpptempl::data_map run_item; - cpptempl::data_list params; - for (auto&& p : r.params) { - cpptempl::data_map item; - item["name"] = p.first; - item["value"] = p.second; - params.push_back(item); - } - run_item["params"] = cpptempl::make_data(params); - for(auto&& d : r.data) { - cpptempl::data_map item; - item["name"] = escape(d.name); - cpptempl::data_map data; - if (!d.samples.empty()) { - data["mean"] = truncate(d.analysis.mean.point.count() * magnitude); - data["stddev"] = truncate(d.analysis.standard_deviation.point.count() * magnitude); - for(auto e : d.samples) - data["samples"].push_back(truncate(e.count() * magnitude)); - } - item["data"] = data; - run_item["benchmarks"].push_back(item); - } - map["runs"].push_back(run_item); - } - - cpptempl::parse(report_stream(), templ, map); - report_stream() << std::flush; - if(verbose) { - progress_stream() << "\n\nresult summary (" - << detail::units_for_magnitude(magnitude) - << ")\n"; - for (auto&& r : runs) { - for (auto&& p : r.params) - progress_stream() << "\n " << p.first << " = " << p.second; - progress_stream() << "\n"; - for(auto&& d : r.data) { - progress_stream() << " " << d.name << "\t " - << truncate(d.analysis.mean.point.count() * magnitude) << "\t " - << truncate(d.analysis.standard_deviation.point.count() * magnitude) - << "\n"; - } - } - progress_stream() << "\ndone\n"; - progress_stream() << std::flush; - } - } - - static double truncate(double x) { - return std::trunc(x * 1000.) / 1000.; - } - - double ideal_magnitude() const { - std::vector<fp_seconds> mins; - mins.reserve(runs.size() * runs.front().data.size()); - for (auto&& r : runs) { - for(auto&& d : r.data) { - if (d.samples.begin() != d.samples.end()) - mins.push_back(*std::min_element(d.samples.begin(), d.samples.end())); - } - } - auto min = *std::min_element(mins.begin(), mins.end()); - return detail::get_magnitude(min); - } - - static std::string escape(std::string const& source) { - static const std::unordered_map<char, std::string> escapes { - { '\'', "'" }, - { '"', """ }, - { '<', "<" }, - { '>', ">" }, - { '&', "&" }, - { '\\', "\\\\" }, - }; - return detail::escape(source, escapes); - } - - struct result_t { - std::string name; - std::vector<fp_seconds> samples; - sample_analysis<fp_seconds> analysis; - }; - - struct run_t { - parameters params; - std::vector<result_t> data; - }; - - int n_samples; - bool verbose; - std::string title; - bool logarithmic; - std::string run_param; - std::vector<run_t> runs; - }; - - NONIUS_REPORTER("html", html_reporter); -} // namespace nonius - -#endif // NONIUS_DISABLE_HTML_REPORTER -#endif // NONIUS_DISABLE_EXTRA_REPORTERS - -#endif // NONIUS_HPP -// #included from: main.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Executable building kit - -#define NONIUS_MAIN_HPP - -// #included from: detail/argparse.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// Command-line argument parsing - -#define NONIUS_ARGPARSE_HPP - -// #included from: detail/mismatch.h++ -// Nonius - C++ benchmarking tool -// -// Written in 2014- by the nonius contributors <nonius@rmf.io> -// -// To the extent possible under law, the author(s) have dedicated all copyright and related -// and neighboring rights to this software to the public domain worldwide. This software is -// distributed without any warranty. -// -// You should have received a copy of the CC0 Public Domain Dedication along with this software. -// If not, see <http://creativecommons.org/publicdomain/zero/1.0/> - -// mismatch algorithm - -#define NONIUS_DETAIL_MISMATCH_HPP - -#include <utility> - -namespace nonius { - namespace detail { - template <typename InputIt1, typename InputIt2, typename BinaryPredicate> - std::pair<InputIt1, InputIt2> mismatch(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate p) { - while(first1 != last1 && first2 != last2 && p(*first1, *first2)) { - ++first1, ++first2; - } - return std::make_pair(first1, first2); - } - } // namespace detail -} // namespace nonius - -#include <string> -#include <unordered_map> -#include <vector> -#include <algorithm> -#include <ostream> -#include <iomanip> -#include <tuple> -#include <functional> - -namespace nonius { - namespace detail { - struct option { - bool matches_short(std::string const& s) const { - return s == ("-" + short_form); - } - std::tuple<bool, std::string::const_iterator> long_separator(std::string const& s) const { - auto l = "--" + long_form; - auto its = detail::mismatch(s.begin(), s.end(), l.begin(), l.end(), [](char a, char b) { return a == b; }); - return std::make_tuple(its.second == l.end(), its.first); - } - bool matches_long(std::string const& s) const { - return std::get<0>(long_separator(s)); - } - bool matches_long(std::string const& s, std::string& argument) const { - bool match; std::string::const_iterator it; - std::tie(match, it) = long_separator(s); - if(match && it != s.end()) { - if(*it == '=') argument.assign(it+1, s.end()); - else return false; - } - return match; - } - - option(std::string long_form, std::string short_form, std::string description, std::string argument = std::string(), bool multiple = false) - : long_form(std::move(long_form)), short_form(std::move(short_form)), description(std::move(description)), argument(std::move(argument)), multiple(multiple) {} - - std::string long_form; - std::string short_form; - std::string description; - std::string argument; - bool multiple; - }; - - using option_set = std::vector<option>; - - struct help_text { - help_text(std::string name, option_set const& options) : name(std::move(name)), options(options) {} - std::string name; - option_set const& options; - }; - - template <typename Iterator, typename Projection> - int get_max_width(Iterator first, Iterator last, Projection proj) { - auto it = std::max_element(first, last, [&proj](option const& a, option const& b) { return proj(a) < proj(b); }); - return static_cast<int>(proj(*it)); - } - - inline std::ostream& operator<<(std::ostream& os, help_text h) { - os << "Usage: " << h.name << " [OPTIONS]\n\n"; - - auto lwidth = 2 + get_max_width(h.options.begin(), h.options.end(), [](option const& o) { return 2 + o.long_form.size() + 1 + o.argument.size(); }); - auto swidth = 2 + get_max_width(h.options.begin(), h.options.end(), [](option const& o) { return 1 + o.short_form.size() + 1 + o.argument.size(); }); - - os << std::left; - for(auto o : h.options) { - auto l = "--" + o.long_form; - auto s = "-" + o.short_form; - if(!o.argument.empty()) { - l += "=" + o.argument; - s += " " + o.argument; - } - os << std::setw(lwidth) << l - << std::setw(swidth) << s - << o.description - << '\n'; - } - return os; - } - - using arguments = std::unordered_multimap<std::string, std::string>; - - struct argument_error { - virtual ~argument_error() = default; - }; - - template <typename Iterator> - void parse_short(option const& o, arguments& args, Iterator& first, Iterator last) { - if(!o.argument.empty()) { - if(++first != last) { - args.emplace(o.long_form, *first); - } else { - throw argument_error(); - } - } else { - args.emplace(o.long_form, ""); - } - } - inline void parse_long(option const& o, arguments& args, std::string&& arg) { - args.emplace(o.long_form, std::move(arg)); - } - - template <typename Iterator> - arguments parse_arguments(option_set const& options, Iterator first, Iterator last) { - arguments args; - for(; first != last; ++first) { - bool parsed = false; - for(auto&& option : options) { - if(option.matches_short(*first)) { - parse_short(option, args, first, last); - parsed = true; - } else { - std::string arg; - if(option.matches_long(*first, arg)) { - parse_long(option, args, std::move(arg)); - parsed = true; - } - } - } - if(!parsed) { - throw argument_error(); - } - } - return args; - } - } // namespace detail -} // namespace nonius - -#include <boost/algorithm/string.hpp> - -#include <vector> -#include <string> -#include <stdexcept> -#include <exception> -#include <iostream> -#include <iomanip> -#include <utility> - -namespace nonius { - namespace detail { - template <typename T> - struct parser; - template <> - struct parser<int> { - static int parse(std::string const& s) { return std::stoi(s); } - }; - template <> - struct parser<double> { - static double parse(std::string const& s) { return std::stod(s); } - }; - template <> - struct parser<std::string> { - static std::string parse(std::string const& s) { return s; } - }; - template <> - struct parser<bool> { - static bool parse(std::string const&) { return true; } - }; - template <> - struct parser<param_configuration> { - static param_configuration parse(std::string const& param) { - auto v = std::vector<std::string>{}; - boost::split(v, param, boost::is_any_of(":")); - try { - if (v.size() > 0) { - auto name = v[0]; - auto def = global_param_registry().defaults().at(name); - if (v.size() == 2) - return {{{name, def.parse(v[1])}}, {}}; - else if (v.size() == 5) { - auto oper = v[1]; - auto init = def.parse(v[2]); - auto step = def.parse(v[3]); - auto count = boost::lexical_cast<std::size_t>(v[4]); - return {{}, run_configuration{name, oper, init, step, count}}; - } - } - } - catch (boost::bad_lexical_cast const&) {} - catch (std::out_of_range const&) {} - return {}; - } - }; - struct assign_fn { - template <typename T, typename U> - void operator() (T& dest, U&& src) const { dest = std::forward<U>(src); } - }; - template <typename T, typename Predicate, typename Assignment=assign_fn> - void parse(T& variable, detail::arguments& args, std::string const& option, Predicate&& is_valid, Assignment&& assign={}) { - auto rng = args.equal_range(option); - for (auto it = rng.first; it != rng.second; ++it) { - if(it != args.end()) { - auto value = parser<T>::parse(it->second); - if(is_valid(value)) { - std::forward<Assignment>(assign) (variable, std::move(value)); - } else { - throw argument_error(); - } - } - } - } - template <typename T> - void parse(T& variable, detail::arguments& args, std::string const& option) { - return parse(variable, args, option, [](T const&) { return true; }); - } - - inline detail::option_set const& command_line_options() { - static detail::option_set the_options { - detail::option("help", "h", "show this help message"), - detail::option("samples", "s", "number of samples to collect (default: 100)", "SAMPLES"), - detail::option("resamples", "rs", "number of resamples for the bootstrap (default: 100000)", "RESAMPLES"), - detail::option("confidence-interval", "ci", "confidence interval for the bootstrap (between 0 and 1, default: 0.95)", "INTERVAL"), - detail::option("param", "p", "set a benchmark parameter", "PARAM"), - detail::option("output", "o", "output file (default: <stdout>)", "FILE"), - detail::option("reporter", "r", "reporter to use (default: standard)", "REPORTER"), - detail::option("title", "t", "set report title", "TITLE"), - detail::option("no-analysis", "A", "perform only measurements; do not perform any analysis"), - detail::option("filter", "f", "only run benchmarks whose name matches the regular expression pattern", "PATTERN"), - detail::option("list", "l", "list benchmarks"), - detail::option("list-params", "lp", "list available parameters"), - detail::option("list-reporters", "lr", "list available reporters"), - detail::option("verbose", "v", "show verbose output (mutually exclusive with -q)"), - detail::option("summary", "q", "show summary output (mutually exclusive with -v)") - }; - return the_options; - } - - template <typename Iterator> - configuration parse_args(std::string const& name, Iterator first, Iterator last) { - try { - auto args = detail::parse_arguments(command_line_options(), first, last); - - configuration cfg; - - auto is_positive = [](int x) { return x > 0; }; - auto is_ci = [](double x) { return x > 0 && x < 1; }; - auto is_reporter = [](std::string const x) { return global_reporter_registry().count(x) > 0; }; - auto is_param = [](param_configuration const& x) { - return !x.map.empty() || x.run; - }; - auto merge_params = [](param_configuration& x, param_configuration&& y) { - x.map = std::move(x.map).merged(std::move(y.map)); - if (y.run) x.run = y.run; - }; - - parse(cfg.help, args, "help"); - parse(cfg.samples, args, "samples", is_positive); - parse(cfg.resamples, args, "resamples", is_positive); - parse(cfg.confidence_interval, args, "confidence-interval", is_ci); - parse(cfg.params, args, "param", is_param, merge_params); - parse(cfg.output_file, args, "output"); - parse(cfg.reporter, args, "reporter", is_reporter); - parse(cfg.no_analysis, args, "no-analysis"); - parse(cfg.filter_pattern, args, "filter"); - parse(cfg.list_benchmarks, args, "list"); - parse(cfg.list_params, args, "list-params"); - parse(cfg.list_reporters, args, "list-reporters"); - parse(cfg.verbose, args, "verbose"); - parse(cfg.summary, args, "summary"); - parse(cfg.title, args, "title"); - if(cfg.verbose && cfg.summary) throw argument_error(); - - return cfg; - } catch(...) { - std::cout << help_text(name, command_line_options()); - throw argument_error(); - } - } - } // namespace detail - - inline int print_help(std::string const& name) { - std::cout << detail::help_text(name, detail::command_line_options()); - return 0; - } - inline int list_benchmarks() { - std::cout << "All available benchmarks:\n"; - for(auto&& b : global_benchmark_registry()) { - std::cout << " " << b.name << "\n"; - } - std::cout << global_benchmark_registry().size() << " benchmarks\n\n"; - return 0; - } - inline int list_params() { - std::cout << "Available parameters (= default):\n" - << global_param_registry().defaults(); - return 0; - } - inline int list_reporters() { - using reporter_entry_ref = decltype(*global_reporter_registry().begin()); - auto cmp = [](reporter_entry_ref a, reporter_entry_ref b) { return a.first.size() < b.first.size(); }; - auto width = 2 + std::max_element(global_reporter_registry().begin(), global_reporter_registry().end(), cmp)->first.size(); - - std::cout << "Available reporters:\n"; - std::cout << std::left; - for(auto&& r : global_reporter_registry()) { - if(!r.first.empty()) { - std::cout << " " << std::setw(width) << r.first << r.second->description() << "\n"; - } - } - std::cout << '\n'; - return 0; - } - inline int run_it(configuration cfg) { - try { - nonius::go(cfg); - } catch(...) { - std::cerr << "PANIC: clock is on fire\n"; - try { - throw; - } catch(std::exception const& e) { - std::cerr << " " << e.what() << "\n"; - } catch(...) {} - return 23; - } - return 0; - } - - template <typename Iterator> - int main(std::string const& name, Iterator first, Iterator last) { - configuration cfg; - - try { - cfg = detail::parse_args(name, first, last); - } catch(detail::argument_error const&) { - return 17; - } - - if(cfg.help) return print_help(name); - else if(cfg.list_benchmarks) return list_benchmarks(); - else if(cfg.list_params) return list_params(); - else if(cfg.list_reporters) return list_reporters(); - else return run_it(cfg); - } - inline int main(int argc, char** argv) { - std::string name(argv[0]); - std::vector<std::string> args(argv+1, argv+argc); - return main(name, args.begin(), args.end()); - } -} - -#ifdef NONIUS_RUNNER -int main(int argc, char** argv) { - return nonius::main(argc, argv); -} -#endif // NONIUS_RUNNER - -#endif // NONIUS_SINGLE_INCLUDE_HPP diff --git a/third_party/immer/tools/include/prettyprint.hpp b/third_party/immer/tools/include/prettyprint.hpp deleted file mode 100644 index f75683ccdd51..000000000000 --- a/third_party/immer/tools/include/prettyprint.hpp +++ /dev/null @@ -1,445 +0,0 @@ -// Copyright Louis Delacroix 2010 - 2014. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// -// A pretty printing library for C++ -// -// Usage: -// Include this header, and operator<< will "just work". - -#ifndef H_PRETTY_PRINT -#define H_PRETTY_PRINT - -#include <cstddef> -#include <iterator> -#include <memory> -#include <ostream> -#include <set> -#include <tuple> -#include <type_traits> -#include <unordered_set> -#include <utility> -#include <valarray> - -namespace pretty_print -{ - namespace detail - { - // SFINAE type trait to detect whether T::const_iterator exists. - - struct sfinae_base - { - using yes = char; - using no = yes[2]; - }; - - template <typename T> - struct has_const_iterator : private sfinae_base - { - private: - template <typename C> static yes & test(typename C::const_iterator*); - template <typename C> static no & test(...); - public: - static const bool value = sizeof(test<T>(nullptr)) == sizeof(yes); - using type = T; - }; - - template <typename T> - struct has_begin_end : private sfinae_base - { - private: - template <typename C> - static yes & f(typename std::enable_if< - std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::begin)), - typename C::const_iterator(C::*)() const>::value>::type *); - - template <typename C> static no & f(...); - - template <typename C> - static yes & g(typename std::enable_if< - std::is_same<decltype(static_cast<typename C::const_iterator(C::*)() const>(&C::end)), - typename C::const_iterator(C::*)() const>::value, void>::type*); - - template <typename C> static no & g(...); - - public: - static bool const beg_value = sizeof(f<T>(nullptr)) == sizeof(yes); - static bool const end_value = sizeof(g<T>(nullptr)) == sizeof(yes); - }; - - } // namespace detail - - - // Holds the delimiter values for a specific character type - - template <typename TChar> - struct delimiters_values - { - using char_type = TChar; - const char_type * prefix; - const char_type * delimiter; - const char_type * postfix; - }; - - - // Defines the delimiter values for a specific container and character type - - template <typename T, typename TChar> - struct delimiters - { - using type = delimiters_values<TChar>; - static const type values; - }; - - - // Functor to print containers. You can use this directly if you want - // to specificy a non-default delimiters type. The printing logic can - // be customized by specializing the nested template. - - template <typename T, - typename TChar = char, - typename TCharTraits = ::std::char_traits<TChar>, - typename TDelimiters = delimiters<T, TChar>> - struct print_container_helper - { - using delimiters_type = TDelimiters; - using ostream_type = std::basic_ostream<TChar, TCharTraits>; - - template <typename U> - struct printer - { - static void print_body(const U & c, ostream_type & stream) - { - using std::begin; - using std::end; - - auto it = begin(c); - const auto the_end = end(c); - - if (it != the_end) - { - for ( ; ; ) - { - stream << *it; - - if (++it == the_end) break; - - if (delimiters_type::values.delimiter != NULL) - stream << delimiters_type::values.delimiter; - } - } - } - }; - - print_container_helper(const T & container) - : container_(container) - { } - - inline void operator()(ostream_type & stream) const - { - if (delimiters_type::values.prefix != NULL) - stream << delimiters_type::values.prefix; - - printer<T>::print_body(container_, stream); - - if (delimiters_type::values.postfix != NULL) - stream << delimiters_type::values.postfix; - } - - private: - const T & container_; - }; - - // Specialization for pairs - - template <typename T, typename TChar, typename TCharTraits, typename TDelimiters> - template <typename T1, typename T2> - struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::pair<T1, T2>> - { - using ostream_type = typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type; - - static void print_body(const std::pair<T1, T2> & c, ostream_type & stream) - { - stream << c.first; - if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL) - stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter; - stream << c.second; - } - }; - - // Specialization for tuples - - template <typename T, typename TChar, typename TCharTraits, typename TDelimiters> - template <typename ...Args> - struct print_container_helper<T, TChar, TCharTraits, TDelimiters>::printer<std::tuple<Args...>> - { - using ostream_type = typename print_container_helper<T, TChar, TCharTraits, TDelimiters>::ostream_type; - using element_type = std::tuple<Args...>; - - template <std::size_t I> struct Int { }; - - static void print_body(const element_type & c, ostream_type & stream) - { - tuple_print(c, stream, Int<0>()); - } - - static void tuple_print(const element_type &, ostream_type &, Int<sizeof...(Args)>) - { - } - - static void tuple_print(const element_type & c, ostream_type & stream, - typename std::conditional<sizeof...(Args) != 0, Int<0>, std::nullptr_t>::type) - { - stream << std::get<0>(c); - tuple_print(c, stream, Int<1>()); - } - - template <std::size_t N> - static void tuple_print(const element_type & c, ostream_type & stream, Int<N>) - { - if (print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter != NULL) - stream << print_container_helper<T, TChar, TCharTraits, TDelimiters>::delimiters_type::values.delimiter; - - stream << std::get<N>(c); - - tuple_print(c, stream, Int<N + 1>()); - } - }; - - // Prints a print_container_helper to the specified stream. - - template<typename T, typename TChar, typename TCharTraits, typename TDelimiters> - inline std::basic_ostream<TChar, TCharTraits> & operator<<( - std::basic_ostream<TChar, TCharTraits> & stream, - const print_container_helper<T, TChar, TCharTraits, TDelimiters> & helper) - { - helper(stream); - return stream; - } - - - // Basic is_container template; specialize to derive from std::true_type for all desired container types - - template <typename T> - struct is_container : public std::integral_constant<bool, - detail::has_const_iterator<T>::value && - detail::has_begin_end<T>::beg_value && - detail::has_begin_end<T>::end_value> { }; - - template <typename T, std::size_t N> - struct is_container<T[N]> : std::true_type { }; - - template <std::size_t N> - struct is_container<char[N]> : std::false_type { }; - - template <typename T> - struct is_container<std::valarray<T>> : std::true_type { }; - - template <typename T1, typename T2> - struct is_container<std::pair<T1, T2>> : std::true_type { }; - - template <typename ...Args> - struct is_container<std::tuple<Args...>> : std::true_type { }; - - - // Default delimiters - - template <typename T> struct delimiters<T, char> { static const delimiters_values<char> values; }; - template <typename T> const delimiters_values<char> delimiters<T, char>::values = { "[", ", ", "]" }; - template <typename T> struct delimiters<T, wchar_t> { static const delimiters_values<wchar_t> values; }; - template <typename T> const delimiters_values<wchar_t> delimiters<T, wchar_t>::values = { L"[", L", ", L"]" }; - - - // Delimiters for (multi)set and unordered_(multi)set - - template <typename T, typename TComp, typename TAllocator> - struct delimiters< ::std::set<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; }; - - template <typename T, typename TComp, typename TAllocator> - const delimiters_values<char> delimiters< ::std::set<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" }; - - template <typename T, typename TComp, typename TAllocator> - struct delimiters< ::std::set<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; }; - - template <typename T, typename TComp, typename TAllocator> - const delimiters_values<wchar_t> delimiters< ::std::set<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" }; - - template <typename T, typename TComp, typename TAllocator> - struct delimiters< ::std::multiset<T, TComp, TAllocator>, char> { static const delimiters_values<char> values; }; - - template <typename T, typename TComp, typename TAllocator> - const delimiters_values<char> delimiters< ::std::multiset<T, TComp, TAllocator>, char>::values = { "{", ", ", "}" }; - - template <typename T, typename TComp, typename TAllocator> - struct delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; }; - - template <typename T, typename TComp, typename TAllocator> - const delimiters_values<wchar_t> delimiters< ::std::multiset<T, TComp, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - const delimiters_values<char> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - struct delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - const delimiters_values<wchar_t> delimiters< ::std::unordered_set<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char> { static const delimiters_values<char> values; }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - const delimiters_values<char> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, char>::values = { "{", ", ", "}" }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - struct delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t> { static const delimiters_values<wchar_t> values; }; - - template <typename T, typename THash, typename TEqual, typename TAllocator> - const delimiters_values<wchar_t> delimiters< ::std::unordered_multiset<T, THash, TEqual, TAllocator>, wchar_t>::values = { L"{", L", ", L"}" }; - - - // Delimiters for pair and tuple - - template <typename T1, typename T2> struct delimiters<std::pair<T1, T2>, char> { static const delimiters_values<char> values; }; - template <typename T1, typename T2> const delimiters_values<char> delimiters<std::pair<T1, T2>, char>::values = { "(", ", ", ")" }; - template <typename T1, typename T2> struct delimiters< ::std::pair<T1, T2>, wchar_t> { static const delimiters_values<wchar_t> values; }; - template <typename T1, typename T2> const delimiters_values<wchar_t> delimiters< ::std::pair<T1, T2>, wchar_t>::values = { L"(", L", ", L")" }; - - template <typename ...Args> struct delimiters<std::tuple<Args...>, char> { static const delimiters_values<char> values; }; - template <typename ...Args> const delimiters_values<char> delimiters<std::tuple<Args...>, char>::values = { "(", ", ", ")" }; - template <typename ...Args> struct delimiters< ::std::tuple<Args...>, wchar_t> { static const delimiters_values<wchar_t> values; }; - template <typename ...Args> const delimiters_values<wchar_t> delimiters< ::std::tuple<Args...>, wchar_t>::values = { L"(", L", ", L")" }; - - - // Type-erasing helper class for easy use of custom delimiters. - // Requires TCharTraits = std::char_traits<TChar> and TChar = char or wchar_t, and MyDelims needs to be defined for TChar. - // Usage: "cout << pretty_print::custom_delims<MyDelims>(x)". - - struct custom_delims_base - { - virtual ~custom_delims_base() { } - virtual std::ostream & stream(::std::ostream &) = 0; - virtual std::wostream & stream(::std::wostream &) = 0; - }; - - template <typename T, typename Delims> - struct custom_delims_wrapper : custom_delims_base - { - custom_delims_wrapper(const T & t_) : t(t_) { } - - std::ostream & stream(std::ostream & s) - { - return s << print_container_helper<T, char, std::char_traits<char>, Delims>(t); - } - - std::wostream & stream(std::wostream & s) - { - return s << print_container_helper<T, wchar_t, std::char_traits<wchar_t>, Delims>(t); - } - - private: - const T & t; - }; - - template <typename Delims> - struct custom_delims - { - template <typename Container> - custom_delims(const Container & c) : base(new custom_delims_wrapper<Container, Delims>(c)) { } - - std::unique_ptr<custom_delims_base> base; - }; - - template <typename TChar, typename TCharTraits, typename Delims> - inline std::basic_ostream<TChar, TCharTraits> & operator<<(std::basic_ostream<TChar, TCharTraits> & s, const custom_delims<Delims> & p) - { - return p.base->stream(s); - } - - - // A wrapper for a C-style array given as pointer-plus-size. - // Usage: std::cout << pretty_print_array(arr, n) << std::endl; - - template<typename T> - struct array_wrapper_n - { - typedef const T * const_iterator; - typedef T value_type; - - array_wrapper_n(const T * const a, size_t n) : _array(a), _n(n) { } - inline const_iterator begin() const { return _array; } - inline const_iterator end() const { return _array + _n; } - - private: - const T * const _array; - size_t _n; - }; - - - // A wrapper for hash-table based containers that offer local iterators to each bucket. - // Usage: std::cout << bucket_print(m, 4) << std::endl; (Prints bucket 5 of container m.) - - template <typename T> - struct bucket_print_wrapper - { - typedef typename T::const_local_iterator const_iterator; - typedef typename T::size_type size_type; - - const_iterator begin() const - { - return m_map.cbegin(n); - } - - const_iterator end() const - { - return m_map.cend(n); - } - - bucket_print_wrapper(const T & m, size_type bucket) : m_map(m), n(bucket) { } - - private: - const T & m_map; - const size_type n; - }; - -} // namespace pretty_print - - -// Global accessor functions for the convenience wrappers - -template<typename T> -inline pretty_print::array_wrapper_n<T> pretty_print_array(const T * const a, size_t n) -{ - return pretty_print::array_wrapper_n<T>(a, n); -} - -template <typename T> pretty_print::bucket_print_wrapper<T> -bucket_print(const T & m, typename T::size_type n) -{ - return pretty_print::bucket_print_wrapper<T>(m, n); -} - - -// Main magic entry point: An overload snuck into namespace std. -// Can we do better? - -namespace std -{ - // Prints a container to the stream using default delimiters - - template<typename T, typename TChar, typename TCharTraits> - inline typename enable_if< ::pretty_print::is_container<T>::value, - basic_ostream<TChar, TCharTraits> &>::type - operator<<(basic_ostream<TChar, TCharTraits> & stream, const T & container) - { - return stream << ::pretty_print::print_container_helper<T, TChar, TCharTraits>(container); - } -} - - - -#endif // H_PRETTY_PRINT diff --git a/third_party/immer/tools/reproduce-paper-results.bash b/third_party/immer/tools/reproduce-paper-results.bash deleted file mode 100755 index 0ee2b98c3406..000000000000 --- a/third_party/immer/tools/reproduce-paper-results.bash +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -test -d build || mkdir -p build -cd build - -cmake .. \ - -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native" \ - -DCHECK_BENCHMARKS=1 \ - -DBENCHMARK_PARAM="N:1000" -DBENCHMARK_SAMPLES="100" -make benchmarks -j1 -ctest -R "benchmark/vector-paper*" - -cmake ..\ - -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native" \ - -DCHECK_BENCHMARKS=1 \ - -DBENCHMARK_PARAM="N:100000" -DBENCHMARK_SAMPLES="20" -make benchmarks -j1 -ctest -R "benchmark/vector-paper*" - -cmake .. \ - -DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_FLAGS="-O3 -march=native" \ - -DCHECK_BENCHMARKS=1 \ - -DBENCHMARK_PARAM="N:10000000" -DBENCHMARK_SAMPLES="3" -make benchmarks -j1 -ctest -R "benchmark/vector-paper*" diff --git a/third_party/immer/tools/scala/README.md b/third_party/immer/tools/scala/README.md deleted file mode 100644 index ce514e445e99..000000000000 --- a/third_party/immer/tools/scala/README.md +++ /dev/null @@ -1,6 +0,0 @@ - -``` -# sbt -> test -> test-only org.immer.* -- -verbose -``` diff --git a/third_party/immer/tools/scala/build.sbt b/third_party/immer/tools/scala/build.sbt deleted file mode 100644 index f2d0bd2cf03c..000000000000 --- a/third_party/immer/tools/scala/build.sbt +++ /dev/null @@ -1,27 +0,0 @@ -/** This is the simplest possible use of ScalaMeter. - * It allows running ScalaMeter benchmarks as part of the test suite. - * It means, that when the test command is run, ScalaMeter benchmarks are run along - * the tests from other test frameworks, such as ScalaTest or ScalaCheck. - */ -lazy val basic = Project( - "basic", - file("."), - settings = Defaults.coreDefaultSettings ++ Seq( - name := "immer-bechmarks", - organization := "org.immer", - scalaVersion := "2.11.1", - scalacOptions ++= Seq("-deprecation", "-unchecked", "-feature", "-Xlint"), - publishArtifact := false, - libraryDependencies ++= Seq( - "com.storm-enroute" %% "scalameter" % "0.8.2" % "test", - "io.github.nicolasstucki" %% "scala-rrb-vector" % "0.1.1" - ), - resolvers ++= Seq( - "Sonatype OSS Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots", - "Sonatype OSS Releases" at "https://oss.sonatype.org/content/repositories/releases" - ), - testFrameworks += new TestFramework("org.scalameter.ScalaMeterFramework"), - parallelExecution in Test := false, - logBuffered := false - ) -) diff --git a/third_party/immer/tools/scala/src/test/scala/org/immer/benchmarks.scala b/third_party/immer/tools/scala/src/test/scala/org/immer/benchmarks.scala deleted file mode 100644 index 98c40a45cd66..000000000000 --- a/third_party/immer/tools/scala/src/test/scala/org/immer/benchmarks.scala +++ /dev/null @@ -1,168 +0,0 @@ -package org.immer - -import org.scalameter.api._ -import scala.collection.immutable.Vector -import scala.collection.immutable.rrbvector.RRBVector - -class BenchmarkBase extends Bench.ForkedTime { - val runs = 20 - val size = 1000 - val step = 10 - val sizes = Gen.range("size")(size, size, 1) - - //def relaxedV(v : RRBVector[Int], n : Int) : RRBVector[Int] = { - // var r = v - // for (i <- 0 to n) { - // r = (RRBVector.empty[Int] :+ i) ++ r - // } - // r - //} - - var vectors = for { s <- sizes } yield Vector.empty[Int] ++ (0 until s) - var rrbvectors = for { s <- sizes } yield RRBVector.empty[Int] ++ (0 until s) - //var rrbvectorsF = for { s <- sizes } yield relaxedV(RRBVector.empty[Int], s) - var rrbsteps = for { s <- sizes } yield RRBVector.empty[Int] ++ (0 until s / step) -} - -class PushBenchmark extends BenchmarkBase { - performance of "push" in { - measure method "Vector" in { using(sizes) config(exec.benchRuns -> runs) in { s => { - var v = Vector.empty[Int] - for (a <- 0 to s) { - v = v :+ a - } - v - }}} - measure method "RRBVector" in { using(sizes) config(exec.benchRuns -> runs) in { s => { - var v = RRBVector.empty[Int] - for (a <- 0 to s) { - v = v :+ a - } - v - }}} - } -} - -class UpdateBenchmark extends BenchmarkBase { - performance of "update" in { - measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v0 => { - var v = v0 - for (a <- 0 to v.size - 1) { - v = v.updated(a, a + 1) - } - v - }}} - measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v0 => { - var v = v0 - for (a <- 0 to v.size - 1) { - v = v.updated(a, a + 1) - } - v - }}} - //measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v0 => { - // var v = v0 - // for (a <- 0 to v.size - 1) { - // v = v.updated(a, a + 1) - // } - // v - //}}} - } - performance of "update/random" in { - measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v0 => { - var v = v0 - var r = new scala.util.Random - for (a <- 0 to v.size - 1) { - v = v.updated(r.nextInt(v.size), a + 1) - } - v - }}} - measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v0 => { - var v = v0 - var r = new scala.util.Random - for (a <- 0 to v.size - 1) { - v = v.updated(r.nextInt(v.size), a + 1) - } - v - }}} - //measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v0 => { - // var v = v0 - // var r = new scala.util.Random - // for (a <- 0 to v.size - 1) { - // v = v.updated(r.nextInt(v.size), a + 1) - // } - // v - //}}} - } -} - -object IterBenchmark extends BenchmarkBase { - performance of "access/reduce" in { - measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v => { - v.reduceLeft(_ + _) - }}} - measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v => { - v.reduceLeft(_ + _) - }}} - //measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v => { - // v.reduceLeft(_ + _) - //}}} - } - performance of "access/idx" in { - measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v => { - var r = 0 - for (a <- 0 to v.size - 1) { - r += v(a) - } - r - }}} - measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v => { - var r = 0 - for (a <- 0 to v.size - 1) { - r += v(a) - } - r - }}} - //measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v => { - // var r = 0 - // for (a <- 0 to v.size - 1) { - // r += v(a) - // } - // r - //}}} - } - performance of "access/iter" in { - measure method "Vector" in { using(vectors) config(exec.benchRuns -> runs) in { v => { - var r = 0 - for (a <- v) { - r += a - } - r - }}} - measure method "RRBVector" in { using(rrbvectors) config(exec.benchRuns -> runs) in { v => { - var r = 0 - for (a <- v) { - r += a - } - r - }}} - //measure method "RRBVector/relaxed" in { using(rrbvectorsF) config(exec.benchRuns -> runs) in { v => { - // var r = 0 - // for (a <- v) { - // r += a - // } - // r - //}}} - } -} - -class ConcatBenchmark extends BenchmarkBase { - performance of "concat" in { - measure method "RRBVector ++" in { using(rrbsteps) config(exec.benchRuns -> runs) in { v => { - var r = RRBVector.empty[Int] - for (_ <- 0 to step) { - r = r ++ v - } - r - }}} - } -} diff --git a/third_party/immer/tools/scala/version.sbt b/third_party/immer/tools/scala/version.sbt deleted file mode 100644 index 3f0ac089016a..000000000000 --- a/third_party/immer/tools/scala/version.sbt +++ /dev/null @@ -1 +0,0 @@ -version in ThisBuild := "0.8.2" diff --git a/third_party/immer/tools/sinusoidal-sphinx-theme b/third_party/immer/tools/sinusoidal-sphinx-theme deleted file mode 160000 -Subproject b5adfa2a6def8aa55d95dedc4e1bfde214a5e36 diff --git a/third_party/immer/tools/travis/ssh-key.enc b/third_party/immer/tools/travis/ssh-key.enc deleted file mode 100644 index 9793aac2df7a..000000000000 --- a/third_party/immer/tools/travis/ssh-key.enc +++ /dev/null Binary files differdiff --git a/third_party/immer/tools/travis/ssh-key.pub b/third_party/immer/tools/travis/ssh-key.pub deleted file mode 100644 index 9994a9772d68..000000000000 --- a/third_party/immer/tools/travis/ssh-key.pub +++ /dev/null @@ -1 +0,0 @@ -ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBLgrMsYWwjiR/oe2bzg1kr1CGgLYiLrvQIeZw9mv10qF+MS+xpthy4tXxEHHeqkbQ1FsSoo3RaCKnya47LTysT1HE4Qf1TbxY5b1kU9SJ0jGNYejvkdmWzg/wspSCbFi3PGJhctxoks5sJCfVMc/oFwIlFAZALfL3JIRYk8EZv7bnrtA1Il1hPV2ug7ADBWJOXCc8pW4E7X3ZiDnvAZfqZ1QHrcQwy1aA8LVTv5azJg7Db8D90JjuRTlhO1XL7Cg/PGBkP1B3jOW5LRZK8AupnOPTw4kIsIc/i32O/poZPIRbHqYumYqEKBJQ/ggN4rKVXcp0lrMZ6/joslFLMvwr immer diff --git a/third_party/immer/tools/with-tee.bash b/third_party/immer/tools/with-tee.bash deleted file mode 100755 index 60c331326d28..000000000000 --- a/third_party/immer/tools/with-tee.bash +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -echo "${@:2} | tee $1" - -${@:2} | tee $1 |