From 42925a84cfaae0edade635ca01c8f50af02c2795 Mon Sep 17 00:00:00 2001 From: Stian Soiland-Reyes Date: Mon, 22 May 2023 17:03:28 +0100 Subject: [PATCH 01/17] Add FAIR data and RO-Crate module Squashed commit of the following: commit 272b8f4eb1b21edc966999be2d7d6c2e1ee41bb6 Merge: 60825e16b1a 2f91c9e7931 Author: Stian Soiland-Reyes Date: Mon May 22 17:02:04 2023 +0100 Merge remote-tracking branch 'upstream/main' into ro-crate commit 60825e16b1a7ea362ea1c17c1ca935f19fc718dd Author: Stian Soiland-Reyes Date: Mon May 22 16:53:31 2023 +0100 Rearranged commit 170cad822b3f5620dc393f276a22182890f2cd46 Author: Stian Soiland-Reyes Date: Mon May 22 16:01:39 2023 +0100 Rainfall example 1.2.1 commit 84e5dbf51dfad4672b7dec305a834cae3e6319fe Author: Stian Soiland-Reyes Date: Mon May 22 15:33:39 2023 +0100 directories -> folders commit fa8efaff03f0fe44c7d391a21917237ddb633678 Merge: fe929a2894b 303078e6a50 Author: Stian Soiland-Reyes Date: Mon May 22 13:15:34 2023 +0100 Merge branch 'ro-crate' of github.com:ResearchObject/galaxy-training-material into ro-crate commit fe929a2894b1f6e1da192d72b714287fe62515a3 Author: Stian Soiland-Reyes Date: Mon May 22 13:13:04 2023 +0100 link to introduction commit 8629dd5bd1244b5fff6fd3a53ab2a6799cf27e06 Author: Stian Soiland-Reyes Date: Mon May 22 12:48:46 2023 +0100 final typos commit 142ff8e560bccee2c8c9da841de1e79384dfe3ee Author: Stian Soiland-Reyes Date: Mon May 22 12:46:20 2023 +0100 more metadata commit 983634d27053dd794ffc61cbc835670eebfa05d1 Author: Stian Soiland-Reyes Date: Mon May 22 12:17:40 2023 +0100 something on JSON-LD playground commit beacd601dcb277458d24a657c4aba4c10f29fb79 Author: Stian Soiland-Reyes Date: Mon May 22 11:52:02 2023 +0100 about licenses commit 0fcd826f5f84467eb8e458d2d2479f90710c560f Author: Stian Soiland-Reyes Date: Mon May 22 11:25:51 2023 +0100 more on JSON-LD playground commit 66c37e14b400234c7b7028254dde6a86982c944d Author: Stian Soiland-Reyes Date: Mon May 22 11:23:19 2023 +0100 more on contextual commit 48fdf024f6089fb53bf5e7d8dfb376bdd00cf639 Author: Stian Soiland-Reyes Date: Mon May 22 10:40:47 2023 +0100 more on file formats commit a9c1a5ef407a9bb73423f80f76ae0f7e58ad4a3c Author: Stian Soiland-Reyes Date: Mon May 22 10:23:48 2023 +0100 more tutorial commit 12701eb90beaaeb265ec4e406f41b59bbef17ef7 Author: Stian Soiland-Reyes Date: Mon May 22 09:45:19 2023 +0100 more on licence commit 46266ef1a3a601a87da5a594b6ea185acfb523ba Author: Stian Soiland-Reyes Date: Mon May 22 09:39:52 2023 +0100 Start rewriting commit 303078e6a50a7d6f198bdec8e1fb179d4de779d9 Author: Stian Soiland-Reyes Date: Fri Apr 28 13:21:24 2023 +0100 Update tutorial.md commit 2d80340a7ac8f5cfafb8831a9698e01eed65217e Author: Stian Soiland-Reyes Date: Thu Apr 27 20:28:16 2023 +0100 Attempt to add ro-crate-intro as tutorial commit a54e8337175a3b994aee21967c1672f9da0df15d Author: Stian Soiland-Reyes Date: Mon Apr 17 20:02:05 2023 +0100 Add skeleton RO-Crate intro --- CONTRIBUTORS.yaml | 13 +- .../images/ro-crate-intro/crate1-folders.png | Bin 0 -> 13529 bytes .../ro-crate-intro/introduction-figure-1.svg | 291 + .../jsonld-playground-table.png | Bin 0 -> 305697 bytes .../jsonld-playground-visualized.png | Bin 0 -> 95225 bytes .../ro-crate-preview-example.png | Bin 0 -> 98264 bytes topics/data-science/metadata.yaml | 3 + .../ro-crate-intro/rainfall-1.2.1/data.csv | 3 + .../ro-crate-intro/rainfall-1.2.1/index.html | 1 + .../rainfall-1.2.1/ro-crate-metadata.json | 76 + .../rainfall-1.2.1/ro-crate-preview.html | 366 + .../ro-crate-preview_files/bootstrap.min.css | 7 + .../font-awesome.min.css | 4 + .../ro-crate-dynamic.js | 34026 ++++++++++++++++ .../tutorials/ro-crate-intro/tutorial.md | 642 + 15 files changed, 35431 insertions(+), 1 deletion(-) create mode 100644 topics/data-science/images/ro-crate-intro/crate1-folders.png create mode 100644 topics/data-science/images/ro-crate-intro/introduction-figure-1.svg create mode 100644 topics/data-science/images/ro-crate-intro/jsonld-playground-table.png create mode 100644 topics/data-science/images/ro-crate-intro/jsonld-playground-visualized.png create mode 100644 topics/data-science/images/ro-crate-intro/ro-crate-preview-example.png create mode 100644 topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/data.csv create mode 120000 topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/index.html create mode 100644 topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-metadata.json create mode 100644 topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview.html create mode 100644 topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/bootstrap.min.css create mode 100644 topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/font-awesome.min.css create mode 100644 topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/ro-crate-dynamic.js create mode 100644 topics/data-science/tutorials/ro-crate-intro/tutorial.md diff --git a/CONTRIBUTORS.yaml b/CONTRIBUTORS.yaml index 86ad9bd2cbea6..e152b3ad5e2dd 100644 --- a/CONTRIBUTORS.yaml +++ b/CONTRIBUTORS.yaml @@ -1258,6 +1258,10 @@ pravs3683: email: kumar207@umn.edu joined: 2019-04 +ptsefton: + name: Peter Sefton + orcid: 0000-0002-3545-944X + pvanheus: name: Peter van Heusden twitter: pvanheus @@ -1414,9 +1418,16 @@ sophia120199: stain: name: Stian Soiland-Reyes - joined: 2023-04 + email: soiland-reyes@manchester.ac.uk + twitter: soilandreyes orcid: 0000-0001-9842-9718 + joined: 2023-04 elixir_node: uk + location: + country: UK + lat: 53.46724379071192 + lon: -2.233631283105614 + fediverse: https://scholar.social/@soilandreyes stephanierobin: name: Stéphanie Robin diff --git a/topics/data-science/images/ro-crate-intro/crate1-folders.png b/topics/data-science/images/ro-crate-intro/crate1-folders.png new file mode 100644 index 0000000000000000000000000000000000000000..f1891db325612efec85b1041b794791d0ae93976 GIT binary patch literal 13529 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 bodx@vo-Og0pq0KJM}kw5Q + + + + + + + + + + + + { "@id": "./", "@type": "Dataset", "name": "Example dataset for RO-Crate specification", "description": "Official rainfall readings… "datePublished": "2022-12-01", "hasPart": [ {"@id": "data.csv"} ]} + + + + + + { "@id": "ro-crate-metadata.json", "@type": "CreativeWork", "conformsTo": {"@id": "https://w3id.org/ro/crate/1.2"}, "about": {"@id": "./"}} + + + + + + + + + + { "@id": "./", "@type": "Dataset", "name": "Example dataset for RO-Crate specification", "description": "Official rainfall readings… "datePublished": "2022-12-01", "hasPart": [ {"@id": "data.csv"} ]} + + + diff --git a/topics/data-science/images/ro-crate-intro/jsonld-playground-table.png b/topics/data-science/images/ro-crate-intro/jsonld-playground-table.png new file mode 100644 index 0000000000000000000000000000000000000000..af4c68104ae8ccdfbe974ccdf26e8570385d7851 GIT binary patch literal 305697 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
d-Y+Y2uJLTZD7<&vAI>?b=OP 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

ukUk;(NcRWqo8eR2k-5%&w5|;q$yf@Bl^_3f6 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

=7aVFi3v4O2qGGvsXekB$p3{C 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

  • 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 literal 0 HcmV?d00001 diff --git a/topics/data-science/images/ro-crate-intro/jsonld-playground-visualized.png b/topics/data-science/images/ro-crate-intro/jsonld-playground-visualized.png new file mode 100644 index 0000000000000000000000000000000000000000..8c341031848dababdc125bd1bd58617aedd32638 GIT binary patch literal 95225 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%0A?47wRgCEx*5C^eNl0iE0@#XEhYyF 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 + + + + + + + + + + + + + + + + + + + + +

    +
    + + + + +
    +
    +
    +

    Example dataset for RO-Crate specification

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +


    +
    +

    Go to: Josiah Carberry

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    + +
    +


    +
    +

    ⬇️ Download: Rainfall Katoomba 2022-02

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +


    +
    +

    Go to: CC0-1.0

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +


    +
    +

    Go to: Brown University

    + + + + +
    + + + + + + + + + + + + + + + + + + + + + + +
    + +
    +


    +
    + + + + + + + diff --git a/topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/bootstrap.min.css b/topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/bootstrap.min.css new file mode 100644 index 0000000000000..e6b4977799e3a --- /dev/null +++ b/topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.2.1 (https://getbootstrap.com/) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(2.25rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.8125rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(2.875rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:2.25rem;background-repeat:no-repeat;background-position:center right calc(2.25rem / 4);background-size:calc(2.25rem / 2) calc(2.25rem / 2);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e")}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2.25rem;background-position:top calc(2.25rem / 4) right calc(2.25rem / 4)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:3.4375rem;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") no-repeat center right 1.75rem/1.125rem 1.125rem}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:2.25rem;background-repeat:no-repeat;background-position:center right calc(2.25rem / 4);background-size:calc(2.25rem / 2) calc(2.25rem / 2);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E")}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2.25rem;background-position:top calc(2.25rem / 4) right calc(2.25rem / 4)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:3.4375rem;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") no-repeat center right 1.75rem/1.125rem 1.125rem}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media screen and (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media screen and (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-right{right:0;left:auto}}.dropdown-menu-left{right:auto;left:0}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:first-child{border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.dropdown-item:last-child{border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(2.875rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.8125rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:2.25rem;padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;color:inherit;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion .card{overflow:hidden}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion .card .card-header{margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media screen and (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled){cursor:pointer}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);border-radius:.25rem;box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-dialog-centered::before{display:block;height:calc(100vh - (.5rem * 2));content:""}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-dialog-centered::before{height:calc(100vh - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media screen and (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media screen and (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media screen and (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-3by4::before{padding-top:133.333333%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/font-awesome.min.css b/topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/font-awesome.min.css new file mode 100644 index 0000000000000..540440ce89f2a --- /dev/null +++ b/topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/font-awesome.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/ro-crate-dynamic.js b/topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/ro-crate-dynamic.js new file mode 100644 index 0000000000000..1cff39b7a467a --- /dev/null +++ b/topics/data-science/tutorials/ro-crate-intro/rainfall-1.2.1/ro-crate-preview_files/ro-crate-dynamic.js @@ -0,0 +1,34026 @@ +(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i. +*/ + + + +const back_links = { + hasFile: "fileOf", + hasPart: "isPartOf", + hasMember: "memberOf", + memberOf: "hasMember" + } + +const roCrateMetadataID = "ro-crate-metadata.jsonld"; + +const DATASET_TEMPLATE = { + "@type": "Dataset", + "@id": "./", + }; + +const METADATA_FILE_DESCRIPTOR = { + "@type": "CreativeWork", + "@id": roCrateMetadataID, + "identifier": roCrateMetadataID, + "about": {"@id": "./"} + }; + +const back_back_links = new Set(Object.values(back_links)); + +const defaults = { + ro_crate_name: "ro-crate-metadata", + roCrateMetadataID: "ro-crate-metadata.jsonld", + context: ["https://researchobject.github.io/ro-crate/1.0/context.jsonld", {"@vocab": "http://schema.org/"}], + render_script: "https://unpkg.com/ro-crate-html-js/dist/ro-crate-dynamic.js", + multi_page_render_script: "https://unpkg.com/ro-crate-html-js/dist/ro-crate-dynamic-multipage.js", + back_links: back_links, + back_back_links: back_back_links, + datasetTemplate: DATASET_TEMPLATE, + metadataFileDescriptorTemplate: METADATA_FILE_DESCRIPTOR, + ROCrate_Specification_Identifier: "https://researchobject.github.io/ro-crate/1.0/", + roCratePreviewFileName: "ro-crate-preview.html", + pageSize: 50 +} + + +module.exports = defaults; + +},{}],2:[function(require,module,exports){ +/* + +This is part of ro-crate-html-js a tool for generating HTMl +previews of HTML files. + +Copyright (C) 2021 University of Technology Sydney + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +const Preview = require("./ro-crate-preview"); +const Checker = require("ro-crate").Checker; +const ROCrate = require("ro-crate").ROCrate; +const { config } = require("chai"); + +var meta; +var preview; + +async function check() { + var checker = new Checker(meta); + await checker.check(); + document.getElementById("check").innerHTML = `
    ${checker.summarize()}
    ${checker.report()}
    `; +}; + +async function load() { + if (!meta) { + meta = new ROCrate( + JSON.parse(document.querySelector('script[type="application/ld+json"]').innerHTML) + ); + preview = await new Preview(meta, config); + meta.resolveContext().then(function () {updatePage()}); // This is async + } + var css = document.createElement('style'); + css.type = 'text/css'; + var styles = 'summary { display: list-item; }'; + css.appendChild(document.createTextNode(styles)); + + document.getElementsByTagName("head")[0].appendChild(css); + + + document.getElementsByTagName("body").append + document.getElementById("check").innerHTML = ""; + updatePage(); +} + +window.onhashchange = function () { + load(); +}; + +window.onload = function () { + load(); +}; + + + +async function updatePage() { + var hash = location.hash; + + if (hash.startsWith("#___check")) { + check(); + } else if (hash) { + await preview.display(unescape(hash.replace("#", ""))); + } else { + await preview.display(preview.root["@id"]); + } +} + +},{"./ro-crate-preview":4,"chai":33,"ro-crate":70}],3:[function(require,module,exports){ +/* + +This is part of ro-crate-html-js a tool for generating HTMl +previews of HTML files. + +Copyright (C) 2021 University of Technology Sydney + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +class Page { + constructor(args) { + this.pageSize = args.pageSize || 20; + var values = args.values; + //Values is an array (or singleton) of strings / or objects + if (!Array.isArray(values)) { + values = [values]; + } + this.pages = []; + this.values = []; + + const l = values.length; + this.first = values[0]; + [this.last] = values.slice(-1); + if (l <= this.pageSize) { + this.values = values; + } + else if (l <= this.pageSize * this.pageSize) { + for (let s = 0; s <= l ; s += this.pageSize) + { + this.pages.push(new Page({values: values.slice(s, s + this.pageSize), pageSize: this.pageSize})); + } + } else { + for (let s = 0; s < l ; s += this.pageSize * this.pageSize) + { + this.pages.push(new Page({values: values.slice(s, s + this.pageSize * this.pageSize), pageSize: this.pageSize} )) + } + } + } +} +module.exports = Page; + + +},{}],4:[function(require,module,exports){ +/* + +This is part of ro-crate-html-js a tool for generating HTMl +previews of HTML files. + +Copyright (C) 2021 University of Technology Sydney + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +const defaults = require("./defaults"); +const _ = require("lodash"); +const Page = require("./paginate"); +const { times } = require("lodash"); + +const display_keys = [ + "@id", + "name", + "familyName", + "givenName", + "@type", + "description", + "funder", + "memberOf", + "isPartOf", + "fileOf", + "thumbnail", + "datePublished", + "author", + "encodingFormat", + "contentSize", + "affiliation", + "email" + ]; + +const displayTypeTemplates = { + "PropertyValue" : (item)=> {return `${item.name}: ${item.value}`}, + "GeoCoordinates" : (item)=> {return `Lat: ${item.latitude }, Long: ${item.longitude}`} +} + + + + +class Preview { + constructor(crate, config, id) { + this.defaults = defaults; + this.crate = crate; + this.config = _.clone(config) || {}; //TODO - add some defaults here; + this.crate.index(); + this.crate.addBackLinks(); + this.rootId = this.crate.getRootId(); + this.baseID = id || this.rootId; + this.root = this.crate.getRootDataset(); + if (!this.crate.context) { + this.crate.resolveContext(); + } + this.places = []; + } + + + async display(id) { + const datasetDisplay = await this.renderMetadataForItem(id); + document.getElementById("summary").innerHTML = datasetDisplay; + } + + completeDataset(entryID, dontShowRootDataset) { + entryID = entryID || this.crate.getRootId(); + var html = ""; + html += this.metaTable(this.crate.getItem(entryID)); + this.baseID = entryID; + for (let item of this.crate.getJson()["@graph"]) { + if (item["@id"] != entryID && + !this.displayTypeAsString(item) && + !this.crate.defaults.roCrateMetadataIDs.includes(item["@id"]) && !(dontShowRootDataset && item["@id"] === this.crate.getRootID())){ + html += this.metaTable(item, true); + } + } + return html; + } + + async summarizeDataset() { + // Makes HTML tables for RO-Crate Core Metadata - just a teaser of the contents, not all of it + var keepIds = [this.rootId]; + for (let prop of this.sortKeys(Object.keys(this.root))) { + var values = this.crate.utils.asArray(this.root[prop]); + for (let v of values) { + if (v["@id"] && !keepIds.includes(v["@id"]) ) { + keepIds.push(v["@id"]); + } + } + } + // Now prune out stuff we don't need into a new graph + var newGraph = [] + for (let i of this.crate.getJson()["@graph"]) { + if (keepIds.includes(i['@id'])) { + newGraph.push(i); + } + } + + //this.crate.getJson()["@graph"] = newGraph; + //this.crate.init(this.crate.getJson()); + // And generate HTML for what's left + const dontShowPreviews = (this.root.hasPart && this.root.hasPart.length > defaults.pageSize); + var allMeta = `
    `; + for (let i of keepIds) { + allMeta += await this.renderMetadataForItem(i, dontShowPreviews); + allMeta += "


    "; + } + allMeta += `
    `; + // Don't try to show files if there are a lot - ie more than one + + return allMeta; + } + + + + async renderMetadataForItem(id, dontShowPreviews) { + var item = _.clone(this.crate.getItem(id)); + if (!item) { + return ""; + } + // Check if there are any parts that should be displayed up top + + + + + // Thumbnail if present + + // Display a table or table-like - core metadata show all the properties + + + var itemHtml = ` +
    + ${this.header(item)} + ${this.image(item)} + ${this.previews(item, dontShowPreviews)} + ${this.articleBody(item)} + ${this.metaTable(item)} + +
    + `; + return itemHtml; + + } + + displayPlaces() { + const config = this.config; + // Places is an GeoJSON object + if (config && this.places && this.places.type === "FeatureCollection") { + + var jsonString = JSON.stringify(places,null,2) + + const dir = config.geoURL; + return ` + + + + + + + + + + + + +
    + + + + + Download GeoJSON + + + ` + } else { + return ``; + } + } + + header(item) { + // Display the name of the thing with apropriate download links etc + var name = item.name ? item.name : item["@id"]; + var types = this.crate.utils.asArray(item["@type"]); + var view; + var path = item["@id"]; + var idLink = ""; + // Special treatment for Datasets - add download links if there is a distribution + if (path.match(/^https?:\/\//i)) { + view = "Go to: "; + } else if (types.includes("Dataset")){ + if (window.location.href.match(/^file:\/\//i)){ + view = "Browse files "; + } + if (item["distribution"]) { + for (let dist of this.crate.utils.asArray(item["distribution"])){ + const download = this.crate.getItem(dist["@id"]); + // Dealing with legacy - we used to have path mapped to contentUrl + if (download) { + var downloadName = download.name ? download.name : name; + var u = download["contentUrl"] ? download["contentUrl"] : download["path"]; + if (u) { + idLink += `⬇️📦 Download this dataset: ${downloadName}
    `; + + } + } + } + } + } else if ( types.includes("File") || types.includes("ImageObject") || types.includes("MediaObject") || path === "ro-crate-metadata.jsonld"){ + view = "⬇️ Download: "; + } + if (view){ + idLink += `${view}`; + } + return `

    ${idLink} ${name}

    ` + } + + image(item) { + var image = ""; + if (item.image || item.thumbnail) { + var src; + if (item.image && item.image.length > 0 ) { + src = this.crate.utils.asArray(item.image)[0]; + delete item.image; + } else if (item.thumbnail && item.thumbnail.length > 0){ + src = this.crate.utils.asArray(item.thumbnail)[0]; + delete item.thumbnail; + } + if (src) { + if (src["@id"]) { + src = src["@id"]; + } + image = ``; + } + } + return image; + } + articleBody(item) { + // See if there are any fragments to display - if there are references to things which have + // articleBody but no name (for lab notebook display) + var articleBody = "" + for (let part of this.crate.utils.asArray(item.hasPart)) { + const p = this.crate.getItem(part["@id"]); + if (p && this.crate.utils.asArray(p["@type"]).includes("Article") && p.articleBody) { + for (let b of this.crate.utils.asArray(p.articleBody)) + { + articleBody += `

    ${p.description}
    ${b}
    ` + } + } + } + return articleBody; + } + + script() { + const url = this.config.renderScript || this.crate.defaults.render_script; + return `` + } + previews(item, dontShowPreviews) { + var p = `${item["@id"]}`; + if (this.config.utils) { + p = this.config.utils.getImagePath(this.baseID, p) + } + + + + var previews = ""; + var types = this.crate.utils.asArray(item["@type"]); + if (!dontShowPreviews && (types.includes("Dataset") || types.includes("File") ||types.includes("ImageObject") ||types.includes("MediaObject"))) { + if (p.match(/(\.txt$)|(\.html?$)/i)){ + previews += ``; + } else if (p.match(/(\.mp3)|(\.ogg?)|(\.wav)$/i)){ + previews += ``; + } else if (p.match(/(\.jpe?g)|(\.png)$/i)){ + previews += ``; + } + else if (p.match(/pdf$/i)){ + previews += ``; + + } + } + return previews; + } + + metaTable(it, showName) { + // Generate a "table" (or other structure) + const item = _.clone(it); + var name = ""; + if (showName) { + name = `

    ${this.crate.utils.asArray(item.name).join(" ")}

    `; + delete item.name; + } + var rows = ""; + for (let prop of this.sortKeys(Object.keys(item))) { + if (prop === "@reverse") { + // Do nothing + } else { + rows += this.metadataRow(item, prop); + } + } + if (item["@reverse"]) { + rows += `Items that reference this one`; + for (let prop of Object.keys(item["@reverse"])) { + rows += this.metadataRow(item["@reverse"], prop); + + } + } + return ` +
    + ${name} + + ${rows} + +
    `; + } + + sortKeys(keys) { + // Sort a set or array of keys to be in a nice order + // Returns set + var keys_in_order = new Set(); + keys = new Set(keys); + for (let key of display_keys) { + if (keys.has(key)) { + keys_in_order.add(key); + } + } + for (let key of keys) { + if (!keys_in_order.has(key)) { + keys_in_order.add(key); + } + } + return keys_in_order; + } + + + metadataRow(item, prop){ + if (this.crate.context) { + const def = this.crate.getDefinition(prop); + var propName = prop; + if (def["rdfs:comment"]) { + propName = def["rdfs:label"] || propName; + propName = `${propName} [?]` + + } else if (def["@id"]) { + propName = `${propName} [?]`; + } + } + return ` + ${propName} + ${this.displayValues(item[prop])} + `; + } + + displayValuesAsString(v) { + const vals = this.crate.utils.asArray(v); + var html = ""; + for (v of vals) { + html += this.displayValue(v); + } + return html; +} + + displayValues(v) { + const vals = this.crate.utils.asArray(v); + const page = new Page({values: vals, pageSize: this.defaults.pageSize}); + return this.displayPage(page); +} + + +displayPage(page) { + var html = ""; + if (page.pages.length > 0) { + for (let p of page.pages) { + if (p.first && p.last) { + html += ` +
    + + ${this.displayValue(p.first)} -to- ${this.displayValue(p.last)} + + ${this.displayPage(p)} +
    + `; + } + } + } else { + if (page.values.length > 1 ) { + html += "
      "; + for (let p of page.values) { + html += ` +
    • ${this.displayValue(p)}
    • + `; + } + html += "
    "; + } else if (page.values[0]) { + html += `${this.displayValue(page.values[0])}`; + } + } + return html; + } + + + displayTypeAsString(item){ + // Return either false or a function to render this particular type of item + const types = this.crate.utils.asArray(item["@type"]); + for (let type of types) { + const renderFunction = displayTypeTemplates[type]; + if (renderFunction) { + return renderFunction; + } + } + return null; + } + + + displayValue(val) { + if (val["@id"]) { + var target = this.crate.getItem(val["@id"]); + if (target) { + var name = target.name || target.value || target["@id"]; + if (this.config.utils && this.config.utils.hasOwnPage(target, this.config)) { + return `${name}`; + } + const renderFunction = this.displayTypeAsString(target); + if (!renderFunction) { + return `${name}` + } else { + return renderFunction(target); + } + } else { + if (val["@id"].toString().match(/^https?:\/\//i)) { + return `${val["@id"]}` + } + else { + return val["@id"]; + } + } + } + + else if (val.toString().match(/^https?:\/\//i)) { + return `${val}`; + } else { + return `${val}`; + } + } +} + +module.exports = Preview; + +},{"./defaults":1,"./paginate":3,"lodash":68}],5:[function(require,module,exports){ +/*! + * assertion-error + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +/*! + * Return a function that will copy properties from + * one object to another excluding any originally + * listed. Returned function will create a new `{}`. + * + * @param {String} excluded properties ... + * @return {Function} + */ + +function exclude () { + var excludes = [].slice.call(arguments); + + function excludeProps (res, obj) { + Object.keys(obj).forEach(function (key) { + if (!~excludes.indexOf(key)) res[key] = obj[key]; + }); + } + + return function extendExclude () { + var args = [].slice.call(arguments) + , i = 0 + , res = {}; + + for (; i < args.length; i++) { + excludeProps(res, args[i]); + } + + return res; + }; +}; + +/*! + * Primary Exports + */ + +module.exports = AssertionError; + +/** + * ### AssertionError + * + * An extension of the JavaScript `Error` constructor for + * assertion and validation scenarios. + * + * @param {String} message + * @param {Object} properties to include (optional) + * @param {callee} start stack function (optional) + */ + +function AssertionError (message, _props, ssf) { + var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') + , props = extend(_props || {}); + + // default values + this.message = message || 'Unspecified AssertionError'; + this.showDiff = false; + + // copy from properties + for (var key in props) { + this[key] = props[key]; + } + + // capture stack trace + ssf = ssf || AssertionError; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, ssf); + } else { + try { + throw new Error(); + } catch(e) { + this.stack = e.stack; + } + } +} + +/*! + * Inherit from Error.prototype + */ + +AssertionError.prototype = Object.create(Error.prototype); + +/*! + * Statically set name + */ + +AssertionError.prototype.name = 'AssertionError'; + +/*! + * Ensure correct constructor + */ + +AssertionError.prototype.constructor = AssertionError; + +/** + * Allow errors to be converted to JSON for static transfer. + * + * @param {Boolean} include stack (default: `true`) + * @return {Object} object that can be `JSON.stringify` + */ + +AssertionError.prototype.toJSON = function (stack) { + var extend = exclude('constructor', 'toJSON', 'stack') + , props = extend({ name: this.name }, this); + + // include stack if exists and not turned off + if (false !== stack && this.stack) { + props.stack = this.stack; + } + + return props; +}; + +},{}],6:[function(require,module,exports){ +module.exports = require('./lib/axios'); +},{"./lib/axios":8}],7:[function(require,module,exports){ +'use strict'; + +var utils = require('./../utils'); +var settle = require('./../core/settle'); +var cookies = require('./../helpers/cookies'); +var buildURL = require('./../helpers/buildURL'); +var buildFullPath = require('../core/buildFullPath'); +var parseHeaders = require('./../helpers/parseHeaders'); +var isURLSameOrigin = require('./../helpers/isURLSameOrigin'); +var createError = require('../core/createError'); + +module.exports = function xhrAdapter(config) { + return new Promise(function dispatchXhrRequest(resolve, reject) { + var requestData = config.data; + var requestHeaders = config.headers; + + if (utils.isFormData(requestData)) { + delete requestHeaders['Content-Type']; // Let the browser set it + } + + var request = new XMLHttpRequest(); + + // HTTP basic authentication + if (config.auth) { + var username = config.auth.username || ''; + var password = config.auth.password ? unescape(encodeURIComponent(config.auth.password)) : ''; + requestHeaders.Authorization = 'Basic ' + btoa(username + ':' + password); + } + + var fullPath = buildFullPath(config.baseURL, config.url); + request.open(config.method.toUpperCase(), buildURL(fullPath, config.params, config.paramsSerializer), true); + + // Set the request timeout in MS + request.timeout = config.timeout; + + // Listen for ready state + request.onreadystatechange = function handleLoad() { + if (!request || request.readyState !== 4) { + return; + } + + // The request errored out and we didn't get a response, this will be + // handled by onerror instead + // With one exception: request that using file: protocol, most browsers + // will return status as 0 even though it's a successful request + if (request.status === 0 && !(request.responseURL && request.responseURL.indexOf('file:') === 0)) { + return; + } + + // Prepare the response + var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders(request.getAllResponseHeaders()) : null; + var responseData = !config.responseType || config.responseType === 'text' ? request.responseText : request.response; + var response = { + data: responseData, + status: request.status, + statusText: request.statusText, + headers: responseHeaders, + config: config, + request: request + }; + + settle(resolve, reject, response); + + // Clean up request + request = null; + }; + + // Handle browser request cancellation (as opposed to a manual cancellation) + request.onabort = function handleAbort() { + if (!request) { + return; + } + + reject(createError('Request aborted', config, 'ECONNABORTED', request)); + + // Clean up request + request = null; + }; + + // Handle low level network errors + request.onerror = function handleError() { + // Real errors are hidden from us by the browser + // onerror should only fire if it's a network error + reject(createError('Network Error', config, null, request)); + + // Clean up request + request = null; + }; + + // Handle timeout + request.ontimeout = function handleTimeout() { + var timeoutErrorMessage = 'timeout of ' + config.timeout + 'ms exceeded'; + if (config.timeoutErrorMessage) { + timeoutErrorMessage = config.timeoutErrorMessage; + } + reject(createError(timeoutErrorMessage, config, 'ECONNABORTED', + request)); + + // Clean up request + request = null; + }; + + // Add xsrf header + // This is only done if running in a standard browser environment. + // Specifically not if we're in a web worker, or react-native. + if (utils.isStandardBrowserEnv()) { + // Add xsrf header + var xsrfValue = (config.withCredentials || isURLSameOrigin(fullPath)) && config.xsrfCookieName ? + cookies.read(config.xsrfCookieName) : + undefined; + + if (xsrfValue) { + requestHeaders[config.xsrfHeaderName] = xsrfValue; + } + } + + // Add headers to the request + if ('setRequestHeader' in request) { + utils.forEach(requestHeaders, function setRequestHeader(val, key) { + if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') { + // Remove Content-Type if data is undefined + delete requestHeaders[key]; + } else { + // Otherwise add header to the request + request.setRequestHeader(key, val); + } + }); + } + + // Add withCredentials to request if needed + if (!utils.isUndefined(config.withCredentials)) { + request.withCredentials = !!config.withCredentials; + } + + // Add responseType to request if needed + if (config.responseType) { + try { + request.responseType = config.responseType; + } catch (e) { + // Expected DOMException thrown by browsers not compatible XMLHttpRequest Level 2. + // But, this can be suppressed for 'json' type as it can be parsed by default 'transformResponse' function. + if (config.responseType !== 'json') { + throw e; + } + } + } + + // Handle progress if needed + if (typeof config.onDownloadProgress === 'function') { + request.addEventListener('progress', config.onDownloadProgress); + } + + // Not all browsers support upload events + if (typeof config.onUploadProgress === 'function' && request.upload) { + request.upload.addEventListener('progress', config.onUploadProgress); + } + + if (config.cancelToken) { + // Handle cancellation + config.cancelToken.promise.then(function onCanceled(cancel) { + if (!request) { + return; + } + + request.abort(); + reject(cancel); + // Clean up request + request = null; + }); + } + + if (!requestData) { + requestData = null; + } + + // Send the request + request.send(requestData); + }); +}; + +},{"../core/buildFullPath":14,"../core/createError":15,"./../core/settle":19,"./../helpers/buildURL":23,"./../helpers/cookies":25,"./../helpers/isURLSameOrigin":28,"./../helpers/parseHeaders":30,"./../utils":32}],8:[function(require,module,exports){ +'use strict'; + +var utils = require('./utils'); +var bind = require('./helpers/bind'); +var Axios = require('./core/Axios'); +var mergeConfig = require('./core/mergeConfig'); +var defaults = require('./defaults'); + +/** + * Create an instance of Axios + * + * @param {Object} defaultConfig The default config for the instance + * @return {Axios} A new instance of Axios + */ +function createInstance(defaultConfig) { + var context = new Axios(defaultConfig); + var instance = bind(Axios.prototype.request, context); + + // Copy axios.prototype to instance + utils.extend(instance, Axios.prototype, context); + + // Copy context to instance + utils.extend(instance, context); + + return instance; +} + +// Create the default instance to be exported +var axios = createInstance(defaults); + +// Expose Axios class to allow class inheritance +axios.Axios = Axios; + +// Factory for creating new instances +axios.create = function create(instanceConfig) { + return createInstance(mergeConfig(axios.defaults, instanceConfig)); +}; + +// Expose Cancel & CancelToken +axios.Cancel = require('./cancel/Cancel'); +axios.CancelToken = require('./cancel/CancelToken'); +axios.isCancel = require('./cancel/isCancel'); + +// Expose all/spread +axios.all = function all(promises) { + return Promise.all(promises); +}; +axios.spread = require('./helpers/spread'); + +// Expose isAxiosError +axios.isAxiosError = require('./helpers/isAxiosError'); + +module.exports = axios; + +// Allow use of default import syntax in TypeScript +module.exports.default = axios; + +},{"./cancel/Cancel":9,"./cancel/CancelToken":10,"./cancel/isCancel":11,"./core/Axios":12,"./core/mergeConfig":18,"./defaults":21,"./helpers/bind":22,"./helpers/isAxiosError":27,"./helpers/spread":31,"./utils":32}],9:[function(require,module,exports){ +'use strict'; + +/** + * A `Cancel` is an object that is thrown when an operation is canceled. + * + * @class + * @param {string=} message The message. + */ +function Cancel(message) { + this.message = message; +} + +Cancel.prototype.toString = function toString() { + return 'Cancel' + (this.message ? ': ' + this.message : ''); +}; + +Cancel.prototype.__CANCEL__ = true; + +module.exports = Cancel; + +},{}],10:[function(require,module,exports){ +'use strict'; + +var Cancel = require('./Cancel'); + +/** + * A `CancelToken` is an object that can be used to request cancellation of an operation. + * + * @class + * @param {Function} executor The executor function. + */ +function CancelToken(executor) { + if (typeof executor !== 'function') { + throw new TypeError('executor must be a function.'); + } + + var resolvePromise; + this.promise = new Promise(function promiseExecutor(resolve) { + resolvePromise = resolve; + }); + + var token = this; + executor(function cancel(message) { + if (token.reason) { + // Cancellation has already been requested + return; + } + + token.reason = new Cancel(message); + resolvePromise(token.reason); + }); +} + +/** + * Throws a `Cancel` if cancellation has been requested. + */ +CancelToken.prototype.throwIfRequested = function throwIfRequested() { + if (this.reason) { + throw this.reason; + } +}; + +/** + * Returns an object that contains a new `CancelToken` and a function that, when called, + * cancels the `CancelToken`. + */ +CancelToken.source = function source() { + var cancel; + var token = new CancelToken(function executor(c) { + cancel = c; + }); + return { + token: token, + cancel: cancel + }; +}; + +module.exports = CancelToken; + +},{"./Cancel":9}],11:[function(require,module,exports){ +'use strict'; + +module.exports = function isCancel(value) { + return !!(value && value.__CANCEL__); +}; + +},{}],12:[function(require,module,exports){ +'use strict'; + +var utils = require('./../utils'); +var buildURL = require('../helpers/buildURL'); +var InterceptorManager = require('./InterceptorManager'); +var dispatchRequest = require('./dispatchRequest'); +var mergeConfig = require('./mergeConfig'); + +/** + * Create a new instance of Axios + * + * @param {Object} instanceConfig The default config for the instance + */ +function Axios(instanceConfig) { + this.defaults = instanceConfig; + this.interceptors = { + request: new InterceptorManager(), + response: new InterceptorManager() + }; +} + +/** + * Dispatch a request + * + * @param {Object} config The config specific for this request (merged with this.defaults) + */ +Axios.prototype.request = function request(config) { + /*eslint no-param-reassign:0*/ + // Allow for axios('example/url'[, config]) a la fetch API + if (typeof config === 'string') { + config = arguments[1] || {}; + config.url = arguments[0]; + } else { + config = config || {}; + } + + config = mergeConfig(this.defaults, config); + + // Set config.method + if (config.method) { + config.method = config.method.toLowerCase(); + } else if (this.defaults.method) { + config.method = this.defaults.method.toLowerCase(); + } else { + config.method = 'get'; + } + + // Hook up interceptors middleware + var chain = [dispatchRequest, undefined]; + var promise = Promise.resolve(config); + + this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) { + chain.unshift(interceptor.fulfilled, interceptor.rejected); + }); + + this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) { + chain.push(interceptor.fulfilled, interceptor.rejected); + }); + + while (chain.length) { + promise = promise.then(chain.shift(), chain.shift()); + } + + return promise; +}; + +Axios.prototype.getUri = function getUri(config) { + config = mergeConfig(this.defaults, config); + return buildURL(config.url, config.params, config.paramsSerializer).replace(/^\?/, ''); +}; + +// Provide aliases for supported request methods +utils.forEach(['delete', 'get', 'head', 'options'], function forEachMethodNoData(method) { + /*eslint func-names:0*/ + Axios.prototype[method] = function(url, config) { + return this.request(mergeConfig(config || {}, { + method: method, + url: url, + data: (config || {}).data + })); + }; +}); + +utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + /*eslint func-names:0*/ + Axios.prototype[method] = function(url, data, config) { + return this.request(mergeConfig(config || {}, { + method: method, + url: url, + data: data + })); + }; +}); + +module.exports = Axios; + +},{"../helpers/buildURL":23,"./../utils":32,"./InterceptorManager":13,"./dispatchRequest":16,"./mergeConfig":18}],13:[function(require,module,exports){ +'use strict'; + +var utils = require('./../utils'); + +function InterceptorManager() { + this.handlers = []; +} + +/** + * Add a new interceptor to the stack + * + * @param {Function} fulfilled The function to handle `then` for a `Promise` + * @param {Function} rejected The function to handle `reject` for a `Promise` + * + * @return {Number} An ID used to remove interceptor later + */ +InterceptorManager.prototype.use = function use(fulfilled, rejected) { + this.handlers.push({ + fulfilled: fulfilled, + rejected: rejected + }); + return this.handlers.length - 1; +}; + +/** + * Remove an interceptor from the stack + * + * @param {Number} id The ID that was returned by `use` + */ +InterceptorManager.prototype.eject = function eject(id) { + if (this.handlers[id]) { + this.handlers[id] = null; + } +}; + +/** + * Iterate over all the registered interceptors + * + * This method is particularly useful for skipping over any + * interceptors that may have become `null` calling `eject`. + * + * @param {Function} fn The function to call for each interceptor + */ +InterceptorManager.prototype.forEach = function forEach(fn) { + utils.forEach(this.handlers, function forEachHandler(h) { + if (h !== null) { + fn(h); + } + }); +}; + +module.exports = InterceptorManager; + +},{"./../utils":32}],14:[function(require,module,exports){ +'use strict'; + +var isAbsoluteURL = require('../helpers/isAbsoluteURL'); +var combineURLs = require('../helpers/combineURLs'); + +/** + * Creates a new URL by combining the baseURL with the requestedURL, + * only when the requestedURL is not already an absolute URL. + * If the requestURL is absolute, this function returns the requestedURL untouched. + * + * @param {string} baseURL The base URL + * @param {string} requestedURL Absolute or relative URL to combine + * @returns {string} The combined full path + */ +module.exports = function buildFullPath(baseURL, requestedURL) { + if (baseURL && !isAbsoluteURL(requestedURL)) { + return combineURLs(baseURL, requestedURL); + } + return requestedURL; +}; + +},{"../helpers/combineURLs":24,"../helpers/isAbsoluteURL":26}],15:[function(require,module,exports){ +'use strict'; + +var enhanceError = require('./enhanceError'); + +/** + * Create an Error with the specified message, config, error code, request and response. + * + * @param {string} message The error message. + * @param {Object} config The config. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * @returns {Error} The created error. + */ +module.exports = function createError(message, config, code, request, response) { + var error = new Error(message); + return enhanceError(error, config, code, request, response); +}; + +},{"./enhanceError":17}],16:[function(require,module,exports){ +'use strict'; + +var utils = require('./../utils'); +var transformData = require('./transformData'); +var isCancel = require('../cancel/isCancel'); +var defaults = require('../defaults'); + +/** + * Throws a `Cancel` if cancellation has been requested. + */ +function throwIfCancellationRequested(config) { + if (config.cancelToken) { + config.cancelToken.throwIfRequested(); + } +} + +/** + * Dispatch a request to the server using the configured adapter. + * + * @param {object} config The config that is to be used for the request + * @returns {Promise} The Promise to be fulfilled + */ +module.exports = function dispatchRequest(config) { + throwIfCancellationRequested(config); + + // Ensure headers exist + config.headers = config.headers || {}; + + // Transform request data + config.data = transformData( + config.data, + config.headers, + config.transformRequest + ); + + // Flatten headers + config.headers = utils.merge( + config.headers.common || {}, + config.headers[config.method] || {}, + config.headers + ); + + utils.forEach( + ['delete', 'get', 'head', 'post', 'put', 'patch', 'common'], + function cleanHeaderConfig(method) { + delete config.headers[method]; + } + ); + + var adapter = config.adapter || defaults.adapter; + + return adapter(config).then(function onAdapterResolution(response) { + throwIfCancellationRequested(config); + + // Transform response data + response.data = transformData( + response.data, + response.headers, + config.transformResponse + ); + + return response; + }, function onAdapterRejection(reason) { + if (!isCancel(reason)) { + throwIfCancellationRequested(config); + + // Transform response data + if (reason && reason.response) { + reason.response.data = transformData( + reason.response.data, + reason.response.headers, + config.transformResponse + ); + } + } + + return Promise.reject(reason); + }); +}; + +},{"../cancel/isCancel":11,"../defaults":21,"./../utils":32,"./transformData":20}],17:[function(require,module,exports){ +'use strict'; + +/** + * Update an Error with the specified config, error code, and response. + * + * @param {Error} error The error to update. + * @param {Object} config The config. + * @param {string} [code] The error code (for example, 'ECONNABORTED'). + * @param {Object} [request] The request. + * @param {Object} [response] The response. + * @returns {Error} The error. + */ +module.exports = function enhanceError(error, config, code, request, response) { + error.config = config; + if (code) { + error.code = code; + } + + error.request = request; + error.response = response; + error.isAxiosError = true; + + error.toJSON = function toJSON() { + return { + // Standard + message: this.message, + name: this.name, + // Microsoft + description: this.description, + number: this.number, + // Mozilla + fileName: this.fileName, + lineNumber: this.lineNumber, + columnNumber: this.columnNumber, + stack: this.stack, + // Axios + config: this.config, + code: this.code + }; + }; + return error; +}; + +},{}],18:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); + +/** + * Config-specific merge-function which creates a new config-object + * by merging two configuration objects together. + * + * @param {Object} config1 + * @param {Object} config2 + * @returns {Object} New object resulting from merging config2 to config1 + */ +module.exports = function mergeConfig(config1, config2) { + // eslint-disable-next-line no-param-reassign + config2 = config2 || {}; + var config = {}; + + var valueFromConfig2Keys = ['url', 'method', 'data']; + var mergeDeepPropertiesKeys = ['headers', 'auth', 'proxy', 'params']; + var defaultToConfig2Keys = [ + 'baseURL', 'transformRequest', 'transformResponse', 'paramsSerializer', + 'timeout', 'timeoutMessage', 'withCredentials', 'adapter', 'responseType', 'xsrfCookieName', + 'xsrfHeaderName', 'onUploadProgress', 'onDownloadProgress', 'decompress', + 'maxContentLength', 'maxBodyLength', 'maxRedirects', 'transport', 'httpAgent', + 'httpsAgent', 'cancelToken', 'socketPath', 'responseEncoding' + ]; + var directMergeKeys = ['validateStatus']; + + function getMergedValue(target, source) { + if (utils.isPlainObject(target) && utils.isPlainObject(source)) { + return utils.merge(target, source); + } else if (utils.isPlainObject(source)) { + return utils.merge({}, source); + } else if (utils.isArray(source)) { + return source.slice(); + } + return source; + } + + function mergeDeepProperties(prop) { + if (!utils.isUndefined(config2[prop])) { + config[prop] = getMergedValue(config1[prop], config2[prop]); + } else if (!utils.isUndefined(config1[prop])) { + config[prop] = getMergedValue(undefined, config1[prop]); + } + } + + utils.forEach(valueFromConfig2Keys, function valueFromConfig2(prop) { + if (!utils.isUndefined(config2[prop])) { + config[prop] = getMergedValue(undefined, config2[prop]); + } + }); + + utils.forEach(mergeDeepPropertiesKeys, mergeDeepProperties); + + utils.forEach(defaultToConfig2Keys, function defaultToConfig2(prop) { + if (!utils.isUndefined(config2[prop])) { + config[prop] = getMergedValue(undefined, config2[prop]); + } else if (!utils.isUndefined(config1[prop])) { + config[prop] = getMergedValue(undefined, config1[prop]); + } + }); + + utils.forEach(directMergeKeys, function merge(prop) { + if (prop in config2) { + config[prop] = getMergedValue(config1[prop], config2[prop]); + } else if (prop in config1) { + config[prop] = getMergedValue(undefined, config1[prop]); + } + }); + + var axiosKeys = valueFromConfig2Keys + .concat(mergeDeepPropertiesKeys) + .concat(defaultToConfig2Keys) + .concat(directMergeKeys); + + var otherKeys = Object + .keys(config1) + .concat(Object.keys(config2)) + .filter(function filterAxiosKeys(key) { + return axiosKeys.indexOf(key) === -1; + }); + + utils.forEach(otherKeys, mergeDeepProperties); + + return config; +}; + +},{"../utils":32}],19:[function(require,module,exports){ +'use strict'; + +var createError = require('./createError'); + +/** + * Resolve or reject a Promise based on response status. + * + * @param {Function} resolve A function that resolves the promise. + * @param {Function} reject A function that rejects the promise. + * @param {object} response The response. + */ +module.exports = function settle(resolve, reject, response) { + var validateStatus = response.config.validateStatus; + if (!response.status || !validateStatus || validateStatus(response.status)) { + resolve(response); + } else { + reject(createError( + 'Request failed with status code ' + response.status, + response.config, + null, + response.request, + response + )); + } +}; + +},{"./createError":15}],20:[function(require,module,exports){ +'use strict'; + +var utils = require('./../utils'); + +/** + * Transform the data for a request or a response + * + * @param {Object|String} data The data to be transformed + * @param {Array} headers The headers for the request or response + * @param {Array|Function} fns A single function or Array of functions + * @returns {*} The resulting transformed data + */ +module.exports = function transformData(data, headers, fns) { + /*eslint no-param-reassign:0*/ + utils.forEach(fns, function transform(fn) { + data = fn(data, headers); + }); + + return data; +}; + +},{"./../utils":32}],21:[function(require,module,exports){ +(function (process){(function (){ +'use strict'; + +var utils = require('./utils'); +var normalizeHeaderName = require('./helpers/normalizeHeaderName'); + +var DEFAULT_CONTENT_TYPE = { + 'Content-Type': 'application/x-www-form-urlencoded' +}; + +function setContentTypeIfUnset(headers, value) { + if (!utils.isUndefined(headers) && utils.isUndefined(headers['Content-Type'])) { + headers['Content-Type'] = value; + } +} + +function getDefaultAdapter() { + var adapter; + if (typeof XMLHttpRequest !== 'undefined') { + // For browsers use XHR adapter + adapter = require('./adapters/xhr'); + } else if (typeof process !== 'undefined' && Object.prototype.toString.call(process) === '[object process]') { + // For node use HTTP adapter + adapter = require('./adapters/http'); + } + return adapter; +} + +var defaults = { + adapter: getDefaultAdapter(), + + transformRequest: [function transformRequest(data, headers) { + normalizeHeaderName(headers, 'Accept'); + normalizeHeaderName(headers, 'Content-Type'); + if (utils.isFormData(data) || + utils.isArrayBuffer(data) || + utils.isBuffer(data) || + utils.isStream(data) || + utils.isFile(data) || + utils.isBlob(data) + ) { + return data; + } + if (utils.isArrayBufferView(data)) { + return data.buffer; + } + if (utils.isURLSearchParams(data)) { + setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); + return data.toString(); + } + if (utils.isObject(data)) { + setContentTypeIfUnset(headers, 'application/json;charset=utf-8'); + return JSON.stringify(data); + } + return data; + }], + + transformResponse: [function transformResponse(data) { + /*eslint no-param-reassign:0*/ + if (typeof data === 'string') { + try { + data = JSON.parse(data); + } catch (e) { /* Ignore */ } + } + return data; + }], + + /** + * A timeout in milliseconds to abort a request. If set to 0 (default) a + * timeout is not created. + */ + timeout: 0, + + xsrfCookieName: 'XSRF-TOKEN', + xsrfHeaderName: 'X-XSRF-TOKEN', + + maxContentLength: -1, + maxBodyLength: -1, + + validateStatus: function validateStatus(status) { + return status >= 200 && status < 300; + } +}; + +defaults.headers = { + common: { + 'Accept': 'application/json, text/plain, */*' + } +}; + +utils.forEach(['delete', 'get', 'head'], function forEachMethodNoData(method) { + defaults.headers[method] = {}; +}); + +utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) { + defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE); +}); + +module.exports = defaults; + +}).call(this)}).call(this,require('_process')) +},{"./adapters/http":7,"./adapters/xhr":7,"./helpers/normalizeHeaderName":29,"./utils":32,"_process":76}],22:[function(require,module,exports){ +'use strict'; + +module.exports = function bind(fn, thisArg) { + return function wrap() { + var args = new Array(arguments.length); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i]; + } + return fn.apply(thisArg, args); + }; +}; + +},{}],23:[function(require,module,exports){ +'use strict'; + +var utils = require('./../utils'); + +function encode(val) { + return encodeURIComponent(val). + replace(/%3A/gi, ':'). + replace(/%24/g, '$'). + replace(/%2C/gi, ','). + replace(/%20/g, '+'). + replace(/%5B/gi, '['). + replace(/%5D/gi, ']'); +} + +/** + * Build a URL by appending params to the end + * + * @param {string} url The base of the url (e.g., http://www.google.com) + * @param {object} [params] The params to be appended + * @returns {string} The formatted url + */ +module.exports = function buildURL(url, params, paramsSerializer) { + /*eslint no-param-reassign:0*/ + if (!params) { + return url; + } + + var serializedParams; + if (paramsSerializer) { + serializedParams = paramsSerializer(params); + } else if (utils.isURLSearchParams(params)) { + serializedParams = params.toString(); + } else { + var parts = []; + + utils.forEach(params, function serialize(val, key) { + if (val === null || typeof val === 'undefined') { + return; + } + + if (utils.isArray(val)) { + key = key + '[]'; + } else { + val = [val]; + } + + utils.forEach(val, function parseValue(v) { + if (utils.isDate(v)) { + v = v.toISOString(); + } else if (utils.isObject(v)) { + v = JSON.stringify(v); + } + parts.push(encode(key) + '=' + encode(v)); + }); + }); + + serializedParams = parts.join('&'); + } + + if (serializedParams) { + var hashmarkIndex = url.indexOf('#'); + if (hashmarkIndex !== -1) { + url = url.slice(0, hashmarkIndex); + } + + url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams; + } + + return url; +}; + +},{"./../utils":32}],24:[function(require,module,exports){ +'use strict'; + +/** + * Creates a new URL by combining the specified URLs + * + * @param {string} baseURL The base URL + * @param {string} relativeURL The relative URL + * @returns {string} The combined URL + */ +module.exports = function combineURLs(baseURL, relativeURL) { + return relativeURL + ? baseURL.replace(/\/+$/, '') + '/' + relativeURL.replace(/^\/+/, '') + : baseURL; +}; + +},{}],25:[function(require,module,exports){ +'use strict'; + +var utils = require('./../utils'); + +module.exports = ( + utils.isStandardBrowserEnv() ? + + // Standard browser envs support document.cookie + (function standardBrowserEnv() { + return { + write: function write(name, value, expires, path, domain, secure) { + var cookie = []; + cookie.push(name + '=' + encodeURIComponent(value)); + + if (utils.isNumber(expires)) { + cookie.push('expires=' + new Date(expires).toGMTString()); + } + + if (utils.isString(path)) { + cookie.push('path=' + path); + } + + if (utils.isString(domain)) { + cookie.push('domain=' + domain); + } + + if (secure === true) { + cookie.push('secure'); + } + + document.cookie = cookie.join('; '); + }, + + read: function read(name) { + var match = document.cookie.match(new RegExp('(^|;\\s*)(' + name + ')=([^;]*)')); + return (match ? decodeURIComponent(match[3]) : null); + }, + + remove: function remove(name) { + this.write(name, '', Date.now() - 86400000); + } + }; + })() : + + // Non standard browser env (web workers, react-native) lack needed support. + (function nonStandardBrowserEnv() { + return { + write: function write() {}, + read: function read() { return null; }, + remove: function remove() {} + }; + })() +); + +},{"./../utils":32}],26:[function(require,module,exports){ +'use strict'; + +/** + * Determines whether the specified URL is absolute + * + * @param {string} url The URL to test + * @returns {boolean} True if the specified URL is absolute, otherwise false + */ +module.exports = function isAbsoluteURL(url) { + // A URL is considered absolute if it begins with "://" or "//" (protocol-relative URL). + // RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed + // by any combination of letters, digits, plus, period, or hyphen. + return /^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(url); +}; + +},{}],27:[function(require,module,exports){ +'use strict'; + +/** + * Determines whether the payload is an error thrown by Axios + * + * @param {*} payload The value to test + * @returns {boolean} True if the payload is an error thrown by Axios, otherwise false + */ +module.exports = function isAxiosError(payload) { + return (typeof payload === 'object') && (payload.isAxiosError === true); +}; + +},{}],28:[function(require,module,exports){ +'use strict'; + +var utils = require('./../utils'); + +module.exports = ( + utils.isStandardBrowserEnv() ? + + // Standard browser envs have full support of the APIs needed to test + // whether the request URL is of the same origin as current location. + (function standardBrowserEnv() { + var msie = /(msie|trident)/i.test(navigator.userAgent); + var urlParsingNode = document.createElement('a'); + var originURL; + + /** + * Parse a URL to discover it's components + * + * @param {String} url The URL to be parsed + * @returns {Object} + */ + function resolveURL(url) { + var href = url; + + if (msie) { + // IE needs attribute set twice to normalize properties + urlParsingNode.setAttribute('href', href); + href = urlParsingNode.href; + } + + urlParsingNode.setAttribute('href', href); + + // urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils + return { + href: urlParsingNode.href, + protocol: urlParsingNode.protocol ? urlParsingNode.protocol.replace(/:$/, '') : '', + host: urlParsingNode.host, + search: urlParsingNode.search ? urlParsingNode.search.replace(/^\?/, '') : '', + hash: urlParsingNode.hash ? urlParsingNode.hash.replace(/^#/, '') : '', + hostname: urlParsingNode.hostname, + port: urlParsingNode.port, + pathname: (urlParsingNode.pathname.charAt(0) === '/') ? + urlParsingNode.pathname : + '/' + urlParsingNode.pathname + }; + } + + originURL = resolveURL(window.location.href); + + /** + * Determine if a URL shares the same origin as the current location + * + * @param {String} requestURL The URL to test + * @returns {boolean} True if URL shares the same origin, otherwise false + */ + return function isURLSameOrigin(requestURL) { + var parsed = (utils.isString(requestURL)) ? resolveURL(requestURL) : requestURL; + return (parsed.protocol === originURL.protocol && + parsed.host === originURL.host); + }; + })() : + + // Non standard browser envs (web workers, react-native) lack needed support. + (function nonStandardBrowserEnv() { + return function isURLSameOrigin() { + return true; + }; + })() +); + +},{"./../utils":32}],29:[function(require,module,exports){ +'use strict'; + +var utils = require('../utils'); + +module.exports = function normalizeHeaderName(headers, normalizedName) { + utils.forEach(headers, function processHeader(value, name) { + if (name !== normalizedName && name.toUpperCase() === normalizedName.toUpperCase()) { + headers[normalizedName] = value; + delete headers[name]; + } + }); +}; + +},{"../utils":32}],30:[function(require,module,exports){ +'use strict'; + +var utils = require('./../utils'); + +// Headers whose duplicates are ignored by node +// c.f. https://nodejs.org/api/http.html#http_message_headers +var ignoreDuplicateOf = [ + 'age', 'authorization', 'content-length', 'content-type', 'etag', + 'expires', 'from', 'host', 'if-modified-since', 'if-unmodified-since', + 'last-modified', 'location', 'max-forwards', 'proxy-authorization', + 'referer', 'retry-after', 'user-agent' +]; + +/** + * Parse headers into an object + * + * ``` + * Date: Wed, 27 Aug 2014 08:58:49 GMT + * Content-Type: application/json + * Connection: keep-alive + * Transfer-Encoding: chunked + * ``` + * + * @param {String} headers Headers needing to be parsed + * @returns {Object} Headers parsed into an object + */ +module.exports = function parseHeaders(headers) { + var parsed = {}; + var key; + var val; + var i; + + if (!headers) { return parsed; } + + utils.forEach(headers.split('\n'), function parser(line) { + i = line.indexOf(':'); + key = utils.trim(line.substr(0, i)).toLowerCase(); + val = utils.trim(line.substr(i + 1)); + + if (key) { + if (parsed[key] && ignoreDuplicateOf.indexOf(key) >= 0) { + return; + } + if (key === 'set-cookie') { + parsed[key] = (parsed[key] ? parsed[key] : []).concat([val]); + } else { + parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val; + } + } + }); + + return parsed; +}; + +},{"./../utils":32}],31:[function(require,module,exports){ +'use strict'; + +/** + * Syntactic sugar for invoking a function and expanding an array for arguments. + * + * Common use case would be to use `Function.prototype.apply`. + * + * ```js + * function f(x, y, z) {} + * var args = [1, 2, 3]; + * f.apply(null, args); + * ``` + * + * With `spread` this example can be re-written. + * + * ```js + * spread(function(x, y, z) {})([1, 2, 3]); + * ``` + * + * @param {Function} callback + * @returns {Function} + */ +module.exports = function spread(callback) { + return function wrap(arr) { + return callback.apply(null, arr); + }; +}; + +},{}],32:[function(require,module,exports){ +'use strict'; + +var bind = require('./helpers/bind'); + +/*global toString:true*/ + +// utils is a library of generic helper functions non-specific to axios + +var toString = Object.prototype.toString; + +/** + * Determine if a value is an Array + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Array, otherwise false + */ +function isArray(val) { + return toString.call(val) === '[object Array]'; +} + +/** + * Determine if a value is undefined + * + * @param {Object} val The value to test + * @returns {boolean} True if the value is undefined, otherwise false + */ +function isUndefined(val) { + return typeof val === 'undefined'; +} + +/** + * Determine if a value is a Buffer + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Buffer, otherwise false + */ +function isBuffer(val) { + return val !== null && !isUndefined(val) && val.constructor !== null && !isUndefined(val.constructor) + && typeof val.constructor.isBuffer === 'function' && val.constructor.isBuffer(val); +} + +/** + * Determine if a value is an ArrayBuffer + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an ArrayBuffer, otherwise false + */ +function isArrayBuffer(val) { + return toString.call(val) === '[object ArrayBuffer]'; +} + +/** + * Determine if a value is a FormData + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an FormData, otherwise false + */ +function isFormData(val) { + return (typeof FormData !== 'undefined') && (val instanceof FormData); +} + +/** + * Determine if a value is a view on an ArrayBuffer + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a view on an ArrayBuffer, otherwise false + */ +function isArrayBufferView(val) { + var result; + if ((typeof ArrayBuffer !== 'undefined') && (ArrayBuffer.isView)) { + result = ArrayBuffer.isView(val); + } else { + result = (val) && (val.buffer) && (val.buffer instanceof ArrayBuffer); + } + return result; +} + +/** + * Determine if a value is a String + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a String, otherwise false + */ +function isString(val) { + return typeof val === 'string'; +} + +/** + * Determine if a value is a Number + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Number, otherwise false + */ +function isNumber(val) { + return typeof val === 'number'; +} + +/** + * Determine if a value is an Object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is an Object, otherwise false + */ +function isObject(val) { + return val !== null && typeof val === 'object'; +} + +/** + * Determine if a value is a plain Object + * + * @param {Object} val The value to test + * @return {boolean} True if value is a plain Object, otherwise false + */ +function isPlainObject(val) { + if (toString.call(val) !== '[object Object]') { + return false; + } + + var prototype = Object.getPrototypeOf(val); + return prototype === null || prototype === Object.prototype; +} + +/** + * Determine if a value is a Date + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Date, otherwise false + */ +function isDate(val) { + return toString.call(val) === '[object Date]'; +} + +/** + * Determine if a value is a File + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a File, otherwise false + */ +function isFile(val) { + return toString.call(val) === '[object File]'; +} + +/** + * Determine if a value is a Blob + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Blob, otherwise false + */ +function isBlob(val) { + return toString.call(val) === '[object Blob]'; +} + +/** + * Determine if a value is a Function + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Function, otherwise false + */ +function isFunction(val) { + return toString.call(val) === '[object Function]'; +} + +/** + * Determine if a value is a Stream + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a Stream, otherwise false + */ +function isStream(val) { + return isObject(val) && isFunction(val.pipe); +} + +/** + * Determine if a value is a URLSearchParams object + * + * @param {Object} val The value to test + * @returns {boolean} True if value is a URLSearchParams object, otherwise false + */ +function isURLSearchParams(val) { + return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams; +} + +/** + * Trim excess whitespace off the beginning and end of a string + * + * @param {String} str The String to trim + * @returns {String} The String freed of excess whitespace + */ +function trim(str) { + return str.replace(/^\s*/, '').replace(/\s*$/, ''); +} + +/** + * Determine if we're running in a standard browser environment + * + * This allows axios to run in a web worker, and react-native. + * Both environments support XMLHttpRequest, but not fully standard globals. + * + * web workers: + * typeof window -> undefined + * typeof document -> undefined + * + * react-native: + * navigator.product -> 'ReactNative' + * nativescript + * navigator.product -> 'NativeScript' or 'NS' + */ +function isStandardBrowserEnv() { + if (typeof navigator !== 'undefined' && (navigator.product === 'ReactNative' || + navigator.product === 'NativeScript' || + navigator.product === 'NS')) { + return false; + } + return ( + typeof window !== 'undefined' && + typeof document !== 'undefined' + ); +} + +/** + * Iterate over an Array or an Object invoking a function for each item. + * + * If `obj` is an Array callback will be called passing + * the value, index, and complete array for each item. + * + * If 'obj' is an Object callback will be called passing + * the value, key, and complete object for each property. + * + * @param {Object|Array} obj The object to iterate + * @param {Function} fn The callback to invoke for each item + */ +function forEach(obj, fn) { + // Don't bother if no value provided + if (obj === null || typeof obj === 'undefined') { + return; + } + + // Force an array if not already something iterable + if (typeof obj !== 'object') { + /*eslint no-param-reassign:0*/ + obj = [obj]; + } + + if (isArray(obj)) { + // Iterate over array values + for (var i = 0, l = obj.length; i < l; i++) { + fn.call(null, obj[i], i, obj); + } + } else { + // Iterate over object keys + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + fn.call(null, obj[key], key, obj); + } + } + } +} + +/** + * Accepts varargs expecting each argument to be an object, then + * immutably merges the properties of each object and returns result. + * + * When multiple objects contain the same key the later object in + * the arguments list will take precedence. + * + * Example: + * + * ```js + * var result = merge({foo: 123}, {foo: 456}); + * console.log(result.foo); // outputs 456 + * ``` + * + * @param {Object} obj1 Object to merge + * @returns {Object} Result of all merge properties + */ +function merge(/* obj1, obj2, obj3, ... */) { + var result = {}; + function assignValue(val, key) { + if (isPlainObject(result[key]) && isPlainObject(val)) { + result[key] = merge(result[key], val); + } else if (isPlainObject(val)) { + result[key] = merge({}, val); + } else if (isArray(val)) { + result[key] = val.slice(); + } else { + result[key] = val; + } + } + + for (var i = 0, l = arguments.length; i < l; i++) { + forEach(arguments[i], assignValue); + } + return result; +} + +/** + * Extends object a by mutably adding to it the properties of object b. + * + * @param {Object} a The object to be extended + * @param {Object} b The object to copy properties from + * @param {Object} thisArg The object to bind function to + * @return {Object} The resulting value of object a + */ +function extend(a, b, thisArg) { + forEach(b, function assignValue(val, key) { + if (thisArg && typeof val === 'function') { + a[key] = bind(val, thisArg); + } else { + a[key] = val; + } + }); + return a; +} + +/** + * Remove byte order marker. This catches EF BB BF (the UTF-8 BOM) + * + * @param {string} content with BOM + * @return {string} content value without BOM + */ +function stripBOM(content) { + if (content.charCodeAt(0) === 0xFEFF) { + content = content.slice(1); + } + return content; +} + +module.exports = { + isArray: isArray, + isArrayBuffer: isArrayBuffer, + isBuffer: isBuffer, + isFormData: isFormData, + isArrayBufferView: isArrayBufferView, + isString: isString, + isNumber: isNumber, + isObject: isObject, + isPlainObject: isPlainObject, + isUndefined: isUndefined, + isDate: isDate, + isFile: isFile, + isBlob: isBlob, + isFunction: isFunction, + isStream: isStream, + isURLSearchParams: isURLSearchParams, + isStandardBrowserEnv: isStandardBrowserEnv, + forEach: forEach, + merge: merge, + extend: extend, + trim: trim, + stripBOM: stripBOM +}; + +},{"./helpers/bind":22}],33:[function(require,module,exports){ +module.exports = require('./lib/chai'); + +},{"./lib/chai":34}],34:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var used = []; + +/*! + * Chai version + */ + +exports.version = '4.2.0'; + +/*! + * Assertion Error + */ + +exports.AssertionError = require('assertion-error'); + +/*! + * Utils for plugins (not exported) + */ + +var util = require('./chai/utils'); + +/** + * # .use(function) + * + * Provides a way to extend the internals of Chai. + * + * @param {Function} + * @returns {this} for chaining + * @api public + */ + +exports.use = function (fn) { + if (!~used.indexOf(fn)) { + fn(exports, util); + used.push(fn); + } + + return exports; +}; + +/*! + * Utility Functions + */ + +exports.util = util; + +/*! + * Configuration + */ + +var config = require('./chai/config'); +exports.config = config; + +/*! + * Primary `Assertion` prototype + */ + +var assertion = require('./chai/assertion'); +exports.use(assertion); + +/*! + * Core Assertions + */ + +var core = require('./chai/core/assertions'); +exports.use(core); + +/*! + * Expect interface + */ + +var expect = require('./chai/interface/expect'); +exports.use(expect); + +/*! + * Should interface + */ + +var should = require('./chai/interface/should'); +exports.use(should); + +/*! + * Assert interface + */ + +var assert = require('./chai/interface/assert'); +exports.use(assert); + +},{"./chai/assertion":35,"./chai/config":36,"./chai/core/assertions":37,"./chai/interface/assert":38,"./chai/interface/expect":39,"./chai/interface/should":40,"./chai/utils":54,"assertion-error":5}],35:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +var config = require('./config'); + +module.exports = function (_chai, util) { + /*! + * Module dependencies. + */ + + var AssertionError = _chai.AssertionError + , flag = util.flag; + + /*! + * Module export. + */ + + _chai.Assertion = Assertion; + + /*! + * Assertion Constructor + * + * Creates object for chaining. + * + * `Assertion` objects contain metadata in the form of flags. Three flags can + * be assigned during instantiation by passing arguments to this constructor: + * + * - `object`: This flag contains the target of the assertion. For example, in + * the assertion `expect(numKittens).to.equal(7);`, the `object` flag will + * contain `numKittens` so that the `equal` assertion can reference it when + * needed. + * + * - `message`: This flag contains an optional custom error message to be + * prepended to the error message that's generated by the assertion when it + * fails. + * + * - `ssfi`: This flag stands for "start stack function indicator". It + * contains a function reference that serves as the starting point for + * removing frames from the stack trace of the error that's created by the + * assertion when it fails. The goal is to provide a cleaner stack trace to + * end users by removing Chai's internal functions. Note that it only works + * in environments that support `Error.captureStackTrace`, and only when + * `Chai.config.includeStack` hasn't been set to `false`. + * + * - `lockSsfi`: This flag controls whether or not the given `ssfi` flag + * should retain its current value, even as assertions are chained off of + * this object. This is usually set to `true` when creating a new assertion + * from within another assertion. It's also temporarily set to `true` before + * an overwritten assertion gets called by the overwriting assertion. + * + * @param {Mixed} obj target of the assertion + * @param {String} msg (optional) custom error message + * @param {Function} ssfi (optional) starting point for removing stack frames + * @param {Boolean} lockSsfi (optional) whether or not the ssfi flag is locked + * @api private + */ + + function Assertion (obj, msg, ssfi, lockSsfi) { + flag(this, 'ssfi', ssfi || Assertion); + flag(this, 'lockSsfi', lockSsfi); + flag(this, 'object', obj); + flag(this, 'message', msg); + + return util.proxify(this); + } + + Object.defineProperty(Assertion, 'includeStack', { + get: function() { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + return config.includeStack; + }, + set: function(value) { + console.warn('Assertion.includeStack is deprecated, use chai.config.includeStack instead.'); + config.includeStack = value; + } + }); + + Object.defineProperty(Assertion, 'showDiff', { + get: function() { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + return config.showDiff; + }, + set: function(value) { + console.warn('Assertion.showDiff is deprecated, use chai.config.showDiff instead.'); + config.showDiff = value; + } + }); + + Assertion.addProperty = function (name, fn) { + util.addProperty(this.prototype, name, fn); + }; + + Assertion.addMethod = function (name, fn) { + util.addMethod(this.prototype, name, fn); + }; + + Assertion.addChainableMethod = function (name, fn, chainingBehavior) { + util.addChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + Assertion.overwriteProperty = function (name, fn) { + util.overwriteProperty(this.prototype, name, fn); + }; + + Assertion.overwriteMethod = function (name, fn) { + util.overwriteMethod(this.prototype, name, fn); + }; + + Assertion.overwriteChainableMethod = function (name, fn, chainingBehavior) { + util.overwriteChainableMethod(this.prototype, name, fn, chainingBehavior); + }; + + /** + * ### .assert(expression, message, negateMessage, expected, actual, showDiff) + * + * Executes an expression and check expectations. Throws AssertionError for reporting if test doesn't pass. + * + * @name assert + * @param {Philosophical} expression to be tested + * @param {String|Function} message or function that returns message to display if expression fails + * @param {String|Function} negatedMessage or function that returns negatedMessage to display if negated expression fails + * @param {Mixed} expected value (remember to check for negation) + * @param {Mixed} actual (optional) will default to `this.obj` + * @param {Boolean} showDiff (optional) when set to `true`, assert will display a diff in addition to the message if expression fails + * @api private + */ + + Assertion.prototype.assert = function (expr, msg, negateMsg, expected, _actual, showDiff) { + var ok = util.test(this, arguments); + if (false !== showDiff) showDiff = true; + if (undefined === expected && undefined === _actual) showDiff = false; + if (true !== config.showDiff) showDiff = false; + + if (!ok) { + msg = util.getMessage(this, arguments); + var actual = util.getActual(this, arguments); + throw new AssertionError(msg, { + actual: actual + , expected: expected + , showDiff: showDiff + }, (config.includeStack) ? this.assert : flag(this, 'ssfi')); + } + }; + + /*! + * ### ._obj + * + * Quick reference to stored `actual` value for plugin developers. + * + * @api private + */ + + Object.defineProperty(Assertion.prototype, '_obj', + { get: function () { + return flag(this, 'object'); + } + , set: function (val) { + flag(this, 'object', val); + } + }); +}; + +},{"./config":36}],36:[function(require,module,exports){ +module.exports = { + + /** + * ### config.includeStack + * + * User configurable property, influences whether stack trace + * is included in Assertion error message. Default of false + * suppresses stack trace in the error message. + * + * chai.config.includeStack = true; // enable stack on error + * + * @param {Boolean} + * @api public + */ + + includeStack: false, + + /** + * ### config.showDiff + * + * User configurable property, influences whether or not + * the `showDiff` flag should be included in the thrown + * AssertionErrors. `false` will always be `false`; `true` + * will be true when the assertion has requested a diff + * be shown. + * + * @param {Boolean} + * @api public + */ + + showDiff: true, + + /** + * ### config.truncateThreshold + * + * User configurable property, sets length threshold for actual and + * expected values in assertion errors. If this threshold is exceeded, for + * example for large data structures, the value is replaced with something + * like `[ Array(3) ]` or `{ Object (prop1, prop2) }`. + * + * Set it to zero if you want to disable truncating altogether. + * + * This is especially userful when doing assertions on arrays: having this + * set to a reasonable large value makes the failure messages readily + * inspectable. + * + * chai.config.truncateThreshold = 0; // disable truncating + * + * @param {Number} + * @api public + */ + + truncateThreshold: 40, + + /** + * ### config.useProxy + * + * User configurable property, defines if chai will use a Proxy to throw + * an error when a non-existent property is read, which protects users + * from typos when using property-based assertions. + * + * Set it to false if you want to disable this feature. + * + * chai.config.useProxy = false; // disable use of Proxy + * + * This feature is automatically disabled regardless of this config value + * in environments that don't support proxies. + * + * @param {Boolean} + * @api public + */ + + useProxy: true, + + /** + * ### config.proxyExcludedKeys + * + * User configurable property, defines which properties should be ignored + * instead of throwing an error if they do not exist on the assertion. + * This is only applied if the environment Chai is running in supports proxies and + * if the `useProxy` configuration setting is enabled. + * By default, `then` and `inspect` will not throw an error if they do not exist on the + * assertion object because the `.inspect` property is read by `util.inspect` (for example, when + * using `console.log` on the assertion object) and `.then` is necessary for promise type-checking. + * + * // By default these keys will not throw an error if they do not exist on the assertion object + * chai.config.proxyExcludedKeys = ['then', 'inspect']; + * + * @param {Array} + * @api public + */ + + proxyExcludedKeys: ['then', 'catch', 'inspect', 'toJSON'] +}; + +},{}],37:[function(require,module,exports){ +/*! + * chai + * http://chaijs.com + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, _) { + var Assertion = chai.Assertion + , AssertionError = chai.AssertionError + , flag = _.flag; + + /** + * ### Language Chains + * + * The following are provided as chainable getters to improve the readability + * of your assertions. + * + * **Chains** + * + * - to + * - be + * - been + * - is + * - that + * - which + * - and + * - has + * - have + * - with + * - at + * - of + * - same + * - but + * - does + * - still + * + * @name language chains + * @namespace BDD + * @api public + */ + + [ 'to', 'be', 'been', 'is' + , 'and', 'has', 'have', 'with' + , 'that', 'which', 'at', 'of' + , 'same', 'but', 'does', 'still' ].forEach(function (chain) { + Assertion.addProperty(chain); + }); + + /** + * ### .not + * + * Negates all assertions that follow in the chain. + * + * expect(function () {}).to.not.throw(); + * expect({a: 1}).to.not.have.property('b'); + * expect([1, 2]).to.be.an('array').that.does.not.include(3); + * + * Just because you can negate any assertion with `.not` doesn't mean you + * should. With great power comes great responsibility. It's often best to + * assert that the one expected output was produced, rather than asserting + * that one of countless unexpected outputs wasn't produced. See individual + * assertions for specific guidance. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.equal(1); // Not recommended + * + * @name not + * @namespace BDD + * @api public + */ + + Assertion.addProperty('not', function () { + flag(this, 'negate', true); + }); + + /** + * ### .deep + * + * Causes all `.equal`, `.include`, `.members`, `.keys`, and `.property` + * assertions that follow in the chain to use deep equality instead of strict + * (`===`) equality. See the `deep-eql` project page for info on the deep + * equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.keys([{a: 1}]); + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * @name deep + * @namespace BDD + * @api public + */ + + Assertion.addProperty('deep', function () { + flag(this, 'deep', true); + }); + + /** + * ### .nested + * + * Enables dot- and bracket-notation in all `.property` and `.include` + * assertions that follow in the chain. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * expect({'.a': {'[b]': 'x'}}).to.nested.include({'\\.a.\\[b\\]': 'x'}); + * + * `.nested` cannot be combined with `.own`. + * + * @name nested + * @namespace BDD + * @api public + */ + + Assertion.addProperty('nested', function () { + flag(this, 'nested', true); + }); + + /** + * ### .own + * + * Causes all `.property` and `.include` assertions that follow in the chain + * to ignore inherited properties. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.property('b'); + * expect({a: 1}).to.not.have.own.property('b'); + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * `.own` cannot be combined with `.nested`. + * + * @name own + * @namespace BDD + * @api public + */ + + Assertion.addProperty('own', function () { + flag(this, 'own', true); + }); + + /** + * ### .ordered + * + * Causes all `.members` assertions that follow in the chain to require that + * members be in the same order. + * + * expect([1, 2]).to.have.ordered.members([1, 2]) + * .but.not.have.ordered.members([2, 1]); + * + * When `.include` and `.ordered` are combined, the ordering begins at the + * start of both arrays. + * + * expect([1, 2, 3]).to.include.ordered.members([1, 2]) + * .but.not.include.ordered.members([2, 3]); + * + * @name ordered + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ordered', function () { + flag(this, 'ordered', true); + }); + + /** + * ### .any + * + * Causes all `.keys` assertions that follow in the chain to only require that + * the target have at least one of the given keys. This is the opposite of + * `.all`, which requires that the target have all of the given keys. + * + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name any + * @namespace BDD + * @api public + */ + + Assertion.addProperty('any', function () { + flag(this, 'any', true); + flag(this, 'all', false); + }); + + /** + * ### .all + * + * Causes all `.keys` assertions that follow in the chain to require that the + * target have all of the given keys. This is the opposite of `.any`, which + * only requires that the target have at least one of the given keys. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` are + * added earlier in the chain. However, it's often best to add `.all` anyway + * because it improves readability. + * + * See the `.keys` doc for guidance on when to use `.any` or `.all`. + * + * @name all + * @namespace BDD + * @api public + */ + + Assertion.addProperty('all', function () { + flag(this, 'all', true); + flag(this, 'any', false); + }); + + /** + * ### .a(type[, msg]) + * + * Asserts that the target's type is equal to the given string `type`. Types + * are case insensitive. See the `type-detect` project page for info on the + * type detection algorithm: https://github.com/chaijs/type-detect. + * + * expect('foo').to.be.a('string'); + * expect({a: 1}).to.be.an('object'); + * expect(null).to.be.a('null'); + * expect(undefined).to.be.an('undefined'); + * expect(new Error).to.be.an('error'); + * expect(Promise.resolve()).to.be.a('promise'); + * expect(new Float32Array).to.be.a('float32array'); + * expect(Symbol()).to.be.a('symbol'); + * + * `.a` supports objects that have a custom type set via `Symbol.toStringTag`. + * + * var myObj = { + * [Symbol.toStringTag]: 'myCustomType' + * }; + * + * expect(myObj).to.be.a('myCustomType').but.not.an('object'); + * + * It's often best to use `.a` to check a target's type before making more + * assertions on the same target. That way, you avoid unexpected behavior from + * any assertion that does different things based on the target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.a`. However, it's often best to + * assert that the target is the expected type, rather than asserting that it + * isn't one of many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.an('array'); // Not recommended + * + * `.a` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * expect(1).to.be.a('string', 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.a('string'); + * + * `.a` can also be used as a language chain to improve the readability of + * your assertions. + * + * expect({b: 2}).to.have.a.property('b'); + * + * The alias `.an` can be used interchangeably with `.a`. + * + * @name a + * @alias an + * @param {String} type + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function an (type, msg) { + if (msg) flag(this, 'message', msg); + type = type.toLowerCase(); + var obj = flag(this, 'object') + , article = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(type.charAt(0)) ? 'an ' : 'a '; + + this.assert( + type === _.type(obj).toLowerCase() + , 'expected #{this} to be ' + article + type + , 'expected #{this} not to be ' + article + type + ); + } + + Assertion.addChainableMethod('an', an); + Assertion.addChainableMethod('a', an); + + /** + * ### .include(val[, msg]) + * + * When the target is a string, `.include` asserts that the given string `val` + * is a substring of the target. + * + * expect('foobar').to.include('foo'); + * + * When the target is an array, `.include` asserts that the given `val` is a + * member of the target. + * + * expect([1, 2, 3]).to.include(2); + * + * When the target is an object, `.include` asserts that the given object + * `val`'s properties are a subset of the target's properties. + * + * expect({a: 1, b: 2, c: 3}).to.include({a: 1, b: 2}); + * + * When the target is a Set or WeakSet, `.include` asserts that the given `val` is a + * member of the target. SameValueZero equality algorithm is used. + * + * expect(new Set([1, 2])).to.include(2); + * + * When the target is a Map, `.include` asserts that the given `val` is one of + * the values of the target. SameValueZero equality algorithm is used. + * + * expect(new Map([['a', 1], ['b', 2]])).to.include(2); + * + * Because `.include` does different things based on the target's type, it's + * important to check the target's type before using `.include`. See the `.a` + * doc for info on testing a target's type. + * + * expect([1, 2, 3]).to.be.an('array').that.includes(2); + * + * By default, strict (`===`) equality is used to compare array members and + * object properties. Add `.deep` earlier in the chain to use deep equality + * instead (WeakSet targets are not supported). See the `deep-eql` project + * page for info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) includes `{a: 1}` + * expect([{a: 1}]).to.deep.include({a: 1}); + * expect([{a: 1}]).to.not.include({a: 1}); + * + * // Target object deeply (but not strictly) includes `x: {a: 1}` + * expect({x: {a: 1}}).to.deep.include({x: {a: 1}}); + * expect({x: {a: 1}}).to.not.include({x: {a: 1}}); + * + * By default, all of the target's properties are searched when working with + * objects. This includes properties that are inherited and/or non-enumerable. + * Add `.own` earlier in the chain to exclude the target's inherited + * properties from the search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.own.include({a: 1}); + * expect({a: 1}).to.include({b: 2}).but.not.own.include({b: 2}); + * + * Note that a target object is always only searched for `val`'s own + * enumerable properties. + * + * `.deep` and `.own` can be combined. + * + * expect({a: {b: 2}}).to.deep.own.include({a: {b: 2}}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.nested.include({'a.b[1]': 'y'}); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 2}}).to.nested.include({'\\.a.\\[b\\]': 2}); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}).to.deep.nested.include({'a.b[0]': {c: 3}}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.include`. + * + * expect('foobar').to.not.include('taco'); + * expect([1, 2, 3]).to.not.include(4); + * + * However, it's dangerous to negate `.include` when the target is an object. + * The problem is that it creates uncertain expectations by asserting that the + * target object doesn't have all of `val`'s key/value pairs but may or may + * not have some of them. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target object isn't even expected to have `val`'s keys, it's + * often best to assert exactly that. + * + * expect({c: 3}).to.not.have.any.keys('a', 'b'); // Recommended + * expect({c: 3}).to.not.include({a: 1, b: 2}); // Not recommended + * + * When the target object is expected to have `val`'s keys, it's often best to + * assert that each of the properties has its expected value, rather than + * asserting that each property doesn't have one of many unexpected values. + * + * expect({a: 3, b: 4}).to.include({a: 3, b: 4}); // Recommended + * expect({a: 3, b: 4}).to.not.include({a: 1, b: 2}); // Not recommended + * + * `.include` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.include(4, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.include(4); + * + * `.include` can also be used as a language chain, causing all `.members` and + * `.keys` assertions that follow in the chain to require the target to be a + * superset of the expected set, rather than an identical set. Note that + * `.members` ignores duplicates in the subset when `.include` is added. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * Note that adding `.any` earlier in the chain causes the `.keys` assertion + * to ignore `.include`. + * + * // Both assertions are identical + * expect({a: 1}).to.include.any.keys('a', 'b'); + * expect({a: 1}).to.have.any.keys('a', 'b'); + * + * The aliases `.includes`, `.contain`, and `.contains` can be used + * interchangeably with `.include`. + * + * @name include + * @alias contain + * @alias includes + * @alias contains + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function SameValueZero(a, b) { + return (_.isNaN(a) && _.isNaN(b)) || a === b; + } + + function includeChainingBehavior () { + flag(this, 'contains', true); + } + + function include (val, msg) { + if (msg) flag(this, 'message', msg); + + var obj = flag(this, 'object') + , objType = _.type(obj).toLowerCase() + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , descriptor = isDeep ? 'deep ' : ''; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + var included = false; + + switch (objType) { + case 'string': + included = obj.indexOf(val) !== -1; + break; + + case 'weakset': + if (isDeep) { + throw new AssertionError( + flagMsg + 'unable to use .deep.include with WeakSet', + undefined, + ssfi + ); + } + + included = obj.has(val); + break; + + case 'map': + var isEql = isDeep ? _.eql : SameValueZero; + obj.forEach(function (item) { + included = included || isEql(item, val); + }); + break; + + case 'set': + if (isDeep) { + obj.forEach(function (item) { + included = included || _.eql(item, val); + }); + } else { + included = obj.has(val); + } + break; + + case 'array': + if (isDeep) { + included = obj.some(function (item) { + return _.eql(item, val); + }) + } else { + included = obj.indexOf(val) !== -1; + } + break; + + default: + // This block is for asserting a subset of properties in an object. + // `_.expectTypes` isn't used here because `.include` should work with + // objects with a custom `@@toStringTag`. + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + 'object tested must be an array, a map, an object,' + + ' a set, a string, or a weakset, but ' + objType + ' given', + undefined, + ssfi + ); + } + + var props = Object.keys(val) + , firstErr = null + , numErrs = 0; + + props.forEach(function (prop) { + var propAssertion = new Assertion(obj); + _.transferFlags(this, propAssertion, true); + flag(propAssertion, 'lockSsfi', true); + + if (!negate || props.length === 1) { + propAssertion.property(prop, val[prop]); + return; + } + + try { + propAssertion.property(prop, val[prop]); + } catch (err) { + if (!_.checkError.compatibleConstructor(err, AssertionError)) { + throw err; + } + if (firstErr === null) firstErr = err; + numErrs++; + } + }, this); + + // When validating .not.include with multiple properties, we only want + // to throw an assertion error if all of the properties are included, + // in which case we throw the first property assertion error that we + // encountered. + if (negate && props.length > 1 && numErrs === props.length) { + throw firstErr; + } + return; + } + + // Assert inclusion in collection or substring in a string. + this.assert( + included + , 'expected #{this} to ' + descriptor + 'include ' + _.inspect(val) + , 'expected #{this} to not ' + descriptor + 'include ' + _.inspect(val)); + } + + Assertion.addChainableMethod('include', include, includeChainingBehavior); + Assertion.addChainableMethod('contain', include, includeChainingBehavior); + Assertion.addChainableMethod('contains', include, includeChainingBehavior); + Assertion.addChainableMethod('includes', include, includeChainingBehavior); + + /** + * ### .ok + * + * Asserts that the target is a truthy value (considered `true` in boolean context). + * However, it's often best to assert that the target is strictly (`===`) or + * deeply equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.ok; // Not recommended + * + * expect(true).to.be.true; // Recommended + * expect(true).to.be.ok; // Not recommended + * + * Add `.not` earlier in the chain to negate `.ok`. + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.not.be.ok; // Not recommended + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.ok; // Not recommended + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.be.ok; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.be.ok; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.ok; + * + * @name ok + * @namespace BDD + * @api public + */ + + Assertion.addProperty('ok', function () { + this.assert( + flag(this, 'object') + , 'expected #{this} to be truthy' + , 'expected #{this} to be falsy'); + }); + + /** + * ### .true + * + * Asserts that the target is strictly (`===`) equal to `true`. + * + * expect(true).to.be.true; + * + * Add `.not` earlier in the chain to negate `.true`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `true`. + * + * expect(false).to.be.false; // Recommended + * expect(false).to.not.be.true; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.true; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(false, 'nooo why fail??').to.be.true; + * + * @name true + * @namespace BDD + * @api public + */ + + Assertion.addProperty('true', function () { + this.assert( + true === flag(this, 'object') + , 'expected #{this} to be true' + , 'expected #{this} to be false' + , flag(this, 'negate') ? false : true + ); + }); + + /** + * ### .false + * + * Asserts that the target is strictly (`===`) equal to `false`. + * + * expect(false).to.be.false; + * + * Add `.not` earlier in the chain to negate `.false`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `false`. + * + * expect(true).to.be.true; // Recommended + * expect(true).to.not.be.false; // Not recommended + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.false; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(true, 'nooo why fail??').to.be.false; + * + * @name false + * @namespace BDD + * @api public + */ + + Assertion.addProperty('false', function () { + this.assert( + false === flag(this, 'object') + , 'expected #{this} to be false' + , 'expected #{this} to be true' + , flag(this, 'negate') ? true : false + ); + }); + + /** + * ### .null + * + * Asserts that the target is strictly (`===`) equal to `null`. + * + * expect(null).to.be.null; + * + * Add `.not` earlier in the chain to negate `.null`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `null`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.null; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.null; + * + * @name null + * @namespace BDD + * @api public + */ + + Assertion.addProperty('null', function () { + this.assert( + null === flag(this, 'object') + , 'expected #{this} to be null' + , 'expected #{this} not to be null' + ); + }); + + /** + * ### .undefined + * + * Asserts that the target is strictly (`===`) equal to `undefined`. + * + * expect(undefined).to.be.undefined; + * + * Add `.not` earlier in the chain to negate `.undefined`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to `undefined`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.undefined; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.undefined; + * + * @name undefined + * @namespace BDD + * @api public + */ + + Assertion.addProperty('undefined', function () { + this.assert( + undefined === flag(this, 'object') + , 'expected #{this} to be undefined' + , 'expected #{this} not to be undefined' + ); + }); + + /** + * ### .NaN + * + * Asserts that the target is exactly `NaN`. + * + * expect(NaN).to.be.NaN; + * + * Add `.not` earlier in the chain to negate `.NaN`. However, it's often best + * to assert that the target is equal to its expected value, rather than not + * equal to `NaN`. + * + * expect('foo').to.equal('foo'); // Recommended + * expect('foo').to.not.be.NaN; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(42, 'nooo why fail??').to.be.NaN; + * + * @name NaN + * @namespace BDD + * @api public + */ + + Assertion.addProperty('NaN', function () { + this.assert( + _.isNaN(flag(this, 'object')) + , 'expected #{this} to be NaN' + , 'expected #{this} not to be NaN' + ); + }); + + /** + * ### .exist + * + * Asserts that the target is not strictly (`===`) equal to either `null` or + * `undefined`. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.exist; // Not recommended + * + * expect(0).to.equal(0); // Recommended + * expect(0).to.exist; // Not recommended + * + * Add `.not` earlier in the chain to negate `.exist`. + * + * expect(null).to.be.null; // Recommended + * expect(null).to.not.exist; // Not recommended + * + * expect(undefined).to.be.undefined; // Recommended + * expect(undefined).to.not.exist; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(null, 'nooo why fail??').to.exist; + * + * @name exist + * @namespace BDD + * @api public + */ + + Assertion.addProperty('exist', function () { + var val = flag(this, 'object'); + this.assert( + val !== null && val !== undefined + , 'expected #{this} to exist' + , 'expected #{this} to not exist' + ); + }); + + /** + * ### .empty + * + * When the target is a string or array, `.empty` asserts that the target's + * `length` property is strictly (`===`) equal to `0`. + * + * expect([]).to.be.empty; + * expect('').to.be.empty; + * + * When the target is a map or set, `.empty` asserts that the target's `size` + * property is strictly equal to `0`. + * + * expect(new Set()).to.be.empty; + * expect(new Map()).to.be.empty; + * + * When the target is a non-function object, `.empty` asserts that the target + * doesn't have any own enumerable properties. Properties with Symbol-based + * keys are excluded from the count. + * + * expect({}).to.be.empty; + * + * Because `.empty` does different things based on the target's type, it's + * important to check the target's type before using `.empty`. See the `.a` + * doc for info on testing a target's type. + * + * expect([]).to.be.an('array').that.is.empty; + * + * Add `.not` earlier in the chain to negate `.empty`. However, it's often + * best to assert that the target contains its expected number of values, + * rather than asserting that it's not empty. + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.not.be.empty; // Not recommended + * + * expect(new Set([1, 2, 3])).to.have.property('size', 3); // Recommended + * expect(new Set([1, 2, 3])).to.not.be.empty; // Not recommended + * + * expect(Object.keys({a: 1})).to.have.lengthOf(1); // Recommended + * expect({a: 1}).to.not.be.empty; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect([1, 2, 3], 'nooo why fail??').to.be.empty; + * + * @name empty + * @namespace BDD + * @api public + */ + + Assertion.addProperty('empty', function () { + var val = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , itemsCount; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + switch (_.type(val).toLowerCase()) { + case 'array': + case 'string': + itemsCount = val.length; + break; + case 'map': + case 'set': + itemsCount = val.size; + break; + case 'weakmap': + case 'weakset': + throw new AssertionError( + flagMsg + '.empty was passed a weak collection', + undefined, + ssfi + ); + case 'function': + var msg = flagMsg + '.empty was passed a function ' + _.getName(val); + throw new AssertionError(msg.trim(), undefined, ssfi); + default: + if (val !== Object(val)) { + throw new AssertionError( + flagMsg + '.empty was passed non-string primitive ' + _.inspect(val), + undefined, + ssfi + ); + } + itemsCount = Object.keys(val).length; + } + + this.assert( + 0 === itemsCount + , 'expected #{this} to be empty' + , 'expected #{this} not to be empty' + ); + }); + + /** + * ### .arguments + * + * Asserts that the target is an `arguments` object. + * + * function test () { + * expect(arguments).to.be.arguments; + * } + * + * test(); + * + * Add `.not` earlier in the chain to negate `.arguments`. However, it's often + * best to assert which type the target is expected to be, rather than + * asserting that its not an `arguments` object. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.arguments; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({}, 'nooo why fail??').to.be.arguments; + * + * The alias `.Arguments` can be used interchangeably with `.arguments`. + * + * @name arguments + * @alias Arguments + * @namespace BDD + * @api public + */ + + function checkArguments () { + var obj = flag(this, 'object') + , type = _.type(obj); + this.assert( + 'Arguments' === type + , 'expected #{this} to be arguments but got ' + type + , 'expected #{this} to not be arguments' + ); + } + + Assertion.addProperty('arguments', checkArguments); + Assertion.addProperty('Arguments', checkArguments); + + /** + * ### .equal(val[, msg]) + * + * Asserts that the target is strictly (`===`) equal to the given `val`. + * + * expect(1).to.equal(1); + * expect('foo').to.equal('foo'); + * + * Add `.deep` earlier in the chain to use deep equality instead. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) equals `{a: 1}` + * expect({a: 1}).to.deep.equal({a: 1}); + * expect({a: 1}).to.not.equal({a: 1}); + * + * // Target array deeply (but not strictly) equals `[1, 2]` + * expect([1, 2]).to.deep.equal([1, 2]); + * expect([1, 2]).to.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.equal`. However, it's often + * best to assert that the target is equal to its expected value, rather than + * not equal to one of countless unexpected values. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.equal(2); // Not recommended + * + * `.equal` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.equal(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.equal(2); + * + * The aliases `.equals` and `eq` can be used interchangeably with `.equal`. + * + * @name equal + * @alias equals + * @alias eq + * @param {Mixed} val + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEqual (val, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + if (flag(this, 'deep')) { + var prevLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + this.eql(val); + flag(this, 'lockSsfi', prevLockSsfi); + } else { + this.assert( + val === obj + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{exp}' + , val + , this._obj + , true + ); + } + } + + Assertion.addMethod('equal', assertEqual); + Assertion.addMethod('equals', assertEqual); + Assertion.addMethod('eq', assertEqual); + + /** + * ### .eql(obj[, msg]) + * + * Asserts that the target is deeply equal to the given `obj`. See the + * `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target object is deeply (but not strictly) equal to {a: 1} + * expect({a: 1}).to.eql({a: 1}).but.not.equal({a: 1}); + * + * // Target array is deeply (but not strictly) equal to [1, 2] + * expect([1, 2]).to.eql([1, 2]).but.not.equal([1, 2]); + * + * Add `.not` earlier in the chain to negate `.eql`. However, it's often best + * to assert that the target is deeply equal to its expected value, rather + * than not deeply equal to one of countless unexpected values. + * + * expect({a: 1}).to.eql({a: 1}); // Recommended + * expect({a: 1}).to.not.eql({b: 2}); // Not recommended + * + * `.eql` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect({a: 1}).to.eql({b: 2}, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.eql({b: 2}); + * + * The alias `.eqls` can be used interchangeably with `.eql`. + * + * The `.deep.equal` assertion is almost identical to `.eql` but with one + * difference: `.deep.equal` causes deep equality comparisons to also be used + * for any other assertions that follow in the chain. + * + * @name eql + * @alias eqls + * @param {Mixed} obj + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertEql(obj, msg) { + if (msg) flag(this, 'message', msg); + this.assert( + _.eql(obj, flag(this, 'object')) + , 'expected #{this} to deeply equal #{exp}' + , 'expected #{this} to not deeply equal #{exp}' + , obj + , this._obj + , true + ); + } + + Assertion.addMethod('eql', assertEql); + Assertion.addMethod('eqls', assertEql); + + /** + * ### .above(n[, msg]) + * + * Asserts that the target is a number or a date greater than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.above(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.above(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.above`. + * + * expect(2).to.equal(2); // Recommended + * expect(1).to.not.be.above(2); // Not recommended + * + * `.above` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.above(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.above(2); + * + * The aliases `.gt` and `.greaterThan` can be used interchangeably with + * `.above`. + * + * @name above + * @alias gt + * @alias greaterThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertAbove (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to above must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to above must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount > n + , 'expected #{this} to have a ' + descriptor + ' above #{exp} but got #{act}' + , 'expected #{this} to not have a ' + descriptor + ' above #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj > n + , 'expected #{this} to be above #{exp}' + , 'expected #{this} to be at most #{exp}' + , n + ); + } + } + + Assertion.addMethod('above', assertAbove); + Assertion.addMethod('gt', assertAbove); + Assertion.addMethod('greaterThan', assertAbove); + + /** + * ### .least(n[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `n` respectively. However, it's often best to assert that the target is equal to + * its expected value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.at.least(1); // Not recommended + * expect(2).to.be.at.least(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.least(2); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.least(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.least`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.at.least(2); // Not recommended + * + * `.least` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.at.least(2, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.at.least(2); + * + * The alias `.gte` can be used interchangeably with `.least`. + * + * @name least + * @alias gte + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLeast (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to least must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to least must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= n + , 'expected #{this} to have a ' + descriptor + ' at least #{exp} but got #{act}' + , 'expected #{this} to have a ' + descriptor + ' below #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj >= n + , 'expected #{this} to be at least #{exp}' + , 'expected #{this} to be below #{exp}' + , n + ); + } + } + + Assertion.addMethod('least', assertLeast); + Assertion.addMethod('gte', assertLeast); + + /** + * ### .below(n[, msg]) + * + * Asserts that the target is a number or a date less than the given number or date `n` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.below(2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is less than the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.below(4); // Not recommended + * + * expect([1, 2, 3]).to.have.length(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.below(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.below`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.below(1); // Not recommended + * + * `.below` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.below(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.below(1); + * + * The aliases `.lt` and `.lessThan` can be used interchangeably with + * `.below`. + * + * @name below + * @alias lt + * @alias lessThan + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertBelow (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to below must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to below must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount < n + , 'expected #{this} to have a ' + descriptor + ' below #{exp} but got #{act}' + , 'expected #{this} to not have a ' + descriptor + ' below #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj < n + , 'expected #{this} to be below #{exp}' + , 'expected #{this} to be at least #{exp}' + , n + ); + } + } + + Assertion.addMethod('below', assertBelow); + Assertion.addMethod('lt', assertBelow); + Assertion.addMethod('lessThan', assertBelow); + + /** + * ### .most(n[, msg]) + * + * Asserts that the target is a number or a date less than or equal to the given number + * or date `n` respectively. However, it's often best to assert that the target is equal to its + * expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.at.most(2); // Not recommended + * expect(1).to.be.at.most(1); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is less than or equal to the given number `n`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.at.most(4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.at.most(4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.most`. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.not.be.at.most(1); // Not recommended + * + * `.most` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(2).to.be.at.most(1, 'nooo why fail??'); + * expect(2, 'nooo why fail??').to.be.at.most(1); + * + * The alias `.lte` can be used interchangeably with `.most`. + * + * @name most + * @alias lte + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertMost (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , nType = _.type(n).toLowerCase() + , errorMessage + , shouldThrow = true; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && nType !== 'date')) { + errorMessage = msgPrefix + 'the argument to most must be a date'; + } else if (nType !== 'number' && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the argument to most must be a number'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount <= n + , 'expected #{this} to have a ' + descriptor + ' at most #{exp} but got #{act}' + , 'expected #{this} to have a ' + descriptor + ' above #{exp}' + , n + , itemsCount + ); + } else { + this.assert( + obj <= n + , 'expected #{this} to be at most #{exp}' + , 'expected #{this} to be above #{exp}' + , n + ); + } + } + + Assertion.addMethod('most', assertMost); + Assertion.addMethod('lte', assertMost); + + /** + * ### .within(start, finish[, msg]) + * + * Asserts that the target is a number or a date greater than or equal to the given + * number or date `start`, and less than or equal to the given number or date `finish` respectively. + * However, it's often best to assert that the target is equal to its expected + * value. + * + * expect(2).to.equal(2); // Recommended + * expect(2).to.be.within(1, 3); // Not recommended + * expect(2).to.be.within(2, 3); // Not recommended + * expect(2).to.be.within(1, 2); // Not recommended + * + * Add `.lengthOf` earlier in the chain to assert that the target's `length` + * or `size` is greater than or equal to the given number `start`, and less + * than or equal to the given number `finish`. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.have.lengthOf.within(2, 4); // Not recommended + * + * expect([1, 2, 3]).to.have.lengthOf(3); // Recommended + * expect([1, 2, 3]).to.have.lengthOf.within(2, 4); // Not recommended + * + * Add `.not` earlier in the chain to negate `.within`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.within(2, 4); // Not recommended + * + * `.within` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(4).to.be.within(1, 3, 'nooo why fail??'); + * expect(4, 'nooo why fail??').to.be.within(1, 3); + * + * @name within + * @param {Number} start lower bound inclusive + * @param {Number} finish upper bound inclusive + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('within', function (start, finish, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , doLength = flag(this, 'doLength') + , flagMsg = flag(this, 'message') + , msgPrefix = ((flagMsg) ? flagMsg + ': ' : '') + , ssfi = flag(this, 'ssfi') + , objType = _.type(obj).toLowerCase() + , startType = _.type(start).toLowerCase() + , finishType = _.type(finish).toLowerCase() + , errorMessage + , shouldThrow = true + , range = (startType === 'date' && finishType === 'date') + ? start.toUTCString() + '..' + finish.toUTCString() + : start + '..' + finish; + + if (doLength && objType !== 'map' && objType !== 'set') { + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + } + + if (!doLength && (objType === 'date' && (startType !== 'date' || finishType !== 'date'))) { + errorMessage = msgPrefix + 'the arguments to within must be dates'; + } else if ((startType !== 'number' || finishType !== 'number') && (doLength || objType === 'number')) { + errorMessage = msgPrefix + 'the arguments to within must be numbers'; + } else if (!doLength && (objType !== 'date' && objType !== 'number')) { + var printObj = (objType === 'string') ? "'" + obj + "'" : obj; + errorMessage = msgPrefix + 'expected ' + printObj + ' to be a number or a date'; + } else { + shouldThrow = false; + } + + if (shouldThrow) { + throw new AssertionError(errorMessage, undefined, ssfi); + } + + if (doLength) { + var descriptor = 'length' + , itemsCount; + if (objType === 'map' || objType === 'set') { + descriptor = 'size'; + itemsCount = obj.size; + } else { + itemsCount = obj.length; + } + this.assert( + itemsCount >= start && itemsCount <= finish + , 'expected #{this} to have a ' + descriptor + ' within ' + range + , 'expected #{this} to not have a ' + descriptor + ' within ' + range + ); + } else { + this.assert( + obj >= start && obj <= finish + , 'expected #{this} to be within ' + range + , 'expected #{this} to not be within ' + range + ); + } + }); + + /** + * ### .instanceof(constructor[, msg]) + * + * Asserts that the target is an instance of the given `constructor`. + * + * function Cat () { } + * + * expect(new Cat()).to.be.an.instanceof(Cat); + * expect([1, 2]).to.be.an.instanceof(Array); + * + * Add `.not` earlier in the chain to negate `.instanceof`. + * + * expect({a: 1}).to.not.be.an.instanceof(Array); + * + * `.instanceof` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.be.an.instanceof(Array, 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.an.instanceof(Array); + * + * Due to limitations in ES5, `.instanceof` may not always work as expected + * when using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing built-in object such as + * `Array`, `Error`, and `Map`. See your transpiler's docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * The alias `.instanceOf` can be used interchangeably with `.instanceof`. + * + * @name instanceof + * @param {Constructor} constructor + * @param {String} msg _optional_ + * @alias instanceOf + * @namespace BDD + * @api public + */ + + function assertInstanceOf (constructor, msg) { + if (msg) flag(this, 'message', msg); + + var target = flag(this, 'object') + var ssfi = flag(this, 'ssfi'); + var flagMsg = flag(this, 'message'); + + try { + var isInstanceOf = target instanceof constructor; + } catch (err) { + if (err instanceof TypeError) { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'The instanceof assertion needs a constructor but ' + + _.type(constructor) + ' was given.', + undefined, + ssfi + ); + } + throw err; + } + + var name = _.getName(constructor); + if (name === null) { + name = 'an unnamed constructor'; + } + + this.assert( + isInstanceOf + , 'expected #{this} to be an instance of ' + name + , 'expected #{this} to not be an instance of ' + name + ); + }; + + Assertion.addMethod('instanceof', assertInstanceOf); + Assertion.addMethod('instanceOf', assertInstanceOf); + + /** + * ### .property(name[, val[, msg]]) + * + * Asserts that the target has a property with the given key `name`. + * + * expect({a: 1}).to.have.property('a'); + * + * When `val` is provided, `.property` also asserts that the property's value + * is equal to the given `val`. + * + * expect({a: 1}).to.have.property('a', 1); + * + * By default, strict (`===`) equality is used. Add `.deep` earlier in the + * chain to use deep equality instead. See the `deep-eql` project page for + * info on the deep equality algorithm: https://github.com/chaijs/deep-eql. + * + * // Target object deeply (but not strictly) has property `x: {a: 1}` + * expect({x: {a: 1}}).to.have.deep.property('x', {a: 1}); + * expect({x: {a: 1}}).to.not.have.property('x', {a: 1}); + * + * The target's enumerable and non-enumerable properties are always included + * in the search. By default, both own and inherited properties are included. + * Add `.own` earlier in the chain to exclude inherited properties from the + * search. + * + * Object.prototype.b = 2; + * + * expect({a: 1}).to.have.own.property('a'); + * expect({a: 1}).to.have.own.property('a', 1); + * expect({a: 1}).to.have.property('b'); + * expect({a: 1}).to.not.have.own.property('b'); + * + * `.deep` and `.own` can be combined. + * + * expect({x: {a: 1}}).to.have.deep.own.property('x', {a: 1}); + * + * Add `.nested` earlier in the chain to enable dot- and bracket-notation when + * referencing nested properties. + * + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]'); + * expect({a: {b: ['x', 'y']}}).to.have.nested.property('a.b[1]', 'y'); + * + * If `.` or `[]` are part of an actual property name, they can be escaped by + * adding two backslashes before them. + * + * expect({'.a': {'[b]': 'x'}}).to.have.nested.property('\\.a.\\[b\\]'); + * + * `.deep` and `.nested` can be combined. + * + * expect({a: {b: [{c: 3}]}}) + * .to.have.deep.nested.property('a.b[0]', {c: 3}); + * + * `.own` and `.nested` cannot be combined. + * + * Add `.not` earlier in the chain to negate `.property`. + * + * expect({a: 1}).to.not.have.property('b'); + * + * However, it's dangerous to negate `.property` when providing `val`. The + * problem is that it creates uncertain expectations by asserting that the + * target either doesn't have a property with the given key `name`, or that it + * does have a property with the given key `name` but its value isn't equal to + * the given `val`. It's often best to identify the exact output that's + * expected, and then write an assertion that only accepts that exact output. + * + * When the target isn't expected to have a property with the given key + * `name`, it's often best to assert exactly that. + * + * expect({b: 2}).to.not.have.property('a'); // Recommended + * expect({b: 2}).to.not.have.property('a', 1); // Not recommended + * + * When the target is expected to have a property with the given key `name`, + * it's often best to assert that the property has its expected value, rather + * than asserting that it doesn't have one of many unexpected values. + * + * expect({a: 3}).to.have.property('a', 3); // Recommended + * expect({a: 3}).to.not.have.property('a', 1); // Not recommended + * + * `.property` changes the target of any assertions that follow in the chain + * to be the value of the property from the original target object. + * + * expect({a: 1}).to.have.property('a').that.is.a('number'); + * + * `.property` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing `val`, only use the + * second form. + * + * // Recommended + * expect({a: 1}).to.have.property('a', 2, 'nooo why fail??'); + * expect({a: 1}, 'nooo why fail??').to.have.property('a', 2); + * expect({a: 1}, 'nooo why fail??').to.have.property('b'); + * + * // Not recommended + * expect({a: 1}).to.have.property('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `val`. Instead, + * it's asserting that the target object has a `b` property that's equal to + * `undefined`. + * + * The assertions `.ownProperty` and `.haveOwnProperty` can be used + * interchangeably with `.own.property`. + * + * @name property + * @param {String} name + * @param {Mixed} val (optional) + * @param {String} msg _optional_ + * @returns value of property for chaining + * @namespace BDD + * @api public + */ + + function assertProperty (name, val, msg) { + if (msg) flag(this, 'message', msg); + + var isNested = flag(this, 'nested') + , isOwn = flag(this, 'own') + , flagMsg = flag(this, 'message') + , obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , nameType = typeof name; + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + if (isNested) { + if (nameType !== 'string') { + throw new AssertionError( + flagMsg + 'the argument to property must be a string when using nested syntax', + undefined, + ssfi + ); + } + } else { + if (nameType !== 'string' && nameType !== 'number' && nameType !== 'symbol') { + throw new AssertionError( + flagMsg + 'the argument to property must be a string, number, or symbol', + undefined, + ssfi + ); + } + } + + if (isNested && isOwn) { + throw new AssertionError( + flagMsg + 'The "nested" and "own" flags cannot be combined.', + undefined, + ssfi + ); + } + + if (obj === null || obj === undefined) { + throw new AssertionError( + flagMsg + 'Target cannot be null or undefined.', + undefined, + ssfi + ); + } + + var isDeep = flag(this, 'deep') + , negate = flag(this, 'negate') + , pathInfo = isNested ? _.getPathInfo(obj, name) : null + , value = isNested ? pathInfo.value : obj[name]; + + var descriptor = ''; + if (isDeep) descriptor += 'deep '; + if (isOwn) descriptor += 'own '; + if (isNested) descriptor += 'nested '; + descriptor += 'property '; + + var hasProperty; + if (isOwn) hasProperty = Object.prototype.hasOwnProperty.call(obj, name); + else if (isNested) hasProperty = pathInfo.exists; + else hasProperty = _.hasProperty(obj, name); + + // When performing a negated assertion for both name and val, merely having + // a property with the given name isn't enough to cause the assertion to + // fail. It must both have a property with the given name, and the value of + // that property must equal the given val. Therefore, skip this assertion in + // favor of the next. + if (!negate || arguments.length === 1) { + this.assert( + hasProperty + , 'expected #{this} to have ' + descriptor + _.inspect(name) + , 'expected #{this} to not have ' + descriptor + _.inspect(name)); + } + + if (arguments.length > 1) { + this.assert( + hasProperty && (isDeep ? _.eql(val, value) : val === value) + , 'expected #{this} to have ' + descriptor + _.inspect(name) + ' of #{exp}, but got #{act}' + , 'expected #{this} to not have ' + descriptor + _.inspect(name) + ' of #{act}' + , val + , value + ); + } + + flag(this, 'object', value); + } + + Assertion.addMethod('property', assertProperty); + + function assertOwnProperty (name, value, msg) { + flag(this, 'own', true); + assertProperty.apply(this, arguments); + } + + Assertion.addMethod('ownProperty', assertOwnProperty); + Assertion.addMethod('haveOwnProperty', assertOwnProperty); + + /** + * ### .ownPropertyDescriptor(name[, descriptor[, msg]]) + * + * Asserts that the target has its own property descriptor with the given key + * `name`. Enumerable and non-enumerable properties are included in the + * search. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a'); + * + * When `descriptor` is provided, `.ownPropertyDescriptor` also asserts that + * the property's descriptor is deeply equal to the given `descriptor`. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * Add `.not` earlier in the chain to negate `.ownPropertyDescriptor`. + * + * expect({a: 1}).to.not.have.ownPropertyDescriptor('b'); + * + * However, it's dangerous to negate `.ownPropertyDescriptor` when providing + * a `descriptor`. The problem is that it creates uncertain expectations by + * asserting that the target either doesn't have a property descriptor with + * the given key `name`, or that it does have a property descriptor with the + * given key `name` but its not deeply equal to the given `descriptor`. It's + * often best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to have a property descriptor with the given + * key `name`, it's often best to assert exactly that. + * + * // Recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a'); + * + * // Not recommended + * expect({b: 2}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * When the target is expected to have a property descriptor with the given + * key `name`, it's often best to assert that the property has its expected + * descriptor, rather than asserting that it doesn't have one of many + * unexpected descriptors. + * + * // Recommended + * expect({a: 3}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 3, + * }); + * + * // Not recommended + * expect({a: 3}).to.not.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 1, + * }); + * + * `.ownPropertyDescriptor` changes the target of any assertions that follow + * in the chain to be the value of the property descriptor from the original + * target object. + * + * expect({a: 1}).to.have.ownPropertyDescriptor('a') + * .that.has.property('enumerable', true); + * + * `.ownPropertyDescriptor` accepts an optional `msg` argument which is a + * custom error message to show when the assertion fails. The message can also + * be given as the second argument to `expect`. When not providing + * `descriptor`, only use the second form. + * + * // Recommended + * expect({a: 1}).to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }, 'nooo why fail??'); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('a', { + * configurable: true, + * enumerable: true, + * writable: true, + * value: 2, + * }); + * + * // Recommended + * expect({a: 1}, 'nooo why fail??').to.have.ownPropertyDescriptor('b'); + * + * // Not recommended + * expect({a: 1}) + * .to.have.ownPropertyDescriptor('b', undefined, 'nooo why fail??'); + * + * The above assertion isn't the same thing as not providing `descriptor`. + * Instead, it's asserting that the target object has a `b` property + * descriptor that's deeply equal to `undefined`. + * + * The alias `.haveOwnPropertyDescriptor` can be used interchangeably with + * `.ownPropertyDescriptor`. + * + * @name ownPropertyDescriptor + * @alias haveOwnPropertyDescriptor + * @param {String} name + * @param {Object} descriptor _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertOwnPropertyDescriptor (name, descriptor, msg) { + if (typeof descriptor === 'string') { + msg = descriptor; + descriptor = null; + } + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var actualDescriptor = Object.getOwnPropertyDescriptor(Object(obj), name); + if (actualDescriptor && descriptor) { + this.assert( + _.eql(descriptor, actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to match ' + _.inspect(descriptor) + ', got ' + _.inspect(actualDescriptor) + , 'expected the own property descriptor for ' + _.inspect(name) + ' on #{this} to not match ' + _.inspect(descriptor) + , descriptor + , actualDescriptor + , true + ); + } else { + this.assert( + actualDescriptor + , 'expected #{this} to have an own property descriptor for ' + _.inspect(name) + , 'expected #{this} to not have an own property descriptor for ' + _.inspect(name) + ); + } + flag(this, 'object', actualDescriptor); + } + + Assertion.addMethod('ownPropertyDescriptor', assertOwnPropertyDescriptor); + Assertion.addMethod('haveOwnPropertyDescriptor', assertOwnPropertyDescriptor); + + /** + * ### .lengthOf(n[, msg]) + * + * Asserts that the target's `length` or `size` is equal to the given number + * `n`. + * + * expect([1, 2, 3]).to.have.lengthOf(3); + * expect('foo').to.have.lengthOf(3); + * expect(new Set([1, 2, 3])).to.have.lengthOf(3); + * expect(new Map([['a', 1], ['b', 2], ['c', 3]])).to.have.lengthOf(3); + * + * Add `.not` earlier in the chain to negate `.lengthOf`. However, it's often + * best to assert that the target's `length` property is equal to its expected + * value, rather than not equal to one of many unexpected values. + * + * expect('foo').to.have.lengthOf(3); // Recommended + * expect('foo').to.not.have.lengthOf(4); // Not recommended + * + * `.lengthOf` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2, 3]).to.have.lengthOf(2, 'nooo why fail??'); + * expect([1, 2, 3], 'nooo why fail??').to.have.lengthOf(2); + * + * `.lengthOf` can also be used as a language chain, causing all `.above`, + * `.below`, `.least`, `.most`, and `.within` assertions that follow in the + * chain to use the target's `length` property as the target. However, it's + * often best to assert that the target's `length` property is equal to its + * expected length, rather than asserting that its `length` property falls + * within some range of values. + * + * // Recommended + * expect([1, 2, 3]).to.have.lengthOf(3); + * + * // Not recommended + * expect([1, 2, 3]).to.have.lengthOf.above(2); + * expect([1, 2, 3]).to.have.lengthOf.below(4); + * expect([1, 2, 3]).to.have.lengthOf.at.least(3); + * expect([1, 2, 3]).to.have.lengthOf.at.most(3); + * expect([1, 2, 3]).to.have.lengthOf.within(2,4); + * + * Due to a compatibility issue, the alias `.length` can't be chained directly + * off of an uninvoked method such as `.a`. Therefore, `.length` can't be used + * interchangeably with `.lengthOf` in every situation. It's recommended to + * always use `.lengthOf` instead of `.length`. + * + * expect([1, 2, 3]).to.have.a.length(3); // incompatible; throws error + * expect([1, 2, 3]).to.have.a.lengthOf(3); // passes as expected + * + * @name lengthOf + * @alias length + * @param {Number} n + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertLengthChain () { + flag(this, 'doLength', true); + } + + function assertLength (n, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , objType = _.type(obj).toLowerCase() + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi') + , descriptor = 'length' + , itemsCount; + + switch (objType) { + case 'map': + case 'set': + descriptor = 'size'; + itemsCount = obj.size; + break; + default: + new Assertion(obj, flagMsg, ssfi, true).to.have.property('length'); + itemsCount = obj.length; + } + + this.assert( + itemsCount == n + , 'expected #{this} to have a ' + descriptor + ' of #{exp} but got #{act}' + , 'expected #{this} to not have a ' + descriptor + ' of #{act}' + , n + , itemsCount + ); + } + + Assertion.addChainableMethod('length', assertLength, assertLengthChain); + Assertion.addChainableMethod('lengthOf', assertLength, assertLengthChain); + + /** + * ### .match(re[, msg]) + * + * Asserts that the target matches the given regular expression `re`. + * + * expect('foobar').to.match(/^foo/); + * + * Add `.not` earlier in the chain to negate `.match`. + * + * expect('foobar').to.not.match(/taco/); + * + * `.match` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect('foobar').to.match(/taco/, 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.match(/taco/); + * + * The alias `.matches` can be used interchangeably with `.match`. + * + * @name match + * @alias matches + * @param {RegExp} re + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + function assertMatch(re, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + this.assert( + re.exec(obj) + , 'expected #{this} to match ' + re + , 'expected #{this} not to match ' + re + ); + } + + Assertion.addMethod('match', assertMatch); + Assertion.addMethod('matches', assertMatch); + + /** + * ### .string(str[, msg]) + * + * Asserts that the target string contains the given substring `str`. + * + * expect('foobar').to.have.string('bar'); + * + * Add `.not` earlier in the chain to negate `.string`. + * + * expect('foobar').to.not.have.string('taco'); + * + * `.string` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect('foobar').to.have.string('taco', 'nooo why fail??'); + * expect('foobar', 'nooo why fail??').to.have.string('taco'); + * + * @name string + * @param {String} str + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('string', function (str, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(obj, flagMsg, ssfi, true).is.a('string'); + + this.assert( + ~obj.indexOf(str) + , 'expected #{this} to contain ' + _.inspect(str) + , 'expected #{this} to not contain ' + _.inspect(str) + ); + }); + + /** + * ### .keys(key1[, key2[, ...]]) + * + * Asserts that the target object, array, map, or set has the given keys. Only + * the target's own inherited properties are included in the search. + * + * When the target is an object or array, keys can be provided as one or more + * string arguments, a single array argument, or a single object argument. In + * the latter case, only the keys in the given object matter; the values are + * ignored. + * + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * expect(['x', 'y']).to.have.all.keys(0, 1); + * + * expect({a: 1, b: 2}).to.have.all.keys(['a', 'b']); + * expect(['x', 'y']).to.have.all.keys([0, 1]); + * + * expect({a: 1, b: 2}).to.have.all.keys({a: 4, b: 5}); // ignore 4 and 5 + * expect(['x', 'y']).to.have.all.keys({0: 4, 1: 5}); // ignore 4 and 5 + * + * When the target is a map or set, each key must be provided as a separate + * argument. + * + * expect(new Map([['a', 1], ['b', 2]])).to.have.all.keys('a', 'b'); + * expect(new Set(['a', 'b'])).to.have.all.keys('a', 'b'); + * + * Because `.keys` does different things based on the target's type, it's + * important to check the target's type before using `.keys`. See the `.a` doc + * for info on testing a target's type. + * + * expect({a: 1, b: 2}).to.be.an('object').that.has.all.keys('a', 'b'); + * + * By default, strict (`===`) equality is used to compare keys of maps and + * sets. Add `.deep` earlier in the chain to use deep equality instead. See + * the `deep-eql` project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target set deeply (but not strictly) has key `{a: 1}` + * expect(new Set([{a: 1}])).to.have.all.deep.keys([{a: 1}]); + * expect(new Set([{a: 1}])).to.not.have.all.keys([{a: 1}]); + * + * By default, the target must have all of the given keys and no more. Add + * `.any` earlier in the chain to only require that the target have at least + * one of the given keys. Also, add `.not` earlier in the chain to negate + * `.keys`. It's often best to add `.any` when negating `.keys`, and to use + * `.all` when asserting `.keys` without negation. + * + * When negating `.keys`, `.any` is preferred because `.not.any.keys` asserts + * exactly what's expected of the output, whereas `.not.all.keys` creates + * uncertain expectations. + * + * // Recommended; asserts that target doesn't have any of the given keys + * expect({a: 1, b: 2}).to.not.have.any.keys('c', 'd'); + * + * // Not recommended; asserts that target doesn't have all of the given + * // keys but may or may not have some of them + * expect({a: 1, b: 2}).to.not.have.all.keys('c', 'd'); + * + * When asserting `.keys` without negation, `.all` is preferred because + * `.all.keys` asserts exactly what's expected of the output, whereas + * `.any.keys` creates uncertain expectations. + * + * // Recommended; asserts that target has all the given keys + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); + * + * // Not recommended; asserts that target has at least one of the given + * // keys but may or may not have more of them + * expect({a: 1, b: 2}).to.have.any.keys('a', 'b'); + * + * Note that `.all` is used by default when neither `.all` nor `.any` appear + * earlier in the chain. However, it's often best to add `.all` anyway because + * it improves readability. + * + * // Both assertions are identical + * expect({a: 1, b: 2}).to.have.all.keys('a', 'b'); // Recommended + * expect({a: 1, b: 2}).to.have.keys('a', 'b'); // Not recommended + * + * Add `.include` earlier in the chain to require that the target's keys be a + * superset of the expected keys, rather than identical sets. + * + * // Target object's keys are a superset of ['a', 'b'] but not identical + * expect({a: 1, b: 2, c: 3}).to.include.all.keys('a', 'b'); + * expect({a: 1, b: 2, c: 3}).to.not.have.all.keys('a', 'b'); + * + * However, if `.any` and `.include` are combined, only the `.any` takes + * effect. The `.include` is ignored in this case. + * + * // Both assertions are identical + * expect({a: 1}).to.have.any.keys('a', 'b'); + * expect({a: 1}).to.include.any.keys('a', 'b'); + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.have.key('b'); + * + * The alias `.key` can be used interchangeably with `.keys`. + * + * @name keys + * @alias key + * @param {...String|Array|Object} keys + * @namespace BDD + * @api public + */ + + function assertKeys (keys) { + var obj = flag(this, 'object') + , objType = _.type(obj) + , keysType = _.type(keys) + , ssfi = flag(this, 'ssfi') + , isDeep = flag(this, 'deep') + , str + , deepStr = '' + , actual + , ok = true + , flagMsg = flag(this, 'message'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + var mixedArgsMsg = flagMsg + 'when testing keys against an object or an array you must give a single Array|Object|String argument or multiple String arguments'; + + if (objType === 'Map' || objType === 'Set') { + deepStr = isDeep ? 'deeply ' : ''; + actual = []; + + // Map and Set '.keys' aren't supported in IE 11. Therefore, use .forEach. + obj.forEach(function (val, key) { actual.push(key) }); + + if (keysType !== 'Array') { + keys = Array.prototype.slice.call(arguments); + } + } else { + actual = _.getOwnEnumerableProperties(obj); + + switch (keysType) { + case 'Array': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + break; + case 'Object': + if (arguments.length > 1) { + throw new AssertionError(mixedArgsMsg, undefined, ssfi); + } + keys = Object.keys(keys); + break; + default: + keys = Array.prototype.slice.call(arguments); + } + + // Only stringify non-Symbols because Symbols would become "Symbol()" + keys = keys.map(function (val) { + return typeof val === 'symbol' ? val : String(val); + }); + } + + if (!keys.length) { + throw new AssertionError(flagMsg + 'keys required', undefined, ssfi); + } + + var len = keys.length + , any = flag(this, 'any') + , all = flag(this, 'all') + , expected = keys; + + if (!any && !all) { + all = true; + } + + // Has any + if (any) { + ok = expected.some(function(expectedKey) { + return actual.some(function(actualKey) { + if (isDeep) { + return _.eql(expectedKey, actualKey); + } else { + return expectedKey === actualKey; + } + }); + }); + } + + // Has all + if (all) { + ok = expected.every(function(expectedKey) { + return actual.some(function(actualKey) { + if (isDeep) { + return _.eql(expectedKey, actualKey); + } else { + return expectedKey === actualKey; + } + }); + }); + + if (!flag(this, 'contains')) { + ok = ok && keys.length == actual.length; + } + } + + // Key string + if (len > 1) { + keys = keys.map(function(key) { + return _.inspect(key); + }); + var last = keys.pop(); + if (all) { + str = keys.join(', ') + ', and ' + last; + } + if (any) { + str = keys.join(', ') + ', or ' + last; + } + } else { + str = _.inspect(keys[0]); + } + + // Form + str = (len > 1 ? 'keys ' : 'key ') + str; + + // Have / include + str = (flag(this, 'contains') ? 'contain ' : 'have ') + str; + + // Assertion + this.assert( + ok + , 'expected #{this} to ' + deepStr + str + , 'expected #{this} to not ' + deepStr + str + , expected.slice(0).sort(_.compareByInspect) + , actual.sort(_.compareByInspect) + , true + ); + } + + Assertion.addMethod('keys', assertKeys); + Assertion.addMethod('key', assertKeys); + + /** + * ### .throw([errorLike], [errMsgMatcher], [msg]) + * + * When no arguments are provided, `.throw` invokes the target function and + * asserts that an error is thrown. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(); + * + * When one argument is provided, and it's an error constructor, `.throw` + * invokes the target function and asserts that an error is thrown that's an + * instance of that error constructor. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError); + * + * When one argument is provided, and it's an error instance, `.throw` invokes + * the target function and asserts that an error is thrown that's strictly + * (`===`) equal to that error instance. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(err); + * + * When one argument is provided, and it's a string, `.throw` invokes the + * target function and asserts that an error is thrown with a message that + * contains that string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw('salmon'); + * + * When one argument is provided, and it's a regular expression, `.throw` + * invokes the target function and asserts that an error is thrown with a + * message that matches that regular expression. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(/salmon/); + * + * When two arguments are provided, and the first is an error instance or + * constructor, and the second is a string or regular expression, `.throw` + * invokes the function and asserts that an error is thrown that fulfills both + * conditions as described above. + * + * var err = new TypeError('Illegal salmon!'); + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); + * expect(badFn).to.throw(TypeError, /salmon/); + * expect(badFn).to.throw(err, 'salmon'); + * expect(badFn).to.throw(err, /salmon/); + * + * Add `.not` earlier in the chain to negate `.throw`. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); + * + * However, it's dangerous to negate `.throw` when providing any arguments. + * The problem is that it creates uncertain expectations by asserting that the + * target either doesn't throw an error, or that it throws an error but of a + * different type than the given type, or that it throws an error of the given + * type but with a message that doesn't include the given string. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to throw an error, it's often best to assert + * exactly that. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.not.throw(); // Recommended + * expect(goodFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * When the target is expected to throw an error, it's often best to assert + * that the error is of its expected type, and has a message that includes an + * expected string, rather than asserting that it doesn't have one of many + * unexpected types, and doesn't have a message that includes some string. + * + * var badFn = function () { throw new TypeError('Illegal salmon!'); }; + * + * expect(badFn).to.throw(TypeError, 'salmon'); // Recommended + * expect(badFn).to.not.throw(ReferenceError, 'x'); // Not recommended + * + * `.throw` changes the target of any assertions that follow in the chain to + * be the error object that's thrown. + * + * var err = new TypeError('Illegal salmon!'); + * err.code = 42; + * var badFn = function () { throw err; }; + * + * expect(badFn).to.throw(TypeError).with.property('code', 42); + * + * `.throw` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. When not providing two arguments, always use + * the second form. + * + * var goodFn = function () {}; + * + * expect(goodFn).to.throw(TypeError, 'x', 'nooo why fail??'); + * expect(goodFn, 'nooo why fail??').to.throw(); + * + * Due to limitations in ES5, `.throw` may not always work as expected when + * using a transpiler such as Babel or TypeScript. In particular, it may + * produce unexpected results when subclassing the built-in `Error` object and + * then passing the subclassed constructor to `.throw`. See your transpiler's + * docs for details: + * + * - ([Babel](https://babeljs.io/docs/usage/caveats/#classes)) + * - ([TypeScript](https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work)) + * + * Beware of some common mistakes when using the `throw` assertion. One common + * mistake is to accidentally invoke the function yourself instead of letting + * the `throw` assertion invoke the function for you. For example, when + * testing if a function named `fn` throws, provide `fn` instead of `fn()` as + * the target for the assertion. + * + * expect(fn).to.throw(); // Good! Tests `fn` as desired + * expect(fn()).to.throw(); // Bad! Tests result of `fn()`, not `fn` + * + * If you need to assert that your function `fn` throws when passed certain + * arguments, then wrap a call to `fn` inside of another function. + * + * expect(function () { fn(42); }).to.throw(); // Function expression + * expect(() => fn(42)).to.throw(); // ES6 arrow function + * + * Another common mistake is to provide an object method (or any stand-alone + * function that relies on `this`) as the target of the assertion. Doing so is + * problematic because the `this` context will be lost when the function is + * invoked by `.throw`; there's no way for it to know what `this` is supposed + * to be. There are two ways around this problem. One solution is to wrap the + * method or function call inside of another function. Another solution is to + * use `bind`. + * + * expect(function () { cat.meow(); }).to.throw(); // Function expression + * expect(() => cat.meow()).to.throw(); // ES6 arrow function + * expect(cat.meow.bind(cat)).to.throw(); // Bind + * + * Finally, it's worth mentioning that it's a best practice in JavaScript to + * only throw `Error` and derivatives of `Error` such as `ReferenceError`, + * `TypeError`, and user-defined objects that extend `Error`. No other type of + * value will generate a stack trace when initialized. With that said, the + * `throw` assertion does technically support any type of value being thrown, + * not just `Error` and its derivatives. + * + * The aliases `.throws` and `.Throw` can be used interchangeably with + * `.throw`. + * + * @name throw + * @alias throws + * @alias Throw + * @param {Error|ErrorConstructor} errorLike + * @param {String|RegExp} errMsgMatcher error message + * @param {String} msg _optional_ + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @returns error for chaining (null if no error) + * @namespace BDD + * @api public + */ + + function assertThrows (errorLike, errMsgMatcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , ssfi = flag(this, 'ssfi') + , flagMsg = flag(this, 'message') + , negate = flag(this, 'negate') || false; + new Assertion(obj, flagMsg, ssfi, true).is.a('function'); + + if (errorLike instanceof RegExp || typeof errorLike === 'string') { + errMsgMatcher = errorLike; + errorLike = null; + } + + var caughtErr; + try { + obj(); + } catch (err) { + caughtErr = err; + } + + // If we have the negate flag enabled and at least one valid argument it means we do expect an error + // but we want it to match a given set of criteria + var everyArgIsUndefined = errorLike === undefined && errMsgMatcher === undefined; + + // If we've got the negate flag enabled and both args, we should only fail if both aren't compatible + // See Issue #551 and PR #683@GitHub + var everyArgIsDefined = Boolean(errorLike && errMsgMatcher); + var errorLikeFail = false; + var errMsgMatcherFail = false; + + // Checking if error was thrown + if (everyArgIsUndefined || !everyArgIsUndefined && !negate) { + // We need this to display results correctly according to their types + var errorLikeString = 'an error'; + if (errorLike instanceof Error) { + errorLikeString = '#{exp}'; + } else if (errorLike) { + errorLikeString = _.checkError.getConstructorName(errorLike); + } + + this.assert( + caughtErr + , 'expected #{this} to throw ' + errorLikeString + , 'expected #{this} to not throw an error but #{act} was thrown' + , errorLike && errorLike.toString() + , (caughtErr instanceof Error ? + caughtErr.toString() : (typeof caughtErr === 'string' ? caughtErr : caughtErr && + _.checkError.getConstructorName(caughtErr))) + ); + } + + if (errorLike && caughtErr) { + // We should compare instances only if `errorLike` is an instance of `Error` + if (errorLike instanceof Error) { + var isCompatibleInstance = _.checkError.compatibleInstance(caughtErr, errorLike); + + if (isCompatibleInstance === negate) { + // These checks were created to ensure we won't fail too soon when we've got both args and a negate + // See Issue #551 and PR #683@GitHub + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr && !negate ? ' but #{act} was thrown' : '') + , errorLike.toString() + , caughtErr.toString() + ); + } + } + } + + var isCompatibleConstructor = _.checkError.compatibleConstructor(caughtErr, errorLike); + if (isCompatibleConstructor === negate) { + if (everyArgIsDefined && negate) { + errorLikeFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + } + } + + if (caughtErr && errMsgMatcher !== undefined && errMsgMatcher !== null) { + // Here we check compatible messages + var placeholder = 'including'; + if (errMsgMatcher instanceof RegExp) { + placeholder = 'matching' + } + + var isCompatibleMessage = _.checkError.compatibleMessage(caughtErr, errMsgMatcher); + if (isCompatibleMessage === negate) { + if (everyArgIsDefined && negate) { + errMsgMatcherFail = true; + } else { + this.assert( + negate + , 'expected #{this} to throw error ' + placeholder + ' #{exp} but got #{act}' + , 'expected #{this} to throw error not ' + placeholder + ' #{exp}' + , errMsgMatcher + , _.checkError.getMessage(caughtErr) + ); + } + } + } + + // If both assertions failed and both should've matched we throw an error + if (errorLikeFail && errMsgMatcherFail) { + this.assert( + negate + , 'expected #{this} to throw #{exp} but #{act} was thrown' + , 'expected #{this} to not throw #{exp}' + (caughtErr ? ' but #{act} was thrown' : '') + , (errorLike instanceof Error ? errorLike.toString() : errorLike && _.checkError.getConstructorName(errorLike)) + , (caughtErr instanceof Error ? caughtErr.toString() : caughtErr && _.checkError.getConstructorName(caughtErr)) + ); + } + + flag(this, 'object', caughtErr); + }; + + Assertion.addMethod('throw', assertThrows); + Assertion.addMethod('throws', assertThrows); + Assertion.addMethod('Throw', assertThrows); + + /** + * ### .respondTo(method[, msg]) + * + * When the target is a non-function object, `.respondTo` asserts that the + * target has a method with the given name `method`. The method can be own or + * inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.respondTo('meow'); + * + * When the target is a function, `.respondTo` asserts that the target's + * `prototype` property has a method with the given name `method`. Again, the + * method can be own or inherited, and it can be enumerable or non-enumerable. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(Cat).to.respondTo('meow'); + * + * Add `.itself` earlier in the chain to force `.respondTo` to treat the + * target as a non-function object, even if it's a function. Thus, it asserts + * that the target has a method with the given name `method`, rather than + * asserting that the target's `prototype` property has a method with the + * given name `method`. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * When not adding `.itself`, it's important to check the target's type before + * using `.respondTo`. See the `.a` doc for info on checking a target's type. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * + * expect(new Cat()).to.be.an('object').that.respondsTo('meow'); + * + * Add `.not` earlier in the chain to negate `.respondTo`. + * + * function Dog () {} + * Dog.prototype.bark = function () {}; + * + * expect(new Dog()).to.not.respondTo('meow'); + * + * `.respondTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect({}).to.respondTo('meow', 'nooo why fail??'); + * expect({}, 'nooo why fail??').to.respondTo('meow'); + * + * The alias `.respondsTo` can be used interchangeably with `.respondTo`. + * + * @name respondTo + * @alias respondsTo + * @param {String} method + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function respondTo (method, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , itself = flag(this, 'itself') + , context = ('function' === typeof obj && !itself) + ? obj.prototype[method] + : obj[method]; + + this.assert( + 'function' === typeof context + , 'expected #{this} to respond to ' + _.inspect(method) + , 'expected #{this} to not respond to ' + _.inspect(method) + ); + } + + Assertion.addMethod('respondTo', respondTo); + Assertion.addMethod('respondsTo', respondTo); + + /** + * ### .itself + * + * Forces all `.respondTo` assertions that follow in the chain to behave as if + * the target is a non-function object, even if it's a function. Thus, it + * causes `.respondTo` to assert that the target has a method with the given + * name, rather than asserting that the target's `prototype` property has a + * method with the given name. + * + * function Cat () {} + * Cat.prototype.meow = function () {}; + * Cat.hiss = function () {}; + * + * expect(Cat).itself.to.respondTo('hiss').but.not.respondTo('meow'); + * + * @name itself + * @namespace BDD + * @api public + */ + + Assertion.addProperty('itself', function () { + flag(this, 'itself', true); + }); + + /** + * ### .satisfy(matcher[, msg]) + * + * Invokes the given `matcher` function with the target being passed as the + * first argument, and asserts that the value returned is truthy. + * + * expect(1).to.satisfy(function(num) { + * return num > 0; + * }); + * + * Add `.not` earlier in the chain to negate `.satisfy`. + * + * expect(1).to.not.satisfy(function(num) { + * return num > 2; + * }); + * + * `.satisfy` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1).to.satisfy(function(num) { + * return num > 2; + * }, 'nooo why fail??'); + * + * expect(1, 'nooo why fail??').to.satisfy(function(num) { + * return num > 2; + * }); + * + * The alias `.satisfies` can be used interchangeably with `.satisfy`. + * + * @name satisfy + * @alias satisfies + * @param {Function} matcher + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function satisfy (matcher, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object'); + var result = matcher(obj); + this.assert( + result + , 'expected #{this} to satisfy ' + _.objDisplay(matcher) + , 'expected #{this} to not satisfy' + _.objDisplay(matcher) + , flag(this, 'negate') ? false : true + , result + ); + } + + Assertion.addMethod('satisfy', satisfy); + Assertion.addMethod('satisfies', satisfy); + + /** + * ### .closeTo(expected, delta[, msg]) + * + * Asserts that the target is a number that's within a given +/- `delta` range + * of the given number `expected`. However, it's often best to assert that the + * target is equal to its expected value. + * + * // Recommended + * expect(1.5).to.equal(1.5); + * + * // Not recommended + * expect(1.5).to.be.closeTo(1, 0.5); + * expect(1.5).to.be.closeTo(2, 0.5); + * expect(1.5).to.be.closeTo(1, 1); + * + * Add `.not` earlier in the chain to negate `.closeTo`. + * + * expect(1.5).to.equal(1.5); // Recommended + * expect(1.5).to.not.be.closeTo(3, 1); // Not recommended + * + * `.closeTo` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect(1.5).to.be.closeTo(3, 1, 'nooo why fail??'); + * expect(1.5, 'nooo why fail??').to.be.closeTo(3, 1); + * + * The alias `.approximately` can be used interchangeably with `.closeTo`. + * + * @name closeTo + * @alias approximately + * @param {Number} expected + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function closeTo(expected, delta, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).is.a('number'); + if (typeof expected !== 'number' || typeof delta !== 'number') { + flagMsg = flagMsg ? flagMsg + ': ' : ''; + throw new AssertionError( + flagMsg + 'the arguments to closeTo or approximately must be numbers', + undefined, + ssfi + ); + } + + this.assert( + Math.abs(obj - expected) <= delta + , 'expected #{this} to be close to ' + expected + ' +/- ' + delta + , 'expected #{this} not to be close to ' + expected + ' +/- ' + delta + ); + } + + Assertion.addMethod('closeTo', closeTo); + Assertion.addMethod('approximately', closeTo); + + // Note: Duplicates are ignored if testing for inclusion instead of sameness. + function isSubsetOf(subset, superset, cmp, contains, ordered) { + if (!contains) { + if (subset.length !== superset.length) return false; + superset = superset.slice(); + } + + return subset.every(function(elem, idx) { + if (ordered) return cmp ? cmp(elem, superset[idx]) : elem === superset[idx]; + + if (!cmp) { + var matchIdx = superset.indexOf(elem); + if (matchIdx === -1) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + } + + return superset.some(function(elem2, matchIdx) { + if (!cmp(elem, elem2)) return false; + + // Remove match from superset so not counted twice if duplicate in subset. + if (!contains) superset.splice(matchIdx, 1); + return true; + }); + }); + } + + /** + * ### .members(set[, msg]) + * + * Asserts that the target array has the same members as the given array + * `set`. + * + * expect([1, 2, 3]).to.have.members([2, 1, 3]); + * expect([1, 2, 2]).to.have.members([2, 1, 2]); + * + * By default, members are compared using strict (`===`) equality. Add `.deep` + * earlier in the chain to use deep equality instead. See the `deep-eql` + * project page for info on the deep equality algorithm: + * https://github.com/chaijs/deep-eql. + * + * // Target array deeply (but not strictly) has member `{a: 1}` + * expect([{a: 1}]).to.have.deep.members([{a: 1}]); + * expect([{a: 1}]).to.not.have.members([{a: 1}]); + * + * By default, order doesn't matter. Add `.ordered` earlier in the chain to + * require that members appear in the same order. + * + * expect([1, 2, 3]).to.have.ordered.members([1, 2, 3]); + * expect([1, 2, 3]).to.have.members([2, 1, 3]) + * .but.not.ordered.members([2, 1, 3]); + * + * By default, both arrays must be the same size. Add `.include` earlier in + * the chain to require that the target's members be a superset of the + * expected members. Note that duplicates are ignored in the subset when + * `.include` is added. + * + * // Target array is a superset of [1, 2] but not identical + * expect([1, 2, 3]).to.include.members([1, 2]); + * expect([1, 2, 3]).to.not.have.members([1, 2]); + * + * // Duplicates in the subset are ignored + * expect([1, 2, 3]).to.include.members([1, 2, 2, 2]); + * + * `.deep`, `.ordered`, and `.include` can all be combined. However, if + * `.include` and `.ordered` are combined, the ordering begins at the start of + * both arrays. + * + * expect([{a: 1}, {b: 2}, {c: 3}]) + * .to.include.deep.ordered.members([{a: 1}, {b: 2}]) + * .but.not.include.deep.ordered.members([{b: 2}, {c: 3}]); + * + * Add `.not` earlier in the chain to negate `.members`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the target array doesn't have all of the same members as + * the given array `set` but may or may not have some of them. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * expect([1, 2]).to.not.include(3).and.not.include(4); // Recommended + * expect([1, 2]).to.not.have.members([3, 4]); // Not recommended + * + * `.members` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. + * + * expect([1, 2]).to.have.members([1, 2, 3], 'nooo why fail??'); + * expect([1, 2], 'nooo why fail??').to.have.members([1, 2, 3]); + * + * @name members + * @param {Array} set + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + Assertion.addMethod('members', function (subset, msg) { + if (msg) flag(this, 'message', msg); + var obj = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + + new Assertion(obj, flagMsg, ssfi, true).to.be.an('array'); + new Assertion(subset, flagMsg, ssfi, true).to.be.an('array'); + + var contains = flag(this, 'contains'); + var ordered = flag(this, 'ordered'); + + var subject, failMsg, failNegateMsg; + + if (contains) { + subject = ordered ? 'an ordered superset' : 'a superset'; + failMsg = 'expected #{this} to be ' + subject + ' of #{exp}'; + failNegateMsg = 'expected #{this} to not be ' + subject + ' of #{exp}'; + } else { + subject = ordered ? 'ordered members' : 'members'; + failMsg = 'expected #{this} to have the same ' + subject + ' as #{exp}'; + failNegateMsg = 'expected #{this} to not have the same ' + subject + ' as #{exp}'; + } + + var cmp = flag(this, 'deep') ? _.eql : undefined; + + this.assert( + isSubsetOf(subset, obj, cmp, contains, ordered) + , failMsg + , failNegateMsg + , subset + , obj + , true + ); + }); + + /** + * ### .oneOf(list[, msg]) + * + * Asserts that the target is a member of the given array `list`. However, + * it's often best to assert that the target is equal to its expected value. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.be.oneOf([1, 2, 3]); // Not recommended + * + * Comparisons are performed using strict (`===`) equality. + * + * Add `.not` earlier in the chain to negate `.oneOf`. + * + * expect(1).to.equal(1); // Recommended + * expect(1).to.not.be.oneOf([2, 3, 4]); // Not recommended + * + * `.oneOf` accepts an optional `msg` argument which is a custom error message + * to show when the assertion fails. The message can also be given as the + * second argument to `expect`. + * + * expect(1).to.be.oneOf([2, 3, 4], 'nooo why fail??'); + * expect(1, 'nooo why fail??').to.be.oneOf([2, 3, 4]); + * + * @name oneOf + * @param {Array<*>} list + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function oneOf (list, msg) { + if (msg) flag(this, 'message', msg); + var expected = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(list, flagMsg, ssfi, true).to.be.an('array'); + + this.assert( + list.indexOf(expected) > -1 + , 'expected #{this} to be one of #{exp}' + , 'expected #{this} to not be one of #{exp}' + , list + , expected + ); + } + + Assertion.addMethod('oneOf', oneOf); + + /** + * ### .change(subject[, prop[, msg]]) + * + * When one argument is provided, `.change` asserts that the given function + * `subject` returns a different value when it's invoked before the target + * function compared to when it's invoked afterward. However, it's often best + * to assert that `subject` is equal to its expected value. + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * // Recommended + * expect(getDots()).to.equal(''); + * addDot(); + * expect(getDots()).to.equal('.'); + * + * // Not recommended + * expect(addDot).to.change(getDots); + * + * When two arguments are provided, `.change` asserts that the value of the + * given object `subject`'s `prop` property is different before invoking the + * target function compared to afterward. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * // Recommended + * expect(myObj).to.have.property('dots', ''); + * addDot(); + * expect(myObj).to.have.property('dots', '.'); + * + * // Not recommended + * expect(addDot).to.change(myObj, 'dots'); + * + * Strict (`===`) equality is used to compare before and after values. + * + * Add `.not` earlier in the chain to negate `.change`. + * + * var dots = '' + * , noop = function () {} + * , getDots = function () { return dots; }; + * + * expect(noop).to.not.change(getDots); + * + * var myObj = {dots: ''} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'dots'); + * + * `.change` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {dots: ''} + * , addDot = function () { myObj.dots += '.'; }; + * + * expect(addDot).to.not.change(myObj, 'dots', 'nooo why fail??'); + * + * var dots = '' + * , addDot = function () { dots += '.'; } + * , getDots = function () { return dots; }; + * + * expect(addDot, 'nooo why fail??').to.not.change(getDots); + * + * `.change` also causes all `.by` assertions that follow in the chain to + * assert how much a numeric subject was increased or decreased by. However, + * it's dangerous to use `.change.by`. The problem is that it creates + * uncertain expectations by asserting that the subject either increases by + * the given delta, or that it decreases by the given delta. It's often best + * to identify the exact output that's expected, and then write an assertion + * that only accepts that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * The alias `.changes` can be used interchangeably with `.change`. + * + * @name change + * @alias changes + * @param {String} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertChanges (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + // This gets flagged because of the .by(delta) assertion + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'change'); + flag(this, 'realDelta', final !== initial); + + this.assert( + initial !== final + , 'expected ' + msgObj + ' to change' + , 'expected ' + msgObj + ' to not change' + ); + } + + Assertion.addMethod('change', assertChanges); + Assertion.addMethod('changes', assertChanges); + + /** + * ### .increase(subject[, prop[, msg]]) + * + * When one argument is provided, `.increase` asserts that the given function + * `subject` returns a greater number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.increase` also + * causes all `.by` assertions that follow in the chain to assert how much + * greater of a number is returned. It's often best to assert that the return + * value increased by the expected amount, rather than asserting it increased + * by any amount. + * + * var val = 1 + * , addTwo = function () { val += 2; } + * , getVal = function () { return val; }; + * + * expect(addTwo).to.increase(getVal).by(2); // Recommended + * expect(addTwo).to.increase(getVal); // Not recommended + * + * When two arguments are provided, `.increase` asserts that the value of the + * given object `subject`'s `prop` property is greater after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.increase(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.increase`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either decreases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to decrease, it's often best to assert that it + * decreased by the expected amount. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.not.increase(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.increase(myObj, 'val'); // Not recommended + * + * `.increase` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.increase(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.increase(getVal); + * + * The alias `.increases` can be used interchangeably with `.increase`. + * + * @name increase + * @alias increases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertIncreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'increase'); + flag(this, 'realDelta', final - initial); + + this.assert( + final - initial > 0 + , 'expected ' + msgObj + ' to increase' + , 'expected ' + msgObj + ' to not increase' + ); + } + + Assertion.addMethod('increase', assertIncreases); + Assertion.addMethod('increases', assertIncreases); + + /** + * ### .decrease(subject[, prop[, msg]]) + * + * When one argument is provided, `.decrease` asserts that the given function + * `subject` returns a lesser number when it's invoked after invoking the + * target function compared to when it's invoked beforehand. `.decrease` also + * causes all `.by` assertions that follow in the chain to assert how much + * lesser of a number is returned. It's often best to assert that the return + * value decreased by the expected amount, rather than asserting it decreased + * by any amount. + * + * var val = 1 + * , subtractTwo = function () { val -= 2; } + * , getVal = function () { return val; }; + * + * expect(subtractTwo).to.decrease(getVal).by(2); // Recommended + * expect(subtractTwo).to.decrease(getVal); // Not recommended + * + * When two arguments are provided, `.decrease` asserts that the value of the + * given object `subject`'s `prop` property is lesser after invoking the + * target function compared to beforehand. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.decrease(myObj, 'val'); // Not recommended + * + * Add `.not` earlier in the chain to negate `.decrease`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either increases, or that it stays the same. + * It's often best to identify the exact output that's expected, and then + * write an assertion that only accepts that exact output. + * + * When the subject is expected to increase, it's often best to assert that it + * increased by the expected amount. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.not.decrease(myObj, 'val'); // Not recommended + * + * When the subject is expected to stay the same, it's often best to assert + * exactly that. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.not.change(myObj, 'val'); // Recommended + * expect(noop).to.not.decrease(myObj, 'val'); // Not recommended + * + * `.decrease` accepts an optional `msg` argument which is a custom error + * message to show when the assertion fails. The message can also be given as + * the second argument to `expect`. When not providing two arguments, always + * use the second form. + * + * var myObj = {val: 1} + * , noop = function () {}; + * + * expect(noop).to.decrease(myObj, 'val', 'nooo why fail??'); + * + * var val = 1 + * , noop = function () {} + * , getVal = function () { return val; }; + * + * expect(noop, 'nooo why fail??').to.decrease(getVal); + * + * The alias `.decreases` can be used interchangeably with `.decrease`. + * + * @name decrease + * @alias decreases + * @param {String|Function} subject + * @param {String} prop name _optional_ + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDecreases (subject, prop, msg) { + if (msg) flag(this, 'message', msg); + var fn = flag(this, 'object') + , flagMsg = flag(this, 'message') + , ssfi = flag(this, 'ssfi'); + new Assertion(fn, flagMsg, ssfi, true).is.a('function'); + + var initial; + if (!prop) { + new Assertion(subject, flagMsg, ssfi, true).is.a('function'); + initial = subject(); + } else { + new Assertion(subject, flagMsg, ssfi, true).to.have.property(prop); + initial = subject[prop]; + } + + // Make sure that the target is a number + new Assertion(initial, flagMsg, ssfi, true).is.a('number'); + + fn(); + + var final = prop === undefined || prop === null ? subject() : subject[prop]; + var msgObj = prop === undefined || prop === null ? initial : '.' + prop; + + flag(this, 'deltaMsgObj', msgObj); + flag(this, 'initialDeltaValue', initial); + flag(this, 'finalDeltaValue', final); + flag(this, 'deltaBehavior', 'decrease'); + flag(this, 'realDelta', initial - final); + + this.assert( + final - initial < 0 + , 'expected ' + msgObj + ' to decrease' + , 'expected ' + msgObj + ' to not decrease' + ); + } + + Assertion.addMethod('decrease', assertDecreases); + Assertion.addMethod('decreases', assertDecreases); + + /** + * ### .by(delta[, msg]) + * + * When following an `.increase` assertion in the chain, `.by` asserts that + * the subject of the `.increase` assertion increased by the given `delta`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * When following a `.decrease` assertion in the chain, `.by` asserts that the + * subject of the `.decrease` assertion decreased by the given `delta`. + * + * var myObj = {val: 1} + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); + * + * When following a `.change` assertion in the chain, `.by` asserts that the + * subject of the `.change` assertion either increased or decreased by the + * given `delta`. However, it's dangerous to use `.change.by`. The problem is + * that it creates uncertain expectations. It's often best to identify the + * exact output that's expected, and then write an assertion that only accepts + * that exact output. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; } + * , subtractTwo = function () { myObj.val -= 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(2); // Recommended + * expect(addTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * expect(subtractTwo).to.decrease(myObj, 'val').by(2); // Recommended + * expect(subtractTwo).to.change(myObj, 'val').by(2); // Not recommended + * + * Add `.not` earlier in the chain to negate `.by`. However, it's often best + * to assert that the subject changed by its expected delta, rather than + * asserting that it didn't change by one of countless unexpected deltas. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * // Recommended + * expect(addTwo).to.increase(myObj, 'val').by(2); + * + * // Not recommended + * expect(addTwo).to.increase(myObj, 'val').but.not.by(3); + * + * `.by` accepts an optional `msg` argument which is a custom error message to + * show when the assertion fails. The message can also be given as the second + * argument to `expect`. + * + * var myObj = {val: 1} + * , addTwo = function () { myObj.val += 2; }; + * + * expect(addTwo).to.increase(myObj, 'val').by(3, 'nooo why fail??'); + * expect(addTwo, 'nooo why fail??').to.increase(myObj, 'val').by(3); + * + * @name by + * @param {Number} delta + * @param {String} msg _optional_ + * @namespace BDD + * @api public + */ + + function assertDelta(delta, msg) { + if (msg) flag(this, 'message', msg); + + var msgObj = flag(this, 'deltaMsgObj'); + var initial = flag(this, 'initialDeltaValue'); + var final = flag(this, 'finalDeltaValue'); + var behavior = flag(this, 'deltaBehavior'); + var realDelta = flag(this, 'realDelta'); + + var expression; + if (behavior === 'change') { + expression = Math.abs(final - initial) === Math.abs(delta); + } else { + expression = realDelta === Math.abs(delta); + } + + this.assert( + expression + , 'expected ' + msgObj + ' to ' + behavior + ' by ' + delta + , 'expected ' + msgObj + ' to not ' + behavior + ' by ' + delta + ); + } + + Assertion.addMethod('by', assertDelta); + + /** + * ### .extensible + * + * Asserts that the target is extensible, which means that new properties can + * be added to it. Primitives are never extensible. + * + * expect({a: 1}).to.be.extensible; + * + * Add `.not` earlier in the chain to negate `.extensible`. + * + * var nonExtensibleObject = Object.preventExtensions({}) + * , sealedObject = Object.seal({}) + * , frozenObject = Object.freeze({}); + * + * expect(nonExtensibleObject).to.not.be.extensible; + * expect(sealedObject).to.not.be.extensible; + * expect(frozenObject).to.not.be.extensible; + * expect(1).to.not.be.extensible; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect(1, 'nooo why fail??').to.be.extensible; + * + * @name extensible + * @namespace BDD + * @api public + */ + + Assertion.addProperty('extensible', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a non-extensible ordinary object, simply return false. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible + // The following provides ES6 behavior for ES5 environments. + + var isExtensible = obj === Object(obj) && Object.isExtensible(obj); + + this.assert( + isExtensible + , 'expected #{this} to be extensible' + , 'expected #{this} to not be extensible' + ); + }); + + /** + * ### .sealed + * + * Asserts that the target is sealed, which means that new properties can't be + * added to it, and its existing properties can't be reconfigured or deleted. + * However, it's possible that its existing properties can still be reassigned + * to different values. Primitives are always sealed. + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * expect(sealedObject).to.be.sealed; + * expect(frozenObject).to.be.sealed; + * expect(1).to.be.sealed; + * + * Add `.not` earlier in the chain to negate `.sealed`. + * + * expect({a: 1}).to.not.be.sealed; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.sealed; + * + * @name sealed + * @namespace BDD + * @api public + */ + + Assertion.addProperty('sealed', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a sealed ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed + // The following provides ES6 behavior for ES5 environments. + + var isSealed = obj === Object(obj) ? Object.isSealed(obj) : true; + + this.assert( + isSealed + , 'expected #{this} to be sealed' + , 'expected #{this} to not be sealed' + ); + }); + + /** + * ### .frozen + * + * Asserts that the target is frozen, which means that new properties can't be + * added to it, and its existing properties can't be reassigned to different + * values, reconfigured, or deleted. Primitives are always frozen. + * + * var frozenObject = Object.freeze({}); + * + * expect(frozenObject).to.be.frozen; + * expect(1).to.be.frozen; + * + * Add `.not` earlier in the chain to negate `.frozen`. + * + * expect({a: 1}).to.not.be.frozen; + * + * A custom error message can be given as the second argument to `expect`. + * + * expect({a: 1}, 'nooo why fail??').to.be.frozen; + * + * @name frozen + * @namespace BDD + * @api public + */ + + Assertion.addProperty('frozen', function() { + var obj = flag(this, 'object'); + + // In ES5, if the argument to this method is a primitive, then it will cause a TypeError. + // In ES6, a non-object argument will be treated as if it was a frozen ordinary object, simply return true. + // See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen + // The following provides ES6 behavior for ES5 environments. + + var isFrozen = obj === Object(obj) ? Object.isFrozen(obj) : true; + + this.assert( + isFrozen + , 'expected #{this} to be frozen' + , 'expected #{this} to not be frozen' + ); + }); + + /** + * ### .finite + * + * Asserts that the target is a number, and isn't `NaN` or positive/negative + * `Infinity`. + * + * expect(1).to.be.finite; + * + * Add `.not` earlier in the chain to negate `.finite`. However, it's + * dangerous to do so. The problem is that it creates uncertain expectations + * by asserting that the subject either isn't a number, or that it's `NaN`, or + * that it's positive `Infinity`, or that it's negative `Infinity`. It's often + * best to identify the exact output that's expected, and then write an + * assertion that only accepts that exact output. + * + * When the target isn't expected to be a number, it's often best to assert + * that it's the expected type, rather than asserting that it isn't one of + * many unexpected types. + * + * expect('foo').to.be.a('string'); // Recommended + * expect('foo').to.not.be.finite; // Not recommended + * + * When the target is expected to be `NaN`, it's often best to assert exactly + * that. + * + * expect(NaN).to.be.NaN; // Recommended + * expect(NaN).to.not.be.finite; // Not recommended + * + * When the target is expected to be positive infinity, it's often best to + * assert exactly that. + * + * expect(Infinity).to.equal(Infinity); // Recommended + * expect(Infinity).to.not.be.finite; // Not recommended + * + * When the target is expected to be negative infinity, it's often best to + * assert exactly that. + * + * expect(-Infinity).to.equal(-Infinity); // Recommended + * expect(-Infinity).to.not.be.finite; // Not recommended + * + * A custom error message can be given as the second argument to `expect`. + * + * expect('foo', 'nooo why fail??').to.be.finite; + * + * @name finite + * @namespace BDD + * @api public + */ + + Assertion.addProperty('finite', function(msg) { + var obj = flag(this, 'object'); + + this.assert( + typeof obj === 'number' && isFinite(obj) + , 'expected #{this} to be a finite number' + , 'expected #{this} to not be a finite number' + ); + }); +}; + +},{}],38:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + /*! + * Chai dependencies. + */ + + var Assertion = chai.Assertion + , flag = util.flag; + + /*! + * Module export. + */ + + /** + * ### assert(expression, message) + * + * Write your own test expressions. + * + * assert('foo' !== 'bar', 'foo is not bar'); + * assert(Array.isArray([]), 'empty arrays are arrays'); + * + * @param {Mixed} expression to test for truthiness + * @param {String} message to display on error + * @name assert + * @namespace Assert + * @api public + */ + + var assert = chai.assert = function (express, errmsg) { + var test = new Assertion(null, null, chai.assert, true); + test.assert( + express + , errmsg + , '[ negation message unavailable ]' + ); + }; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. Node.js `assert` module-compatible. + * + * assert.fail(); + * assert.fail("custom error message"); + * assert.fail(1, 2); + * assert.fail(1, 2, "custom error message"); + * assert.fail(1, 2, "custom error message", ">"); + * assert.fail(1, 2, undefined, ">"); + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace Assert + * @api public + */ + + assert.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + // Comply with Node's fail([message]) interface + + message = actual; + actual = undefined; + } + + message = message || 'assert.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, assert.fail); + }; + + /** + * ### .isOk(object, [message]) + * + * Asserts that `object` is truthy. + * + * assert.isOk('everything', 'everything is ok'); + * assert.isOk(false, 'this will fail'); + * + * @name isOk + * @alias ok + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isOk = function (val, msg) { + new Assertion(val, msg, assert.isOk, true).is.ok; + }; + + /** + * ### .isNotOk(object, [message]) + * + * Asserts that `object` is falsy. + * + * assert.isNotOk('everything', 'this will fail'); + * assert.isNotOk(false, 'this will pass'); + * + * @name isNotOk + * @alias notOk + * @param {Mixed} object to test + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotOk = function (val, msg) { + new Assertion(val, msg, assert.isNotOk, true).is.not.ok; + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * assert.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.equal = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.equal, true); + + test.assert( + exp == flag(test, 'object') + , 'expected #{this} to equal #{exp}' + , 'expected #{this} to not equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .notEqual(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * assert.notEqual(3, 4, 'these numbers are not equal'); + * + * @name notEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notEqual = function (act, exp, msg) { + var test = new Assertion(act, msg, assert.notEqual, true); + + test.assert( + exp != flag(test, 'object') + , 'expected #{this} to not equal #{exp}' + , 'expected #{this} to equal #{act}' + , exp + , act + , true + ); + }; + + /** + * ### .strictEqual(actual, expected, [message]) + * + * Asserts strict equality (`===`) of `actual` and `expected`. + * + * assert.strictEqual(true, true, 'these booleans are strictly equal'); + * + * @name strictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.strictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.strictEqual, true).to.equal(exp); + }; + + /** + * ### .notStrictEqual(actual, expected, [message]) + * + * Asserts strict inequality (`!==`) of `actual` and `expected`. + * + * assert.notStrictEqual(3, '3', 'no coercion for strict equality'); + * + * @name notStrictEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notStrictEqual, true).to.not.equal(exp); + }; + + /** + * ### .deepEqual(actual, expected, [message]) + * + * Asserts that `actual` is deeply equal to `expected`. + * + * assert.deepEqual({ tea: 'green' }, { tea: 'green' }); + * + * @name deepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @alias deepStrictEqual + * @namespace Assert + * @api public + */ + + assert.deepEqual = assert.deepStrictEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.deepEqual, true).to.eql(exp); + }; + + /** + * ### .notDeepEqual(actual, expected, [message]) + * + * Assert that `actual` is not deeply equal to `expected`. + * + * assert.notDeepEqual({ tea: 'green' }, { tea: 'jasmine' }); + * + * @name notDeepEqual + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepEqual = function (act, exp, msg) { + new Assertion(act, msg, assert.notDeepEqual, true).to.not.eql(exp); + }; + + /** + * ### .isAbove(valueToCheck, valueToBeAbove, [message]) + * + * Asserts `valueToCheck` is strictly greater than (>) `valueToBeAbove`. + * + * assert.isAbove(5, 2, '5 is strictly greater than 2'); + * + * @name isAbove + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAbove + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAbove = function (val, abv, msg) { + new Assertion(val, msg, assert.isAbove, true).to.be.above(abv); + }; + + /** + * ### .isAtLeast(valueToCheck, valueToBeAtLeast, [message]) + * + * Asserts `valueToCheck` is greater than or equal to (>=) `valueToBeAtLeast`. + * + * assert.isAtLeast(5, 2, '5 is greater or equal to 2'); + * assert.isAtLeast(3, 3, '3 is greater or equal to 3'); + * + * @name isAtLeast + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtLeast + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtLeast = function (val, atlst, msg) { + new Assertion(val, msg, assert.isAtLeast, true).to.be.least(atlst); + }; + + /** + * ### .isBelow(valueToCheck, valueToBeBelow, [message]) + * + * Asserts `valueToCheck` is strictly less than (<) `valueToBeBelow`. + * + * assert.isBelow(3, 6, '3 is strictly less than 6'); + * + * @name isBelow + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeBelow + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBelow = function (val, blw, msg) { + new Assertion(val, msg, assert.isBelow, true).to.be.below(blw); + }; + + /** + * ### .isAtMost(valueToCheck, valueToBeAtMost, [message]) + * + * Asserts `valueToCheck` is less than or equal to (<=) `valueToBeAtMost`. + * + * assert.isAtMost(3, 6, '3 is less than or equal to 6'); + * assert.isAtMost(4, 4, '4 is less than or equal to 4'); + * + * @name isAtMost + * @param {Mixed} valueToCheck + * @param {Mixed} valueToBeAtMost + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isAtMost = function (val, atmst, msg) { + new Assertion(val, msg, assert.isAtMost, true).to.be.most(atmst); + }; + + /** + * ### .isTrue(value, [message]) + * + * Asserts that `value` is true. + * + * var teaServed = true; + * assert.isTrue(teaServed, 'the tea has been served'); + * + * @name isTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isTrue = function (val, msg) { + new Assertion(val, msg, assert.isTrue, true).is['true']; + }; + + /** + * ### .isNotTrue(value, [message]) + * + * Asserts that `value` is not true. + * + * var tea = 'tasty chai'; + * assert.isNotTrue(tea, 'great, time for tea!'); + * + * @name isNotTrue + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotTrue = function (val, msg) { + new Assertion(val, msg, assert.isNotTrue, true).to.not.equal(true); + }; + + /** + * ### .isFalse(value, [message]) + * + * Asserts that `value` is false. + * + * var teaServed = false; + * assert.isFalse(teaServed, 'no tea yet? hmm...'); + * + * @name isFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFalse = function (val, msg) { + new Assertion(val, msg, assert.isFalse, true).is['false']; + }; + + /** + * ### .isNotFalse(value, [message]) + * + * Asserts that `value` is not false. + * + * var tea = 'tasty chai'; + * assert.isNotFalse(tea, 'great, time for tea!'); + * + * @name isNotFalse + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFalse = function (val, msg) { + new Assertion(val, msg, assert.isNotFalse, true).to.not.equal(false); + }; + + /** + * ### .isNull(value, [message]) + * + * Asserts that `value` is null. + * + * assert.isNull(err, 'there was no error'); + * + * @name isNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNull = function (val, msg) { + new Assertion(val, msg, assert.isNull, true).to.equal(null); + }; + + /** + * ### .isNotNull(value, [message]) + * + * Asserts that `value` is not null. + * + * var tea = 'tasty chai'; + * assert.isNotNull(tea, 'great, time for tea!'); + * + * @name isNotNull + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNull = function (val, msg) { + new Assertion(val, msg, assert.isNotNull, true).to.not.equal(null); + }; + + /** + * ### .isNaN + * + * Asserts that value is NaN. + * + * assert.isNaN(NaN, 'NaN is NaN'); + * + * @name isNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNaN = function (val, msg) { + new Assertion(val, msg, assert.isNaN, true).to.be.NaN; + }; + + /** + * ### .isNotNaN + * + * Asserts that value is not NaN. + * + * assert.isNotNaN(4, '4 is not NaN'); + * + * @name isNotNaN + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + assert.isNotNaN = function (val, msg) { + new Assertion(val, msg, assert.isNotNaN, true).not.to.be.NaN; + }; + + /** + * ### .exists + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * assert.exists(foo, 'foo is neither `null` nor `undefined`'); + * + * @name exists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.exists = function (val, msg) { + new Assertion(val, msg, assert.exists, true).to.exist; + }; + + /** + * ### .notExists + * + * Asserts that the target is either `null` or `undefined`. + * + * var bar = null + * , baz; + * + * assert.notExists(bar); + * assert.notExists(baz, 'baz is either null or undefined'); + * + * @name notExists + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notExists = function (val, msg) { + new Assertion(val, msg, assert.notExists, true).to.not.exist; + }; + + /** + * ### .isUndefined(value, [message]) + * + * Asserts that `value` is `undefined`. + * + * var tea; + * assert.isUndefined(tea, 'no tea defined'); + * + * @name isUndefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isUndefined = function (val, msg) { + new Assertion(val, msg, assert.isUndefined, true).to.equal(undefined); + }; + + /** + * ### .isDefined(value, [message]) + * + * Asserts that `value` is not `undefined`. + * + * var tea = 'cup of chai'; + * assert.isDefined(tea, 'tea has been defined'); + * + * @name isDefined + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isDefined = function (val, msg) { + new Assertion(val, msg, assert.isDefined, true).to.not.equal(undefined); + }; + + /** + * ### .isFunction(value, [message]) + * + * Asserts that `value` is a function. + * + * function serveTea() { return 'cup of tea'; }; + * assert.isFunction(serveTea, 'great, we can have tea now'); + * + * @name isFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFunction = function (val, msg) { + new Assertion(val, msg, assert.isFunction, true).to.be.a('function'); + }; + + /** + * ### .isNotFunction(value, [message]) + * + * Asserts that `value` is _not_ a function. + * + * var serveTea = [ 'heat', 'pour', 'sip' ]; + * assert.isNotFunction(serveTea, 'great, we have listed the steps'); + * + * @name isNotFunction + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotFunction = function (val, msg) { + new Assertion(val, msg, assert.isNotFunction, true).to.not.be.a('function'); + }; + + /** + * ### .isObject(value, [message]) + * + * Asserts that `value` is an object of type 'Object' (as revealed by `Object.prototype.toString`). + * _The assertion does not match subclassed objects._ + * + * var selection = { name: 'Chai', serve: 'with spices' }; + * assert.isObject(selection, 'tea selection is an object'); + * + * @name isObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isObject = function (val, msg) { + new Assertion(val, msg, assert.isObject, true).to.be.a('object'); + }; + + /** + * ### .isNotObject(value, [message]) + * + * Asserts that `value` is _not_ an object of type 'Object' (as revealed by `Object.prototype.toString`). + * + * var selection = 'chai' + * assert.isNotObject(selection, 'tea selection is not an object'); + * assert.isNotObject(null, 'null is not an object'); + * + * @name isNotObject + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotObject = function (val, msg) { + new Assertion(val, msg, assert.isNotObject, true).to.not.be.a('object'); + }; + + /** + * ### .isArray(value, [message]) + * + * Asserts that `value` is an array. + * + * var menu = [ 'green', 'chai', 'oolong' ]; + * assert.isArray(menu, 'what kind of tea do we want?'); + * + * @name isArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isArray = function (val, msg) { + new Assertion(val, msg, assert.isArray, true).to.be.an('array'); + }; + + /** + * ### .isNotArray(value, [message]) + * + * Asserts that `value` is _not_ an array. + * + * var menu = 'green|chai|oolong'; + * assert.isNotArray(menu, 'what kind of tea do we want?'); + * + * @name isNotArray + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotArray = function (val, msg) { + new Assertion(val, msg, assert.isNotArray, true).to.not.be.an('array'); + }; + + /** + * ### .isString(value, [message]) + * + * Asserts that `value` is a string. + * + * var teaOrder = 'chai'; + * assert.isString(teaOrder, 'order placed'); + * + * @name isString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isString = function (val, msg) { + new Assertion(val, msg, assert.isString, true).to.be.a('string'); + }; + + /** + * ### .isNotString(value, [message]) + * + * Asserts that `value` is _not_ a string. + * + * var teaOrder = 4; + * assert.isNotString(teaOrder, 'order placed'); + * + * @name isNotString + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotString = function (val, msg) { + new Assertion(val, msg, assert.isNotString, true).to.not.be.a('string'); + }; + + /** + * ### .isNumber(value, [message]) + * + * Asserts that `value` is a number. + * + * var cups = 2; + * assert.isNumber(cups, 'how many cups'); + * + * @name isNumber + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNumber = function (val, msg) { + new Assertion(val, msg, assert.isNumber, true).to.be.a('number'); + }; + + /** + * ### .isNotNumber(value, [message]) + * + * Asserts that `value` is _not_ a number. + * + * var cups = '2 cups please'; + * assert.isNotNumber(cups, 'how many cups'); + * + * @name isNotNumber + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotNumber = function (val, msg) { + new Assertion(val, msg, assert.isNotNumber, true).to.not.be.a('number'); + }; + + /** + * ### .isFinite(value, [message]) + * + * Asserts that `value` is a finite number. Unlike `.isNumber`, this will fail for `NaN` and `Infinity`. + * + * var cups = 2; + * assert.isFinite(cups, 'how many cups'); + * + * assert.isFinite(NaN); // throws + * + * @name isFinite + * @param {Number} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isFinite = function (val, msg) { + new Assertion(val, msg, assert.isFinite, true).to.be.finite; + }; + + /** + * ### .isBoolean(value, [message]) + * + * Asserts that `value` is a boolean. + * + * var teaReady = true + * , teaServed = false; + * + * assert.isBoolean(teaReady, 'is the tea ready'); + * assert.isBoolean(teaServed, 'has tea been served'); + * + * @name isBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isBoolean = function (val, msg) { + new Assertion(val, msg, assert.isBoolean, true).to.be.a('boolean'); + }; + + /** + * ### .isNotBoolean(value, [message]) + * + * Asserts that `value` is _not_ a boolean. + * + * var teaReady = 'yep' + * , teaServed = 'nope'; + * + * assert.isNotBoolean(teaReady, 'is the tea ready'); + * assert.isNotBoolean(teaServed, 'has tea been served'); + * + * @name isNotBoolean + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.isNotBoolean = function (val, msg) { + new Assertion(val, msg, assert.isNotBoolean, true).to.not.be.a('boolean'); + }; + + /** + * ### .typeOf(value, name, [message]) + * + * Asserts that `value`'s type is `name`, as determined by + * `Object.prototype.toString`. + * + * assert.typeOf({ tea: 'chai' }, 'object', 'we have an object'); + * assert.typeOf(['chai', 'jasmine'], 'array', 'we have an array'); + * assert.typeOf('tea', 'string', 'we have a string'); + * assert.typeOf(/tea/, 'regexp', 'we have a regular expression'); + * assert.typeOf(null, 'null', 'we have a null'); + * assert.typeOf(undefined, 'undefined', 'we have an undefined'); + * + * @name typeOf + * @param {Mixed} value + * @param {String} name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.typeOf = function (val, type, msg) { + new Assertion(val, msg, assert.typeOf, true).to.be.a(type); + }; + + /** + * ### .notTypeOf(value, name, [message]) + * + * Asserts that `value`'s type is _not_ `name`, as determined by + * `Object.prototype.toString`. + * + * assert.notTypeOf('tea', 'number', 'strings are not numbers'); + * + * @name notTypeOf + * @param {Mixed} value + * @param {String} typeof name + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notTypeOf = function (val, type, msg) { + new Assertion(val, msg, assert.notTypeOf, true).to.not.be.a(type); + }; + + /** + * ### .instanceOf(object, constructor, [message]) + * + * Asserts that `value` is an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new Tea('chai'); + * + * assert.instanceOf(chai, Tea, 'chai is an instance of tea'); + * + * @name instanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.instanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.instanceOf, true).to.be.instanceOf(type); + }; + + /** + * ### .notInstanceOf(object, constructor, [message]) + * + * Asserts `value` is not an instance of `constructor`. + * + * var Tea = function (name) { this.name = name; } + * , chai = new String('chai'); + * + * assert.notInstanceOf(chai, Tea, 'chai is not an instance of tea'); + * + * @name notInstanceOf + * @param {Object} object + * @param {Constructor} constructor + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInstanceOf = function (val, type, msg) { + new Assertion(val, msg, assert.notInstanceOf, true) + .to.not.be.instanceOf(type); + }; + + /** + * ### .include(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.include([1,2,3], 2, 'array contains value'); + * assert.include('foobar', 'foo', 'string contains substring'); + * assert.include({ foo: 'bar', hello: 'universe' }, { foo: 'bar' }, 'object contains property'); + * + * Strict equality (===) is used. When asserting the inclusion of a value in + * an array, the array is searched for an element that's strictly equal to the + * given value. When asserting a subset of properties in an object, the object + * is searched for the given property keys, checking that each one is present + * and strictly equal to the given property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.include([obj1, obj2], obj1); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1}); + * assert.include({foo: obj1, bar: obj2}, {foo: obj1, bar: obj2}); + * + * @name include + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.include = function (exp, inc, msg) { + new Assertion(exp, msg, assert.include, true).include(inc); + }; + + /** + * ### .notInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array, a substring in a string, or a subset of + * properties in an object. + * + * assert.notInclude([1,2,3], 4, "array doesn't contain value"); + * assert.notInclude('foobar', 'baz', "string doesn't contain substring"); + * assert.notInclude({ foo: 'bar', hello: 'universe' }, { foo: 'baz' }, 'object doesn't contain property'); + * + * Strict equality (===) is used. When asserting the absence of a value in an + * array, the array is searched to confirm the absence of an element that's + * strictly equal to the given value. When asserting a subset of properties in + * an object, the object is searched to confirm that at least one of the given + * property keys is either not present or not strictly equal to the given + * property value. For instance: + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notInclude([obj1, obj2], {a: 1}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.notInclude({foo: obj1, bar: obj2}, {foo: obj1, bar: {b: 2}}); + * + * @name notInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notInclude, true).not.include(inc); + }; + + /** + * ### .deepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` includes `needle`. Can be used to assert the + * inclusion of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.deepInclude([obj1, obj2], {a: 1}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}}); + * assert.deepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 2}}); + * + * @name deepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.deepInclude, true).deep.include(inc); + }; + + /** + * ### .notDeepInclude(haystack, needle, [message]) + * + * Asserts that `haystack` does not include `needle`. Can be used to assert + * the absence of a value in an array or a subset of properties in an object. + * Deep equality is used. + * + * var obj1 = {a: 1} + * , obj2 = {b: 2}; + * assert.notDeepInclude([obj1, obj2], {a: 9}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 9}}); + * assert.notDeepInclude({foo: obj1, bar: obj2}, {foo: {a: 1}, bar: {b: 9}}); + * + * @name notDeepInclude + * @param {Array|String} haystack + * @param {Mixed} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepInclude, true).not.deep.include(inc); + }; + + /** + * ### .nestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.nestedInclude({'.a': {'b': 'x'}}, {'\\.a.[b]': 'x'}); + * assert.nestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'x'}); + * + * @name nestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.nestedInclude, true).nested.include(inc); + }; + + /** + * ### .notNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notNestedInclude({'.a': {'b': 'x'}}, {'\\.a.b': 'y'}); + * assert.notNestedInclude({'a': {'[b]': 'x'}}, {'a.\\[b\\]': 'y'}); + * + * @name notNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedInclude = function (exp, inc, msg) { + new Assertion(exp, msg, assert.notNestedInclude, true) + .not.nested.include(inc); + }; + + /** + * ### .deepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.deepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {x: 1}}); + * assert.deepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {x: 1}}); + * + * @name deepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepNestedInclude, true) + .deep.nested.include(inc); + }; + + /** + * ### .notDeepNestedInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' does not include 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while checking for deep equality. + * Enables the use of dot- and bracket-notation for referencing nested + * properties. + * '[]' and '.' in property names can be escaped using double backslashes. + * + * assert.notDeepNestedInclude({a: {b: [{x: 1}]}}, {'a.b[0]': {y: 1}}) + * assert.notDeepNestedInclude({'.a': {'[b]': {x: 1}}}, {'\\.a.\\[b\\]': {y: 2}}); + * + * @name notDeepNestedInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepNestedInclude, true) + .not.deep.nested.include(inc); + }; + + /** + * ### .ownInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties. + * + * assert.ownInclude({ a: 1 }, { a: 1 }); + * + * @name ownInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.ownInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.ownInclude, true).own.include(inc); + }; + + /** + * ### .notOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties. + * + * Object.prototype.b = 2; + * + * assert.notOwnInclude({ a: 1 }, { b: 2 }); + * + * @name notOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notOwnInclude, true).not.own.include(inc); + }; + + /** + * ### .deepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the inclusion of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.deepOwnInclude({a: {b: 2}}, {a: {b: 2}}); + * + * @name deepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.deepOwnInclude, true) + .deep.own.include(inc); + }; + + /** + * ### .notDeepOwnInclude(haystack, needle, [message]) + * + * Asserts that 'haystack' includes 'needle'. + * Can be used to assert the absence of a subset of properties in an + * object while ignoring inherited properties and checking for deep equality. + * + * assert.notDeepOwnInclude({a: {b: 2}}, {a: {c: 3}}); + * + * @name notDeepOwnInclude + * @param {Object} haystack + * @param {Object} needle + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepOwnInclude = function(exp, inc, msg) { + new Assertion(exp, msg, assert.notDeepOwnInclude, true) + .not.deep.own.include(inc); + }; + + /** + * ### .match(value, regexp, [message]) + * + * Asserts that `value` matches the regular expression `regexp`. + * + * assert.match('foobar', /^foo/, 'regexp matches'); + * + * @name match + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.match = function (exp, re, msg) { + new Assertion(exp, msg, assert.match, true).to.match(re); + }; + + /** + * ### .notMatch(value, regexp, [message]) + * + * Asserts that `value` does not match the regular expression `regexp`. + * + * assert.notMatch('foobar', /^foo/, 'regexp does not match'); + * + * @name notMatch + * @param {Mixed} value + * @param {RegExp} regexp + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notMatch = function (exp, re, msg) { + new Assertion(exp, msg, assert.notMatch, true).to.not.match(re); + }; + + /** + * ### .property(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`. + * + * assert.property({ tea: { green: 'matcha' }}, 'tea'); + * assert.property({ tea: { green: 'matcha' }}, 'toString'); + * + * @name property + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.property = function (obj, prop, msg) { + new Assertion(obj, msg, assert.property, true).to.have.property(prop); + }; + + /** + * ### .notProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property`. + * + * assert.notProperty({ tea: { green: 'matcha' }}, 'coffee'); + * + * @name notProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notProperty, true) + .to.not.have.property(prop); + }; + + /** + * ### .propertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a strict equality check + * (===). + * + * assert.propertyVal({ tea: 'is good' }, 'tea', 'is good'); + * + * @name propertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.propertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.propertyVal, true) + .to.have.property(prop, val); + }; + + /** + * ### .notPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a strict equality check + * (===). + * + * assert.notPropertyVal({ tea: 'is good' }, 'tea', 'is bad'); + * assert.notPropertyVal({ tea: 'is good' }, 'coffee', 'is good'); + * + * @name notPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notPropertyVal, true) + .to.not.have.property(prop, val); + }; + + /** + * ### .deepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property` with a value given by `value`. Uses a deep equality check. + * + * assert.deepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepPropertyVal, true) + .to.have.deep.property(prop, val); + }; + + /** + * ### .notDeepPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct or inherited property named + * by `property` with value given by `value`. Uses a deep equality check. + * + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * + * @name notDeepPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepPropertyVal, true) + .to.not.have.deep.property(prop, val); + }; + + /** + * ### .ownProperty(object, property, [message]) + * + * Asserts that `object` has a direct property named by `property`. Inherited + * properties aren't checked. + * + * assert.ownProperty({ tea: { green: 'matcha' }}, 'tea'); + * + * @name ownProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.ownProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.ownProperty, true) + .to.have.own.property(prop); + }; + + /** + * ### .notOwnProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a direct property named by + * `property`. Inherited properties aren't checked. + * + * assert.notOwnProperty({ tea: { green: 'matcha' }}, 'coffee'); + * assert.notOwnProperty({}, 'toString'); + * + * @name notOwnProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @api public + */ + + assert.notOwnProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notOwnProperty, true) + .to.not.have.own.property(prop); + }; + + /** + * ### .ownPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a strict equality check (===). + * Inherited properties aren't checked. + * + * assert.ownPropertyVal({ coffee: 'is good'}, 'coffee', 'is good'); + * + * @name ownPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.ownPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.ownPropertyVal, true) + .to.have.own.property(prop, value); + }; + + /** + * ### .notOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a strict equality check + * (===). Inherited properties aren't checked. + * + * assert.notOwnPropertyVal({ tea: 'is better'}, 'tea', 'is worse'); + * assert.notOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notOwnPropertyVal, true) + .to.not.have.own.property(prop, value); + }; + + /** + * ### .deepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a direct property named by `property` and a value + * equal to the provided `value`. Uses a deep equality check. Inherited + * properties aren't checked. + * + * assert.deepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'matcha' }); + * + * @name deepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.deepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.deepOwnPropertyVal, true) + .to.have.deep.own.property(prop, value); + }; + + /** + * ### .notDeepOwnPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a direct property named by `property` + * with a value equal to the provided `value`. Uses a deep equality check. + * Inherited properties aren't checked. + * + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { black: 'matcha' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'tea', { green: 'oolong' }); + * assert.notDeepOwnPropertyVal({ tea: { green: 'matcha' } }, 'coffee', { green: 'matcha' }); + * assert.notDeepOwnPropertyVal({}, 'toString', Object.prototype.toString); + * + * @name notDeepOwnPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @api public + */ + + assert.notDeepOwnPropertyVal = function (obj, prop, value, msg) { + new Assertion(obj, msg, assert.notDeepOwnPropertyVal, true) + .to.not.have.deep.own.property(prop, value); + }; + + /** + * ### .nestedProperty(object, property, [message]) + * + * Asserts that `object` has a direct or inherited property named by + * `property`, which can be a string using dot- and bracket-notation for + * nested reference. + * + * assert.nestedProperty({ tea: { green: 'matcha' }}, 'tea.green'); + * + * @name nestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.nestedProperty, true) + .to.have.nested.property(prop); + }; + + /** + * ### .notNestedProperty(object, property, [message]) + * + * Asserts that `object` does _not_ have a property named by `property`, which + * can be a string using dot- and bracket-notation for nested reference. The + * property cannot exist on the object nor anywhere in its prototype chain. + * + * assert.notNestedProperty({ tea: { green: 'matcha' }}, 'tea.oolong'); + * + * @name notNestedProperty + * @param {Object} object + * @param {String} property + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedProperty = function (obj, prop, msg) { + new Assertion(obj, msg, assert.notNestedProperty, true) + .to.not.have.nested.property(prop); + }; + + /** + * ### .nestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a strict equality check (===). + * + * assert.nestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'matcha'); + * + * @name nestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.nestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.nestedPropertyVal, true) + .to.have.nested.property(prop, val); + }; + + /** + * ### .notNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a strict equality check (===). + * + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'tea.green', 'konacha'); + * assert.notNestedPropertyVal({ tea: { green: 'matcha' }}, 'coffee.green', 'matcha'); + * + * @name notNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notNestedPropertyVal, true) + .to.not.have.nested.property(prop, val); + }; + + /** + * ### .deepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` has a property named by `property` with a value given + * by `value`. `property` can use dot- and bracket-notation for nested + * reference. Uses a deep equality check. + * + * assert.deepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yum' }); + * + * @name deepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.deepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.deepNestedPropertyVal, true) + .to.have.deep.nested.property(prop, val); + }; + + /** + * ### .notDeepNestedPropertyVal(object, property, value, [message]) + * + * Asserts that `object` does _not_ have a property named by `property` with + * value given by `value`. `property` can use dot- and bracket-notation for + * nested reference. Uses a deep equality check. + * + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { oolong: 'yum' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.green', { matcha: 'yuck' }); + * assert.notDeepNestedPropertyVal({ tea: { green: { matcha: 'yum' } } }, 'tea.black', { matcha: 'yum' }); + * + * @name notDeepNestedPropertyVal + * @param {Object} object + * @param {String} property + * @param {Mixed} value + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notDeepNestedPropertyVal = function (obj, prop, val, msg) { + new Assertion(obj, msg, assert.notDeepNestedPropertyVal, true) + .to.not.have.deep.nested.property(prop, val); + } + + /** + * ### .lengthOf(object, length, [message]) + * + * Asserts that `object` has a `length` or `size` with the expected value. + * + * assert.lengthOf([1,2,3], 3, 'array has length of 3'); + * assert.lengthOf('foobar', 6, 'string has length of 6'); + * assert.lengthOf(new Set([1,2,3]), 3, 'set has size of 3'); + * assert.lengthOf(new Map([['a',1],['b',2],['c',3]]), 3, 'map has size of 3'); + * + * @name lengthOf + * @param {Mixed} object + * @param {Number} length + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.lengthOf = function (exp, len, msg) { + new Assertion(exp, msg, assert.lengthOf, true).to.have.lengthOf(len); + }; + + /** + * ### .hasAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'iDontExist', 'baz']); + * assert.hasAnyKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, iDontExist: 99, baz: 1337}); + * assert.hasAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAnyKeys(new Set([{foo: 'bar'}, 'anotherKey']), [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAnyKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyKeys, true).to.have.any.keys(keys); + } + + /** + * ### .hasAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.hasAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337]); + * assert.hasAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.hasAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name hasAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllKeys, true).to.have.all.keys(keys); + } + + /** + * ### .containsAllKeys(object, [keys], [message]) + * + * Asserts that `object` has all of the `keys` provided but may have more keys not listed. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, ['foo', 'bar', 'baz']); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, baz: 1337}); + * assert.containsAllKeys({foo: 1, bar: 2, baz: 3}, {foo: 30, bar: 99, baz: 1337}); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}]); + * assert.containsAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{foo: 1}, 'key']); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}]); + * assert.containsAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{foo: 'bar'}, 'anotherKey']); + * + * @name containsAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllKeys, true) + .to.contain.all.keys(keys); + } + + /** + * ### .doesNotHaveAnyKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAnyKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAnyKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAnyKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAnyKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyKeys, true) + .to.not.have.any.keys(keys); + } + + /** + * ### .doesNotHaveAllKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, ['one', 'two', 'example']); + * assert.doesNotHaveAllKeys({foo: 1, bar: 2, baz: 3}, {one: 1, two: 2, example: 'foo'}); + * assert.doesNotHaveAllKeys(new Map([[{foo: 1}, 'bar'], ['key', 'value']]), [{one: 'two'}, 'example']); + * assert.doesNotHaveAllKeys(new Set([{foo: 'bar'}, 'anotherKey'], [{one: 'two'}, 'example']); + * + * @name doesNotHaveAllKeys + * @param {Mixed} object + * @param {String[]} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllKeys, true) + .to.not.have.all.keys(keys); + } + + /** + * ### .hasAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {three: 'three'}]); + * assert.hasAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name doesNotHaveAllKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAnyDeepKeys, true) + .to.have.any.deep.keys(keys); + } + + /** + * ### .hasAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has all and only all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne']]), {one: 'one'}); + * assert.hasAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.hasAllDeepKeys(new Set([{one: 'one'}]), {one: 'one'}); + * assert.hasAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name hasAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.hasAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.hasAllDeepKeys, true) + .to.have.all.deep.keys(keys); + } + + /** + * ### .containsAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` contains all of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {one: 'one'}); + * assert.containsAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{one: 'one'}, {two: 'two'}]); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {one: 'one'}); + * assert.containsAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {two: 'two'}]); + * + * @name containsAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.containsAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.containsAllDeepKeys, true) + .to.contain.all.deep.keys(keys); + } + + /** + * ### .doesNotHaveAnyDeepKeys(object, [keys], [message]) + * + * Asserts that `object` has none of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAnyDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAnyDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{twenty: 'twenty'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAnyDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAnyDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAnyDeepKeys, true) + .to.not.have.any.deep.keys(keys); + } + + /** + * ### .doesNotHaveAllDeepKeys(object, [keys], [message]) + * + * Asserts that `object` does not have at least one of the `keys` provided. + * Since Sets and Maps can have objects as keys you can use this assertion to perform + * a deep comparison. + * You can also provide a single object instead of a `keys` array and its keys + * will be used as the expected set of keys. + * + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [1, 2]]), {thisDoesNot: 'exist'}); + * assert.doesNotHaveAllDeepKeys(new Map([[{one: 'one'}, 'valueOne'], [{two: 'two'}, 'valueTwo']]), [{twenty: 'twenty'}, {one: 'one'}]); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), {twenty: 'twenty'}); + * assert.doesNotHaveAllDeepKeys(new Set([{one: 'one'}, {two: 'two'}]), [{one: 'one'}, {fifty: 'fifty'}]); + * + * @name doesNotHaveAllDeepKeys + * @param {Mixed} object + * @param {Array|Object} keys + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.doesNotHaveAllDeepKeys = function (obj, keys, msg) { + new Assertion(obj, msg, assert.doesNotHaveAllDeepKeys, true) + .to.not.have.all.deep.keys(keys); + } + + /** + * ### .throws(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will have a + * message matching `errMsgMatcher`. + * + * assert.throws(fn, 'Error thrown must have this msg'); + * assert.throws(fn, /Error thrown must have a msg that matches this/); + * assert.throws(fn, ReferenceError); + * assert.throws(fn, errorInstance); + * assert.throws(fn, ReferenceError, 'Error thrown must be a ReferenceError and have this msg'); + * assert.throws(fn, errorInstance, 'Error thrown must be the same errorInstance and have this msg'); + * assert.throws(fn, ReferenceError, /Error thrown must be a ReferenceError and match this/); + * assert.throws(fn, errorInstance, /Error thrown must be the same errorInstance and match this/); + * + * @name throws + * @alias throw + * @alias Throw + * @param {Function} fn + * @param {ErrorConstructor|Error} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.throws = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + var assertErr = new Assertion(fn, msg, assert.throws, true) + .to.throw(errorLike, errMsgMatcher); + return flag(assertErr, 'object'); + }; + + /** + * ### .doesNotThrow(fn, [errorLike/string/regexp], [string/regexp], [message]) + * + * If `errorLike` is an `Error` constructor, asserts that `fn` will _not_ throw an error that is an + * instance of `errorLike`. + * If `errorLike` is an `Error` instance, asserts that the error thrown is _not_ the same + * instance as `errorLike`. + * If `errMsgMatcher` is provided, it also asserts that the error thrown will _not_ have a + * message matching `errMsgMatcher`. + * + * assert.doesNotThrow(fn, 'Any Error thrown must not have this message'); + * assert.doesNotThrow(fn, /Any Error thrown must not match this/); + * assert.doesNotThrow(fn, Error); + * assert.doesNotThrow(fn, errorInstance); + * assert.doesNotThrow(fn, Error, 'Error must not have this message'); + * assert.doesNotThrow(fn, errorInstance, 'Error must not have this message'); + * assert.doesNotThrow(fn, Error, /Error must not match this/); + * assert.doesNotThrow(fn, errorInstance, /Error must not match this/); + * + * @name doesNotThrow + * @param {Function} fn + * @param {ErrorConstructor} errorLike + * @param {RegExp|String} errMsgMatcher + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Assert + * @api public + */ + + assert.doesNotThrow = function (fn, errorLike, errMsgMatcher, msg) { + if ('string' === typeof errorLike || errorLike instanceof RegExp) { + errMsgMatcher = errorLike; + errorLike = null; + } + + new Assertion(fn, msg, assert.doesNotThrow, true) + .to.not.throw(errorLike, errMsgMatcher); + }; + + /** + * ### .operator(val1, operator, val2, [message]) + * + * Compares two values using `operator`. + * + * assert.operator(1, '<', 2, 'everything is ok'); + * assert.operator(1, '>', 2, 'this will fail'); + * + * @name operator + * @param {Mixed} val1 + * @param {String} operator + * @param {Mixed} val2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.operator = function (val, operator, val2, msg) { + var ok; + switch(operator) { + case '==': + ok = val == val2; + break; + case '===': + ok = val === val2; + break; + case '>': + ok = val > val2; + break; + case '>=': + ok = val >= val2; + break; + case '<': + ok = val < val2; + break; + case '<=': + ok = val <= val2; + break; + case '!=': + ok = val != val2; + break; + case '!==': + ok = val !== val2; + break; + default: + msg = msg ? msg + ': ' : msg; + throw new chai.AssertionError( + msg + 'Invalid operator "' + operator + '"', + undefined, + assert.operator + ); + } + var test = new Assertion(ok, msg, assert.operator, true); + test.assert( + true === flag(test, 'object') + , 'expected ' + util.inspect(val) + ' to be ' + operator + ' ' + util.inspect(val2) + , 'expected ' + util.inspect(val) + ' to not be ' + operator + ' ' + util.inspect(val2) ); + }; + + /** + * ### .closeTo(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.closeTo(1.5, 1, 0.5, 'numbers are close'); + * + * @name closeTo + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.closeTo = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.closeTo, true).to.be.closeTo(exp, delta); + }; + + /** + * ### .approximately(actual, expected, delta, [message]) + * + * Asserts that the target is equal `expected`, to within a +/- `delta` range. + * + * assert.approximately(1.5, 1, 0.5, 'numbers are close'); + * + * @name approximately + * @param {Number} actual + * @param {Number} expected + * @param {Number} delta + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.approximately = function (act, exp, delta, msg) { + new Assertion(act, msg, assert.approximately, true) + .to.be.approximately(exp, delta); + }; + + /** + * ### .sameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * strict equality check (===). + * + * assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); + * + * @name sameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameMembers, true) + .to.have.same.members(set2); + } + + /** + * ### .notSameMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a strict equality check (===). + * + * assert.notSameMembers([ 1, 2, 3 ], [ 5, 1, 3 ], 'not same members'); + * + * @name notSameMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameMembers, true) + .to.not.have.same.members(set2); + } + + /** + * ### .sameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in any order. Uses a + * deep equality check. + * + * assert.sameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { c: 3 }], 'same deep members'); + * + * @name sameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepMembers, true) + .to.have.same.deep.members(set2); + } + + /** + * ### .notSameDeepMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in any order. + * Uses a deep equality check. + * + * assert.notSameDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [{ b: 2 }, { a: 1 }, { f: 5 }], 'not same deep members'); + * + * @name notSameDeepMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepMembers, true) + .to.not.have.same.deep.members(set2); + } + + /** + * ### .sameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a strict equality check (===). + * + * assert.sameOrderedMembers([ 1, 2, 3 ], [ 1, 2, 3 ], 'same ordered members'); + * + * @name sameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameOrderedMembers, true) + .to.have.same.ordered.members(set2); + } + + /** + * ### .notSameOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a strict equality check (===). + * + * assert.notSameOrderedMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'not same ordered members'); + * + * @name notSameOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameOrderedMembers, true) + .to.not.have.same.ordered.members(set2); + } + + /** + * ### .sameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` have the same members in the same order. + * Uses a deep equality check. + * + * assert.sameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { c: 3 } ], 'same deep ordered members'); + * + * @name sameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.sameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.sameDeepOrderedMembers, true) + .to.have.same.deep.ordered.members(set2); + } + + /** + * ### .notSameDeepOrderedMembers(set1, set2, [message]) + * + * Asserts that `set1` and `set2` don't have the same members in the same + * order. Uses a deep equality check. + * + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 }, { z: 5 } ], 'not same deep ordered members'); + * assert.notSameDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { c: 3 } ], 'not same deep ordered members'); + * + * @name notSameDeepOrderedMembers + * @param {Array} set1 + * @param {Array} set2 + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notSameDeepOrderedMembers = function (set1, set2, msg) { + new Assertion(set1, msg, assert.notSameDeepOrderedMembers, true) + .to.not.have.same.deep.ordered.members(set2); + } + + /** + * ### .includeMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.includeMembers([ 1, 2, 3 ], [ 2, 1, 2 ], 'include members'); + * + * @name includeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeMembers, true) + .to.include.members(subset); + } + + /** + * ### .notIncludeMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * strict equality check (===). Duplicates are ignored. + * + * assert.notIncludeMembers([ 1, 2, 3 ], [ 5, 1 ], 'not include members'); + * + * @name notIncludeMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeMembers, true) + .to.not.include.members(subset); + } + + /** + * ### .includeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in any order. Uses a deep + * equality check. Duplicates are ignored. + * + * assert.includeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 }, { b: 2 } ], 'include deep members'); + * + * @name includeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepMembers, true) + .to.include.deep.members(subset); + } + + /** + * ### .notIncludeDeepMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in any order. Uses a + * deep equality check. Duplicates are ignored. + * + * assert.notIncludeDeepMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { f: 5 } ], 'not include deep members'); + * + * @name notIncludeDeepMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepMembers, true) + .to.not.include.deep.members(subset); + } + + /** + * ### .includeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.includeOrderedMembers([ 1, 2, 3 ], [ 1, 2 ], 'include ordered members'); + * + * @name includeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeOrderedMembers, true) + .to.include.ordered.members(subset); + } + + /** + * ### .notIncludeOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a strict equality + * check (===). + * + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 1 ], 'not include ordered members'); + * assert.notIncludeOrderedMembers([ 1, 2, 3 ], [ 2, 3 ], 'not include ordered members'); + * + * @name notIncludeOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeOrderedMembers, true) + .to.not.include.ordered.members(subset); + } + + /** + * ### .includeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` is included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.includeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { b: 2 } ], 'include deep ordered members'); + * + * @name includeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.includeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.includeDeepOrderedMembers, true) + .to.include.deep.ordered.members(subset); + } + + /** + * ### .notIncludeDeepOrderedMembers(superset, subset, [message]) + * + * Asserts that `subset` isn't included in `superset` in the same order + * beginning with the first element in `superset`. Uses a deep equality + * check. + * + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { a: 1 }, { f: 5 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { a: 1 } ], 'not include deep ordered members'); + * assert.notIncludeDeepOrderedMembers([ { a: 1 }, { b: 2 }, { c: 3 } ], [ { b: 2 }, { c: 3 } ], 'not include deep ordered members'); + * + * @name notIncludeDeepOrderedMembers + * @param {Array} superset + * @param {Array} subset + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.notIncludeDeepOrderedMembers = function (superset, subset, msg) { + new Assertion(superset, msg, assert.notIncludeDeepOrderedMembers, true) + .to.not.include.deep.ordered.members(subset); + } + + /** + * ### .oneOf(inList, list, [message]) + * + * Asserts that non-object, non-array value `inList` appears in the flat array `list`. + * + * assert.oneOf(1, [ 2, 1 ], 'Not found in list'); + * + * @name oneOf + * @param {*} inList + * @param {Array<*>} list + * @param {String} message + * @namespace Assert + * @api public + */ + + assert.oneOf = function (inList, list, msg) { + new Assertion(inList, msg, assert.oneOf, true).to.be.oneOf(list); + } + + /** + * ### .changes(function, object, property, [message]) + * + * Asserts that a function changes the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 22 }; + * assert.changes(fn, obj, 'val'); + * + * @name changes + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changes = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changes, true).to.change(obj, prop); + } + + /** + * ### .changesBy(function, object, property, delta, [message]) + * + * Asserts that a function changes the value of a property by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 2 }; + * assert.changesBy(fn, obj, 'val', 2); + * + * @name changesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesBy, true) + .to.change(obj, prop).by(delta); + } + + /** + * ### .doesNotChange(function, object, property, [message]) + * + * Asserts that a function does not change the value of a property. + * + * var obj = { val: 10 }; + * var fn = function() { console.log('foo'); }; + * assert.doesNotChange(fn, obj, 'val'); + * + * @name doesNotChange + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotChange = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotChange, true) + .to.not.change(obj, prop); + } + + /** + * ### .changesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not change the value of a property or of a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.changesButNotBy(fn, obj, 'val', 5); + * + * @name changesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.changesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.changesButNotBy, true) + .to.change(obj, prop).but.not.by(delta); + } + + /** + * ### .increases(function, object, property, [message]) + * + * Asserts that a function increases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 13 }; + * assert.increases(fn, obj, 'val'); + * + * @name increases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.increases, true) + .to.increase(obj, prop); + } + + /** + * ### .increasesBy(function, object, property, delta, [message]) + * + * Asserts that a function increases a numeric object property or a function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val += 10 }; + * assert.increasesBy(fn, obj, 'val', 10); + * + * @name increasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesBy, true) + .to.increase(obj, prop).by(delta); + } + + /** + * ### .doesNotIncrease(function, object, property, [message]) + * + * Asserts that a function does not increase a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 8 }; + * assert.doesNotIncrease(fn, obj, 'val'); + * + * @name doesNotIncrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotIncrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotIncrease, true) + .to.not.increase(obj, prop); + } + + /** + * ### .increasesButNotBy(function, object, property, [message]) + * + * Asserts that a function does not increase a numeric object property or function's return value by an amount (delta). + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.increasesButNotBy(fn, obj, 'val', 10); + * + * @name increasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.increasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.increasesButNotBy, true) + .to.increase(obj, prop).but.not.by(delta); + } + + /** + * ### .decreases(function, object, property, [message]) + * + * Asserts that a function decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreases(fn, obj, 'val'); + * + * @name decreases + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreases = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.decreases, true) + .to.decrease(obj, prop); + } + + /** + * ### .decreasesBy(function, object, property, delta, [message]) + * + * Asserts that a function decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val -= 5 }; + * assert.decreasesBy(fn, obj, 'val', 5); + * + * @name decreasesBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesBy, true) + .to.decrease(obj, prop).by(delta); + } + + /** + * ### .doesNotDecrease(function, object, property, [message]) + * + * Asserts that a function does not decreases a numeric object property. + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 15 }; + * assert.doesNotDecrease(fn, obj, 'val'); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecrease = function (fn, obj, prop, msg) { + if (arguments.length === 3 && typeof obj === 'function') { + msg = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecrease, true) + .to.not.decrease(obj, prop); + } + + /** + * ### .doesNotDecreaseBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.doesNotDecreaseBy(fn, obj, 'val', 1); + * + * @name doesNotDecrease + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.doesNotDecreaseBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + return new Assertion(fn, msg, assert.doesNotDecreaseBy, true) + .to.not.decrease(obj, prop).by(delta); + } + + /** + * ### .decreasesButNotBy(function, object, property, delta, [message]) + * + * Asserts that a function does not decreases a numeric object property or a function's return value by an amount (delta) + * + * var obj = { val: 10 }; + * var fn = function() { obj.val = 5 }; + * assert.decreasesButNotBy(fn, obj, 'val', 1); + * + * @name decreasesButNotBy + * @param {Function} modifier function + * @param {Object} object or getter function + * @param {String} property name _optional_ + * @param {Number} change amount (delta) + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.decreasesButNotBy = function (fn, obj, prop, delta, msg) { + if (arguments.length === 4 && typeof obj === 'function') { + var tmpMsg = delta; + delta = prop; + msg = tmpMsg; + } else if (arguments.length === 3) { + delta = prop; + prop = null; + } + + new Assertion(fn, msg, assert.decreasesButNotBy, true) + .to.decrease(obj, prop).but.not.by(delta); + } + + /*! + * ### .ifError(object) + * + * Asserts if value is not a false value, and throws if it is a true value. + * This is added to allow for chai to be a drop-in replacement for Node's + * assert class. + * + * var err = new Error('I am a custom error'); + * assert.ifError(err); // Rethrows err! + * + * @name ifError + * @param {Object} object + * @namespace Assert + * @api public + */ + + assert.ifError = function (val) { + if (val) { + throw(val); + } + }; + + /** + * ### .isExtensible(object) + * + * Asserts that `object` is extensible (can have new properties added to it). + * + * assert.isExtensible({}); + * + * @name isExtensible + * @alias extensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isExtensible, true).to.be.extensible; + }; + + /** + * ### .isNotExtensible(object) + * + * Asserts that `object` is _not_ extensible. + * + * var nonExtensibleObject = Object.preventExtensions({}); + * var sealedObject = Object.seal({}); + * var frozenObject = Object.freeze({}); + * + * assert.isNotExtensible(nonExtensibleObject); + * assert.isNotExtensible(sealedObject); + * assert.isNotExtensible(frozenObject); + * + * @name isNotExtensible + * @alias notExtensible + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotExtensible = function (obj, msg) { + new Assertion(obj, msg, assert.isNotExtensible, true).to.not.be.extensible; + }; + + /** + * ### .isSealed(object) + * + * Asserts that `object` is sealed (cannot have new properties added to it + * and its existing properties cannot be removed). + * + * var sealedObject = Object.seal({}); + * var frozenObject = Object.seal({}); + * + * assert.isSealed(sealedObject); + * assert.isSealed(frozenObject); + * + * @name isSealed + * @alias sealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isSealed, true).to.be.sealed; + }; + + /** + * ### .isNotSealed(object) + * + * Asserts that `object` is _not_ sealed. + * + * assert.isNotSealed({}); + * + * @name isNotSealed + * @alias notSealed + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotSealed = function (obj, msg) { + new Assertion(obj, msg, assert.isNotSealed, true).to.not.be.sealed; + }; + + /** + * ### .isFrozen(object) + * + * Asserts that `object` is frozen (cannot have new properties added to it + * and its existing properties cannot be modified). + * + * var frozenObject = Object.freeze({}); + * assert.frozen(frozenObject); + * + * @name isFrozen + * @alias frozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isFrozen, true).to.be.frozen; + }; + + /** + * ### .isNotFrozen(object) + * + * Asserts that `object` is _not_ frozen. + * + * assert.isNotFrozen({}); + * + * @name isNotFrozen + * @alias notFrozen + * @param {Object} object + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotFrozen = function (obj, msg) { + new Assertion(obj, msg, assert.isNotFrozen, true).to.not.be.frozen; + }; + + /** + * ### .isEmpty(target) + * + * Asserts that the target does not contain any values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isEmpty([]); + * assert.isEmpty(''); + * assert.isEmpty(new Map); + * assert.isEmpty({}); + * + * @name isEmpty + * @alias empty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isEmpty = function(val, msg) { + new Assertion(val, msg, assert.isEmpty, true).to.be.empty; + }; + + /** + * ### .isNotEmpty(target) + * + * Asserts that the target contains values. + * For arrays and strings, it checks the `length` property. + * For `Map` and `Set` instances, it checks the `size` property. + * For non-function objects, it gets the count of own + * enumerable string keys. + * + * assert.isNotEmpty([1, 2]); + * assert.isNotEmpty('34'); + * assert.isNotEmpty(new Set([5, 6])); + * assert.isNotEmpty({ key: 7 }); + * + * @name isNotEmpty + * @alias notEmpty + * @param {Object|Array|String|Map|Set} target + * @param {String} message _optional_ + * @namespace Assert + * @api public + */ + + assert.isNotEmpty = function(val, msg) { + new Assertion(val, msg, assert.isNotEmpty, true).to.not.be.empty; + }; + + /*! + * Aliases. + */ + + (function alias(name, as){ + assert[as] = assert[name]; + return alias; + }) + ('isOk', 'ok') + ('isNotOk', 'notOk') + ('throws', 'throw') + ('throws', 'Throw') + ('isExtensible', 'extensible') + ('isNotExtensible', 'notExtensible') + ('isSealed', 'sealed') + ('isNotSealed', 'notSealed') + ('isFrozen', 'frozen') + ('isNotFrozen', 'notFrozen') + ('isEmpty', 'empty') + ('isNotEmpty', 'notEmpty'); +}; + +},{}],39:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + chai.expect = function (val, message) { + return new chai.Assertion(val, message); + }; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * expect.fail(); + * expect.fail("custom error message"); + * expect.fail(1, 2); + * expect.fail(1, 2, "custom error message"); + * expect.fail(1, 2, "custom error message", ">"); + * expect.fail(1, 2, undefined, ">"); + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + chai.expect.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = undefined; + } + + message = message || 'expect.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, chai.expect.fail); + }; +}; + +},{}],40:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011-2014 Jake Luer + * MIT Licensed + */ + +module.exports = function (chai, util) { + var Assertion = chai.Assertion; + + function loadShould () { + // explicitly define this method as function as to have it's name to include as `ssfi` + function shouldGetter() { + if (this instanceof String + || this instanceof Number + || this instanceof Boolean + || typeof Symbol === 'function' && this instanceof Symbol) { + return new Assertion(this.valueOf(), null, shouldGetter); + } + return new Assertion(this, null, shouldGetter); + } + function shouldSetter(value) { + // See https://github.com/chaijs/chai/issues/86: this makes + // `whatever.should = someValue` actually set `someValue`, which is + // especially useful for `global.should = require('chai').should()`. + // + // Note that we have to use [[DefineProperty]] instead of [[Put]] + // since otherwise we would trigger this very setter! + Object.defineProperty(this, 'should', { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } + // modify Object.prototype to have `should` + Object.defineProperty(Object.prototype, 'should', { + set: shouldSetter + , get: shouldGetter + , configurable: true + }); + + var should = {}; + + /** + * ### .fail([message]) + * ### .fail(actual, expected, [message], [operator]) + * + * Throw a failure. + * + * should.fail(); + * should.fail("custom error message"); + * should.fail(1, 2); + * should.fail(1, 2, "custom error message"); + * should.fail(1, 2, "custom error message", ">"); + * should.fail(1, 2, undefined, ">"); + * + * + * @name fail + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @param {String} operator + * @namespace BDD + * @api public + */ + + should.fail = function (actual, expected, message, operator) { + if (arguments.length < 2) { + message = actual; + actual = undefined; + } + + message = message || 'should.fail()'; + throw new chai.AssertionError(message, { + actual: actual + , expected: expected + , operator: operator + }, should.fail); + }; + + /** + * ### .equal(actual, expected, [message]) + * + * Asserts non-strict equality (`==`) of `actual` and `expected`. + * + * should.equal(3, '3', '== coerces values to strings'); + * + * @name equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.equal(val2); + }; + + /** + * ### .throw(function, [constructor/string/regexp], [string/regexp], [message]) + * + * Asserts that `function` will throw an error that is an instance of + * `constructor`, or alternately that it will throw an error with message + * matching `regexp`. + * + * should.throw(fn, 'function throws a reference error'); + * should.throw(fn, /function throws a reference error/); + * should.throw(fn, ReferenceError); + * should.throw(fn, ReferenceError, 'function throws a reference error'); + * should.throw(fn, ReferenceError, /function throws a reference error/); + * + * @name throw + * @alias Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.Throw(errt, errs); + }; + + /** + * ### .exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var foo = 'hi'; + * + * should.exist(foo, 'foo exists'); + * + * @name exist + * @namespace Should + * @api public + */ + + should.exist = function (val, msg) { + new Assertion(val, msg).to.exist; + } + + // negation + should.not = {} + + /** + * ### .not.equal(actual, expected, [message]) + * + * Asserts non-strict inequality (`!=`) of `actual` and `expected`. + * + * should.not.equal(3, 4, 'these numbers are not equal'); + * + * @name not.equal + * @param {Mixed} actual + * @param {Mixed} expected + * @param {String} message + * @namespace Should + * @api public + */ + + should.not.equal = function (val1, val2, msg) { + new Assertion(val1, msg).to.not.equal(val2); + }; + + /** + * ### .throw(function, [constructor/regexp], [message]) + * + * Asserts that `function` will _not_ throw an error that is an instance of + * `constructor`, or alternately that it will not throw an error with message + * matching `regexp`. + * + * should.not.throw(fn, Error, 'function does not throw'); + * + * @name not.throw + * @alias not.Throw + * @param {Function} function + * @param {ErrorConstructor} constructor + * @param {RegExp} regexp + * @param {String} message + * @see https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error#Error_types + * @namespace Should + * @api public + */ + + should.not.Throw = function (fn, errt, errs, msg) { + new Assertion(fn, msg).to.not.Throw(errt, errs); + }; + + /** + * ### .not.exist + * + * Asserts that the target is neither `null` nor `undefined`. + * + * var bar = null; + * + * should.not.exist(bar, 'bar does not exist'); + * + * @name not.exist + * @namespace Should + * @api public + */ + + should.not.exist = function (val, msg) { + new Assertion(val, msg).to.not.exist; + } + + should['throw'] = should['Throw']; + should.not['throw'] = should.not['Throw']; + + return should; + }; + + chai.should = loadShould; + chai.Should = loadShould; +}; + +},{}],41:[function(require,module,exports){ +/*! + * Chai - addChainingMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/*! + * Module variables + */ + +// Check whether `Object.setPrototypeOf` is supported +var canSetPrototype = typeof Object.setPrototypeOf === 'function'; + +// Without `Object.setPrototypeOf` support, this module will need to add properties to a function. +// However, some of functions' own props are not configurable and should be skipped. +var testFn = function() {}; +var excludeNames = Object.getOwnPropertyNames(testFn).filter(function(name) { + var propDesc = Object.getOwnPropertyDescriptor(testFn, name); + + // Note: PhantomJS 1.x includes `callee` as one of `testFn`'s own properties, + // but then returns `undefined` as the property descriptor for `callee`. As a + // workaround, we perform an otherwise unnecessary type-check for `propDesc`, + // and then filter it out if it's not an object as it should be. + if (typeof propDesc !== 'object') + return true; + + return !propDesc.configurable; +}); + +// Cache `Function` properties +var call = Function.prototype.call, + apply = Function.prototype.apply; + +/** + * ### .addChainableMethod(ctx, name, method, chainingBehavior) + * + * Adds a method to an object, such that the method can also be chained. + * + * utils.addChainableMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addChainableMethod('foo', fn, chainingBehavior); + * + * The result can then be used as both a method assertion, executing both `method` and + * `chainingBehavior`, or as a language chain, which only executes `chainingBehavior`. + * + * expect(fooStr).to.be.foo('bar'); + * expect(fooStr).to.be.foo.equal('foo'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for `name`, when called + * @param {Function} chainingBehavior function to be called every time the property is accessed + * @namespace Utils + * @name addChainableMethod + * @api public + */ + +module.exports = function addChainableMethod(ctx, name, method, chainingBehavior) { + if (typeof chainingBehavior !== 'function') { + chainingBehavior = function () { }; + } + + var chainableBehavior = { + method: method + , chainingBehavior: chainingBehavior + }; + + // save the methods so we can overwrite them later, if we need to. + if (!ctx.__methods) { + ctx.__methods = {}; + } + ctx.__methods[name] = chainableBehavior; + + Object.defineProperty(ctx, name, + { get: function chainableMethodGetter() { + chainableBehavior.chainingBehavior.call(this); + + var chainableMethodWrapper = function () { + // Setting the `ssfi` flag to `chainableMethodWrapper` causes this + // function to be the starting point for removing implementation + // frames from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then this assertion is being + // invoked from inside of another assertion. In this case, the `ssfi` + // flag has already been set by the outer assertion. + // + // Note that overwriting a chainable method merely replaces the saved + // methods in `ctx.__methods` instead of completely replacing the + // overwritten assertion. Therefore, an overwriting assertion won't + // set the `ssfi` or `lockSsfi` flags. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', chainableMethodWrapper); + } + + var result = chainableBehavior.method.apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(chainableMethodWrapper, name, true); + + // Use `Object.setPrototypeOf` if available + if (canSetPrototype) { + // Inherit all properties from the object by replacing the `Function` prototype + var prototype = Object.create(this); + // Restore the `call` and `apply` methods from `Function` + prototype.call = call; + prototype.apply = apply; + Object.setPrototypeOf(chainableMethodWrapper, prototype); + } + // Otherwise, redefine all properties (slow!) + else { + var asserterNames = Object.getOwnPropertyNames(ctx); + asserterNames.forEach(function (asserterName) { + if (excludeNames.indexOf(asserterName) !== -1) { + return; + } + + var pd = Object.getOwnPropertyDescriptor(ctx, asserterName); + Object.defineProperty(chainableMethodWrapper, asserterName, pd); + }); + } + + transferFlags(this, chainableMethodWrapper); + return proxify(chainableMethodWrapper); + } + , configurable: true + }); +}; + +},{"../../chai":34,"./addLengthGuard":42,"./flag":47,"./proxify":62,"./transferFlags":64}],42:[function(require,module,exports){ +var fnLengthDesc = Object.getOwnPropertyDescriptor(function () {}, 'length'); + +/*! + * Chai - addLengthGuard utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .addLengthGuard(fn, assertionName, isChainable) + * + * Define `length` as a getter on the given uninvoked method assertion. The + * getter acts as a guard against chaining `length` directly off of an uninvoked + * method assertion, which is a problem because it references `function`'s + * built-in `length` property instead of Chai's `length` assertion. When the + * getter catches the user making this mistake, it throws an error with a + * helpful message. + * + * There are two ways in which this mistake can be made. The first way is by + * chaining the `length` assertion directly off of an uninvoked chainable + * method. In this case, Chai suggests that the user use `lengthOf` instead. The + * second way is by chaining the `length` assertion directly off of an uninvoked + * non-chainable method. Non-chainable methods must be invoked prior to + * chaining. In this case, Chai suggests that the user consult the docs for the + * given assertion. + * + * If the `length` property of functions is unconfigurable, then return `fn` + * without modification. + * + * Note that in ES6, the function's `length` property is configurable, so once + * support for legacy environments is dropped, Chai's `length` property can + * replace the built-in function's `length` property, and this length guard will + * no longer be necessary. In the mean time, maintaining consistency across all + * environments is the priority. + * + * @param {Function} fn + * @param {String} assertionName + * @param {Boolean} isChainable + * @namespace Utils + * @name addLengthGuard + */ + +module.exports = function addLengthGuard (fn, assertionName, isChainable) { + if (!fnLengthDesc.configurable) return fn; + + Object.defineProperty(fn, 'length', { + get: function () { + if (isChainable) { + throw Error('Invalid Chai property: ' + assertionName + '.length. Due' + + ' to a compatibility issue, "length" cannot directly follow "' + + assertionName + '". Use "' + assertionName + '.lengthOf" instead.'); + } + + throw Error('Invalid Chai property: ' + assertionName + '.length. See' + + ' docs for proper usage of "' + assertionName + '".'); + } + }); + + return fn; +}; + +},{}],43:[function(require,module,exports){ +/*! + * Chai - addMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addMethod(ctx, name, method) + * + * Adds a method to the prototype of an object. + * + * utils.addMethod(chai.Assertion.prototype, 'foo', function (str) { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.equal(str); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(fooStr).to.be.foo('bar'); + * + * @param {Object} ctx object to which the method is added + * @param {String} name of method to add + * @param {Function} method function to be used for name + * @namespace Utils + * @name addMethod + * @api public + */ + +module.exports = function addMethod(ctx, name, method) { + var methodWrapper = function () { + // Setting the `ssfi` flag to `methodWrapper` causes this function to be the + // starting point for removing implementation frames from the stack trace of + // a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', methodWrapper); + } + + var result = method.apply(this, arguments); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + addLengthGuard(methodWrapper, name, false); + ctx[name] = proxify(methodWrapper, name); +}; + +},{"../../chai":34,"./addLengthGuard":42,"./flag":47,"./proxify":62,"./transferFlags":64}],44:[function(require,module,exports){ +/*! + * Chai - addProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .addProperty(ctx, name, getter) + * + * Adds a property to the prototype of an object. + * + * utils.addProperty(chai.Assertion.prototype, 'foo', function () { + * var obj = utils.flag(this, 'object'); + * new chai.Assertion(obj).to.be.instanceof(Foo); + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.addProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.foo; + * + * @param {Object} ctx object to which the property is added + * @param {String} name of property to add + * @param {Function} getter function to be used for name + * @namespace Utils + * @name addProperty + * @api public + */ + +module.exports = function addProperty(ctx, name, getter) { + getter = getter === undefined ? function () {} : getter; + + Object.defineProperty(ctx, name, + { get: function propertyGetter() { + // Setting the `ssfi` flag to `propertyGetter` causes this function to + // be the starting point for removing implementation frames from the + // stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', propertyGetter); + } + + var result = getter.call(this); + if (result !== undefined) + return result; + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; + +},{"../../chai":34,"./flag":47,"./isProxyEnabled":57,"./transferFlags":64}],45:[function(require,module,exports){ +/*! + * Chai - compareByInspect utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var inspect = require('./inspect'); + +/** + * ### .compareByInspect(mixed, mixed) + * + * To be used as a compareFunction with Array.prototype.sort. Compares elements + * using inspect instead of default behavior of using toString so that Symbols + * and objects with irregular/missing toString can still be sorted without a + * TypeError. + * + * @param {Mixed} first element to compare + * @param {Mixed} second element to compare + * @returns {Number} -1 if 'a' should come before 'b'; otherwise 1 + * @name compareByInspect + * @namespace Utils + * @api public + */ + +module.exports = function compareByInspect(a, b) { + return inspect(a) < inspect(b) ? -1 : 1; +}; + +},{"./inspect":55}],46:[function(require,module,exports){ +/*! + * Chai - expectTypes utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .expectTypes(obj, types) + * + * Ensures that the object being tested against is of a valid type. + * + * utils.expectTypes(this, ['array', 'object', 'string']); + * + * @param {Mixed} obj constructed Assertion + * @param {Array} type A list of allowed types for this assertion + * @namespace Utils + * @name expectTypes + * @api public + */ + +var AssertionError = require('assertion-error'); +var flag = require('./flag'); +var type = require('type-detect'); + +module.exports = function expectTypes(obj, types) { + var flagMsg = flag(obj, 'message'); + var ssfi = flag(obj, 'ssfi'); + + flagMsg = flagMsg ? flagMsg + ': ' : ''; + + obj = flag(obj, 'object'); + types = types.map(function (t) { return t.toLowerCase(); }); + types.sort(); + + // Transforms ['lorem', 'ipsum'] into 'a lorem, or an ipsum' + var str = types.map(function (t, index) { + var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; + var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; + return or + art + ' ' + t; + }).join(', '); + + var objType = type(obj).toLowerCase(); + + if (!types.some(function (expected) { return objType === expected; })) { + throw new AssertionError( + flagMsg + 'object tested must be ' + str + ', but ' + objType + ' given', + undefined, + ssfi + ); + } +}; + +},{"./flag":47,"assertion-error":5,"type-detect":75}],47:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .flag(object, key, [value]) + * + * Get or set a flag value on an object. If a + * value is provided it will be set, else it will + * return the currently set value or `undefined` if + * the value is not set. + * + * utils.flag(this, 'foo', 'bar'); // setter + * utils.flag(this, 'foo'); // getter, returns `bar` + * + * @param {Object} object constructed Assertion + * @param {String} key + * @param {Mixed} value (optional) + * @namespace Utils + * @name flag + * @api private + */ + +module.exports = function flag(obj, key, value) { + var flags = obj.__flags || (obj.__flags = Object.create(null)); + if (arguments.length === 3) { + flags[key] = value; + } else { + return flags[key]; + } +}; + +},{}],48:[function(require,module,exports){ +/*! + * Chai - getActual utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getActual(object, [actual]) + * + * Returns the `actual` value for an Assertion. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getActual + */ + +module.exports = function getActual(obj, args) { + return args.length > 4 ? args[4] : obj._obj; +}; + +},{}],49:[function(require,module,exports){ +/*! + * Chai - getEnumerableProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getEnumerableProperties(object) + * + * This allows the retrieval of enumerable property names of an object, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getEnumerableProperties + * @api public + */ + +module.exports = function getEnumerableProperties(object) { + var result = []; + for (var name in object) { + result.push(name); + } + return result; +}; + +},{}],50:[function(require,module,exports){ +/*! + * Chai - message composition utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var flag = require('./flag') + , getActual = require('./getActual') + , objDisplay = require('./objDisplay'); + +/** + * ### .getMessage(object, message, negateMessage) + * + * Construct the error message based on flags + * and template tags. Template tags will return + * a stringified inspection of the object referenced. + * + * Message template tags: + * - `#{this}` current asserted object + * - `#{act}` actual value + * - `#{exp}` expected value + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name getMessage + * @api public + */ + +module.exports = function getMessage(obj, args) { + var negate = flag(obj, 'negate') + , val = flag(obj, 'object') + , expected = args[3] + , actual = getActual(obj, args) + , msg = negate ? args[2] : args[1] + , flagMsg = flag(obj, 'message'); + + if(typeof msg === "function") msg = msg(); + msg = msg || ''; + msg = msg + .replace(/#\{this\}/g, function () { return objDisplay(val); }) + .replace(/#\{act\}/g, function () { return objDisplay(actual); }) + .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); + + return flagMsg ? flagMsg + ': ' + msg : msg; +}; + +},{"./flag":47,"./getActual":48,"./objDisplay":58}],51:[function(require,module,exports){ +/*! + * Chai - getOwnEnumerableProperties utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/** + * ### .getOwnEnumerableProperties(object) + * + * This allows the retrieval of directly-owned enumerable property names and + * symbols of an object. This function is necessary because Object.keys only + * returns enumerable property names, not enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerableProperties + * @api public + */ + +module.exports = function getOwnEnumerableProperties(obj) { + return Object.keys(obj).concat(getOwnEnumerablePropertySymbols(obj)); +}; + +},{"./getOwnEnumerablePropertySymbols":52}],52:[function(require,module,exports){ +/*! + * Chai - getOwnEnumerablePropertySymbols utility + * Copyright(c) 2011-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .getOwnEnumerablePropertySymbols(object) + * + * This allows the retrieval of directly-owned enumerable property symbols of an + * object. This function is necessary because Object.getOwnPropertySymbols + * returns both enumerable and non-enumerable property symbols. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getOwnEnumerablePropertySymbols + * @api public + */ + +module.exports = function getOwnEnumerablePropertySymbols(obj) { + if (typeof Object.getOwnPropertySymbols !== 'function') return []; + + return Object.getOwnPropertySymbols(obj).filter(function (sym) { + return Object.getOwnPropertyDescriptor(obj, sym).enumerable; + }); +}; + +},{}],53:[function(require,module,exports){ +/*! + * Chai - getProperties utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .getProperties(object) + * + * This allows the retrieval of property names of an object, enumerable or not, + * inherited or not. + * + * @param {Object} object + * @returns {Array} + * @namespace Utils + * @name getProperties + * @api public + */ + +module.exports = function getProperties(object) { + var result = Object.getOwnPropertyNames(object); + + function addProperty(property) { + if (result.indexOf(property) === -1) { + result.push(property); + } + } + + var proto = Object.getPrototypeOf(object); + while (proto !== null) { + Object.getOwnPropertyNames(proto).forEach(addProperty); + proto = Object.getPrototypeOf(proto); + } + + return result; +}; + +},{}],54:[function(require,module,exports){ +/*! + * chai + * Copyright(c) 2011 Jake Luer + * MIT Licensed + */ + +/*! + * Dependencies that are used for multiple exports are required here only once + */ + +var pathval = require('pathval'); + +/*! + * test utility + */ + +exports.test = require('./test'); + +/*! + * type utility + */ + +exports.type = require('type-detect'); + +/*! + * expectTypes utility + */ +exports.expectTypes = require('./expectTypes'); + +/*! + * message utility + */ + +exports.getMessage = require('./getMessage'); + +/*! + * actual utility + */ + +exports.getActual = require('./getActual'); + +/*! + * Inspect util + */ + +exports.inspect = require('./inspect'); + +/*! + * Object Display util + */ + +exports.objDisplay = require('./objDisplay'); + +/*! + * Flag utility + */ + +exports.flag = require('./flag'); + +/*! + * Flag transferring utility + */ + +exports.transferFlags = require('./transferFlags'); + +/*! + * Deep equal utility + */ + +exports.eql = require('deep-eql'); + +/*! + * Deep path info + */ + +exports.getPathInfo = pathval.getPathInfo; + +/*! + * Check if a property exists + */ + +exports.hasProperty = pathval.hasProperty; + +/*! + * Function name + */ + +exports.getName = require('get-func-name'); + +/*! + * add Property + */ + +exports.addProperty = require('./addProperty'); + +/*! + * add Method + */ + +exports.addMethod = require('./addMethod'); + +/*! + * overwrite Property + */ + +exports.overwriteProperty = require('./overwriteProperty'); + +/*! + * overwrite Method + */ + +exports.overwriteMethod = require('./overwriteMethod'); + +/*! + * Add a chainable method + */ + +exports.addChainableMethod = require('./addChainableMethod'); + +/*! + * Overwrite chainable method + */ + +exports.overwriteChainableMethod = require('./overwriteChainableMethod'); + +/*! + * Compare by inspect method + */ + +exports.compareByInspect = require('./compareByInspect'); + +/*! + * Get own enumerable property symbols method + */ + +exports.getOwnEnumerablePropertySymbols = require('./getOwnEnumerablePropertySymbols'); + +/*! + * Get own enumerable properties method + */ + +exports.getOwnEnumerableProperties = require('./getOwnEnumerableProperties'); + +/*! + * Checks error against a given set of criteria + */ + +exports.checkError = require('check-error'); + +/*! + * Proxify util + */ + +exports.proxify = require('./proxify'); + +/*! + * addLengthGuard util + */ + +exports.addLengthGuard = require('./addLengthGuard'); + +/*! + * isProxyEnabled helper + */ + +exports.isProxyEnabled = require('./isProxyEnabled'); + +/*! + * isNaN method + */ + +exports.isNaN = require('./isNaN'); + +},{"./addChainableMethod":41,"./addLengthGuard":42,"./addMethod":43,"./addProperty":44,"./compareByInspect":45,"./expectTypes":46,"./flag":47,"./getActual":48,"./getMessage":50,"./getOwnEnumerableProperties":51,"./getOwnEnumerablePropertySymbols":52,"./inspect":55,"./isNaN":56,"./isProxyEnabled":57,"./objDisplay":58,"./overwriteChainableMethod":59,"./overwriteMethod":60,"./overwriteProperty":61,"./proxify":62,"./test":63,"./transferFlags":64,"check-error":65,"deep-eql":66,"get-func-name":67,"pathval":69,"type-detect":75}],55:[function(require,module,exports){ +// This is (almost) directly from Node.js utils +// https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js + +var getName = require('get-func-name'); +var getProperties = require('./getProperties'); +var getEnumerableProperties = require('./getEnumerableProperties'); +var config = require('../config'); + +module.exports = inspect; + +/** + * ### .inspect(obj, [showHidden], [depth], [colors]) + * + * Echoes the value of a value. Tries to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Boolean} showHidden Flag that shows hidden (not enumerable) + * properties of objects. Default is false. + * @param {Number} depth Depth in which to descend in object. Default is 2. + * @param {Boolean} colors Flag to turn on ANSI escape codes to color the + * output. Default is false (no coloring). + * @namespace Utils + * @name inspect + */ +function inspect(obj, showHidden, depth, colors) { + var ctx = { + showHidden: showHidden, + seen: [], + stylize: function (str) { return str; } + }; + return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); +} + +// Returns true if object is a DOM element. +var isDOMElement = function (object) { + if (typeof HTMLElement === 'object') { + return object instanceof HTMLElement; + } else { + return object && + typeof object === 'object' && + 'nodeType' in object && + object.nodeType === 1 && + typeof object.nodeName === 'string'; + } +}; + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (value && typeof value.inspect === 'function' && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (typeof ret !== 'string') { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // If this is a DOM element, try to get the outer HTML. + if (isDOMElement(value)) { + if ('outerHTML' in value) { + return value.outerHTML; + // This value does not have an outerHTML attribute, + // it could still be an XML element + } else { + // Attempt to serialize it + try { + if (document.xmlVersion) { + var xmlSerializer = new XMLSerializer(); + return xmlSerializer.serializeToString(value); + } else { + // Firefox 11- do not support outerHTML + // It does, however, support innerHTML + // Use the following to render the element + var ns = "http://www.w3.org/1999/xhtml"; + var container = document.createElementNS(ns, '_'); + + container.appendChild(value.cloneNode(false)); + var html = container.innerHTML + .replace('><', '>' + value.innerHTML + '<'); + container.innerHTML = ''; + return html; + } + } catch (err) { + // This could be a non-native DOM implementation, + // continue with the normal flow: + // printing the element as if it is an object. + } + } + } + + // Look up the keys of the object. + var visibleKeys = getEnumerableProperties(value); + var keys = ctx.showHidden ? getProperties(value) : visibleKeys; + + var name, nameSuffix; + + // Some type of object without properties can be shortcut. + // In IE, errors have a single `stack` property, or if they are vanilla `Error`, + // a `stack` plus `description` property; ignore those for consistency. + if (keys.length === 0 || (isError(value) && ( + (keys.length === 1 && keys[0] === 'stack') || + (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') + ))) { + if (typeof value === 'function') { + name = getName(value); + nameSuffix = name ? ': ' + name : ''; + return ctx.stylize('[Function' + nameSuffix + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '' + , array = false + , typedArray = false + , braces = ['{', '}']; + + if (isTypedArray(value)) { + typedArray = true; + braces = ['[', ']']; + } + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (typeof value === 'function') { + name = getName(value); + nameSuffix = name ? ': ' + name : ''; + base = ' [Function' + nameSuffix + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + return formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else if (typedArray) { + return formatTypedArray(value); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + +function formatPrimitive(ctx, value) { + switch (typeof value) { + case 'undefined': + return ctx.stylize('undefined', 'undefined'); + + case 'string': + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + + case 'number': + if (value === 0 && (1/value) === -Infinity) { + return ctx.stylize('-0', 'number'); + } + return ctx.stylize('' + value, 'number'); + + case 'boolean': + return ctx.stylize('' + value, 'boolean'); + + case 'symbol': + return ctx.stylize(value.toString(), 'symbol'); + } + // For some reason typeof null is "object", so special case here. + if (value === null) { + return ctx.stylize('null', 'null'); + } +} + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (Object.prototype.hasOwnProperty.call(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + +function formatTypedArray(value) { + var str = '[ '; + + for (var i = 0; i < value.length; ++i) { + if (str.length >= config.truncateThreshold - 7) { + str += '...'; + break; + } + str += value[i] + ', '; + } + str += ' ]'; + + // Removing trailing `, ` if the array was not truncated + if (str.indexOf(', ]') !== -1) { + str = str.replace(', ]', ' ]'); + } + + return str; +} + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name; + var propDescriptor = Object.getOwnPropertyDescriptor(value, key); + var str; + + if (propDescriptor) { + if (propDescriptor.get) { + if (propDescriptor.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (propDescriptor.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + } + if (visibleKeys.indexOf(key) < 0) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(value[key]) < 0) { + if (recurseTimes === null) { + str = formatValue(ctx, value[key], null); + } else { + str = formatValue(ctx, value[key], recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (typeof name === 'undefined') { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + +function reduceToSingleString(output, base, braces) { + var length = output.reduce(function(prev, cur) { + return prev + cur.length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + +function isTypedArray(ar) { + // Unfortunately there's no way to check if an object is a TypedArray + // We have to check if it's one of these types + return (typeof ar === 'object' && /\w+Array]$/.test(objectToString(ar))); +} + +function isArray(ar) { + return Array.isArray(ar) || + (typeof ar === 'object' && objectToString(ar) === '[object Array]'); +} + +function isRegExp(re) { + return typeof re === 'object' && objectToString(re) === '[object RegExp]'; +} + +function isDate(d) { + return typeof d === 'object' && objectToString(d) === '[object Date]'; +} + +function isError(e) { + return typeof e === 'object' && objectToString(e) === '[object Error]'; +} + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + +},{"../config":36,"./getEnumerableProperties":49,"./getProperties":53,"get-func-name":67}],56:[function(require,module,exports){ +/*! + * Chai - isNaN utility + * Copyright(c) 2012-2015 Sakthipriyan Vairamani + * MIT Licensed + */ + +/** + * ### .isNaN(value) + * + * Checks if the given value is NaN or not. + * + * utils.isNaN(NaN); // true + * + * @param {Value} The value which has to be checked if it is NaN + * @name isNaN + * @api private + */ + +function isNaN(value) { + // Refer http://www.ecma-international.org/ecma-262/6.0/#sec-isnan-number + // section's NOTE. + return value !== value; +} + +// If ECMAScript 6's Number.isNaN is present, prefer that. +module.exports = Number.isNaN || isNaN; + +},{}],57:[function(require,module,exports){ +var config = require('../config'); + +/*! + * Chai - isProxyEnabled helper + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .isProxyEnabled() + * + * Helper function to check if Chai's proxy protection feature is enabled. If + * proxies are unsupported or disabled via the user's Chai config, then return + * false. Otherwise, return true. + * + * @namespace Utils + * @name isProxyEnabled + */ + +module.exports = function isProxyEnabled() { + return config.useProxy && + typeof Proxy !== 'undefined' && + typeof Reflect !== 'undefined'; +}; + +},{"../config":36}],58:[function(require,module,exports){ +/*! + * Chai - flag utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var inspect = require('./inspect'); +var config = require('../config'); + +/** + * ### .objDisplay(object) + * + * Determines if an object or an array matches + * criteria to be inspected in-line for error + * messages or should be truncated. + * + * @param {Mixed} javascript object to inspect + * @name objDisplay + * @namespace Utils + * @api public + */ + +module.exports = function objDisplay(obj) { + var str = inspect(obj) + , type = Object.prototype.toString.call(obj); + + if (config.truncateThreshold && str.length >= config.truncateThreshold) { + if (type === '[object Function]') { + return !obj.name || obj.name === '' + ? '[Function]' + : '[Function: ' + obj.name + ']'; + } else if (type === '[object Array]') { + return '[ Array(' + obj.length + ') ]'; + } else if (type === '[object Object]') { + var keys = Object.keys(obj) + , kstr = keys.length > 2 + ? keys.splice(0, 2).join(', ') + ', ...' + : keys.join(', '); + return '{ Object (' + kstr + ') }'; + } else { + return str; + } + } else { + return str; + } +}; + +},{"../config":36,"./inspect":55}],59:[function(require,module,exports){ +/*! + * Chai - overwriteChainableMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteChainableMethod(ctx, name, method, chainingBehavior) + * + * Overwrites an already existing chainable method + * and provides access to the previous function or + * property. Must return functions to be used for + * name. + * + * utils.overwriteChainableMethod(chai.Assertion.prototype, 'lengthOf', + * function (_super) { + * } + * , function (_super) { + * } + * ); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteChainableMethod('foo', fn, fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.have.lengthOf(3); + * expect(myFoo).to.have.lengthOf.above(3); + * + * @param {Object} ctx object whose method / property is to be overwritten + * @param {String} name of method / property to overwrite + * @param {Function} method function that returns a function to be used for name + * @param {Function} chainingBehavior function that returns a function to be used for property + * @namespace Utils + * @name overwriteChainableMethod + * @api public + */ + +module.exports = function overwriteChainableMethod(ctx, name, method, chainingBehavior) { + var chainableBehavior = ctx.__methods[name]; + + var _chainingBehavior = chainableBehavior.chainingBehavior; + chainableBehavior.chainingBehavior = function overwritingChainableMethodGetter() { + var result = chainingBehavior(_chainingBehavior).call(this); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; + + var _method = chainableBehavior.method; + chainableBehavior.method = function overwritingChainableMethodWrapper() { + var result = method(_method).apply(this, arguments); + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + }; +}; + +},{"../../chai":34,"./transferFlags":64}],60:[function(require,module,exports){ +/*! + * Chai - overwriteMethod utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var addLengthGuard = require('./addLengthGuard'); +var chai = require('../../chai'); +var flag = require('./flag'); +var proxify = require('./proxify'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteMethod(ctx, name, fn) + * + * Overwrites an already existing method and provides + * access to previous function. Must return function + * to be used for name. + * + * utils.overwriteMethod(chai.Assertion.prototype, 'equal', function (_super) { + * return function (str) { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.value).to.equal(str); + * } else { + * _super.apply(this, arguments); + * } + * } + * }); + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteMethod('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.equal('bar'); + * + * @param {Object} ctx object whose method is to be overwritten + * @param {String} name of method to overwrite + * @param {Function} method function that returns a function to be used for name + * @namespace Utils + * @name overwriteMethod + * @api public + */ + +module.exports = function overwriteMethod(ctx, name, method) { + var _method = ctx[name] + , _super = function () { + throw new Error(name + ' is not a function'); + }; + + if (_method && 'function' === typeof _method) + _super = _method; + + var overwritingMethodWrapper = function () { + // Setting the `ssfi` flag to `overwritingMethodWrapper` causes this + // function to be the starting point for removing implementation frames from + // the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if the + // `lockSsfi` flag isn't set. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked from + // inside of another assertion. In the first case, the `ssfi` flag has + // already been set by the overwriting assertion. In the second case, the + // `ssfi` flag has already been set by the outer assertion. + if (!flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingMethodWrapper); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten assertion + // from changing the `ssfi` flag. By this point, the `ssfi` flag is already + // set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = method(_super).apply(this, arguments); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + + addLengthGuard(overwritingMethodWrapper, name, false); + ctx[name] = proxify(overwritingMethodWrapper, name); +}; + +},{"../../chai":34,"./addLengthGuard":42,"./flag":47,"./proxify":62,"./transferFlags":64}],61:[function(require,module,exports){ +/*! + * Chai - overwriteProperty utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +var chai = require('../../chai'); +var flag = require('./flag'); +var isProxyEnabled = require('./isProxyEnabled'); +var transferFlags = require('./transferFlags'); + +/** + * ### .overwriteProperty(ctx, name, fn) + * + * Overwrites an already existing property getter and provides + * access to previous value. Must return function to use as getter. + * + * utils.overwriteProperty(chai.Assertion.prototype, 'ok', function (_super) { + * return function () { + * var obj = utils.flag(this, 'object'); + * if (obj instanceof Foo) { + * new chai.Assertion(obj.name).to.equal('bar'); + * } else { + * _super.call(this); + * } + * } + * }); + * + * + * Can also be accessed directly from `chai.Assertion`. + * + * chai.Assertion.overwriteProperty('foo', fn); + * + * Then can be used as any other assertion. + * + * expect(myFoo).to.be.ok; + * + * @param {Object} ctx object whose property is to be overwritten + * @param {String} name of property to overwrite + * @param {Function} getter function that returns a getter function to be used for name + * @namespace Utils + * @name overwriteProperty + * @api public + */ + +module.exports = function overwriteProperty(ctx, name, getter) { + var _get = Object.getOwnPropertyDescriptor(ctx, name) + , _super = function () {}; + + if (_get && 'function' === typeof _get.get) + _super = _get.get + + Object.defineProperty(ctx, name, + { get: function overwritingPropertyGetter() { + // Setting the `ssfi` flag to `overwritingPropertyGetter` causes this + // function to be the starting point for removing implementation frames + // from the stack trace of a failed assertion. + // + // However, we only want to use this function as the starting point if + // the `lockSsfi` flag isn't set and proxy protection is disabled. + // + // If the `lockSsfi` flag is set, then either this assertion has been + // overwritten by another assertion, or this assertion is being invoked + // from inside of another assertion. In the first case, the `ssfi` flag + // has already been set by the overwriting assertion. In the second + // case, the `ssfi` flag has already been set by the outer assertion. + // + // If proxy protection is enabled, then the `ssfi` flag has already been + // set by the proxy getter. + if (!isProxyEnabled() && !flag(this, 'lockSsfi')) { + flag(this, 'ssfi', overwritingPropertyGetter); + } + + // Setting the `lockSsfi` flag to `true` prevents the overwritten + // assertion from changing the `ssfi` flag. By this point, the `ssfi` + // flag is already set to the correct starting point for this assertion. + var origLockSsfi = flag(this, 'lockSsfi'); + flag(this, 'lockSsfi', true); + var result = getter(_super).call(this); + flag(this, 'lockSsfi', origLockSsfi); + + if (result !== undefined) { + return result; + } + + var newAssertion = new chai.Assertion(); + transferFlags(this, newAssertion); + return newAssertion; + } + , configurable: true + }); +}; + +},{"../../chai":34,"./flag":47,"./isProxyEnabled":57,"./transferFlags":64}],62:[function(require,module,exports){ +var config = require('../config'); +var flag = require('./flag'); +var getProperties = require('./getProperties'); +var isProxyEnabled = require('./isProxyEnabled'); + +/*! + * Chai - proxify utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .proxify(object) + * + * Return a proxy of given object that throws an error when a non-existent + * property is read. By default, the root cause is assumed to be a misspelled + * property, and thus an attempt is made to offer a reasonable suggestion from + * the list of existing properties. However, if a nonChainableMethodName is + * provided, then the root cause is instead a failure to invoke a non-chainable + * method prior to reading the non-existent property. + * + * If proxies are unsupported or disabled via the user's Chai config, then + * return object without modification. + * + * @param {Object} obj + * @param {String} nonChainableMethodName + * @namespace Utils + * @name proxify + */ + +var builtins = ['__flags', '__methods', '_obj', 'assert']; + +module.exports = function proxify(obj, nonChainableMethodName) { + if (!isProxyEnabled()) return obj; + + return new Proxy(obj, { + get: function proxyGetter(target, property) { + // This check is here because we should not throw errors on Symbol properties + // such as `Symbol.toStringTag`. + // The values for which an error should be thrown can be configured using + // the `config.proxyExcludedKeys` setting. + if (typeof property === 'string' && + config.proxyExcludedKeys.indexOf(property) === -1 && + !Reflect.has(target, property)) { + // Special message for invalid property access of non-chainable methods. + if (nonChainableMethodName) { + throw Error('Invalid Chai property: ' + nonChainableMethodName + '.' + + property + '. See docs for proper usage of "' + + nonChainableMethodName + '".'); + } + + // If the property is reasonably close to an existing Chai property, + // suggest that property to the user. Only suggest properties with a + // distance less than 4. + var suggestion = null; + var suggestionDistance = 4; + getProperties(target).forEach(function(prop) { + if ( + !Object.prototype.hasOwnProperty(prop) && + builtins.indexOf(prop) === -1 + ) { + var dist = stringDistanceCapped( + property, + prop, + suggestionDistance + ); + if (dist < suggestionDistance) { + suggestion = prop; + suggestionDistance = dist; + } + } + }); + + if (suggestion !== null) { + throw Error('Invalid Chai property: ' + property + + '. Did you mean "' + suggestion + '"?'); + } else { + throw Error('Invalid Chai property: ' + property); + } + } + + // Use this proxy getter as the starting point for removing implementation + // frames from the stack trace of a failed assertion. For property + // assertions, this prevents the proxy getter from showing up in the stack + // trace since it's invoked before the property getter. For method and + // chainable method assertions, this flag will end up getting changed to + // the method wrapper, which is good since this frame will no longer be in + // the stack once the method is invoked. Note that Chai builtin assertion + // properties such as `__flags` are skipped since this is only meant to + // capture the starting point of an assertion. This step is also skipped + // if the `lockSsfi` flag is set, thus indicating that this assertion is + // being called from within another assertion. In that case, the `ssfi` + // flag is already set to the outer assertion's starting point. + if (builtins.indexOf(property) === -1 && !flag(target, 'lockSsfi')) { + flag(target, 'ssfi', proxyGetter); + } + + return Reflect.get(target, property); + } + }); +}; + +/** + * # stringDistanceCapped(strA, strB, cap) + * Return the Levenshtein distance between two strings, but no more than cap. + * @param {string} strA + * @param {string} strB + * @param {number} number + * @return {number} min(string distance between strA and strB, cap) + * @api private + */ + +function stringDistanceCapped(strA, strB, cap) { + if (Math.abs(strA.length - strB.length) >= cap) { + return cap; + } + + var memo = []; + // `memo` is a two-dimensional array containing distances. + // memo[i][j] is the distance between strA.slice(0, i) and + // strB.slice(0, j). + for (var i = 0; i <= strA.length; i++) { + memo[i] = Array(strB.length + 1).fill(0); + memo[i][0] = i; + } + for (var j = 0; j < strB.length; j++) { + memo[0][j] = j; + } + + for (var i = 1; i <= strA.length; i++) { + var ch = strA.charCodeAt(i - 1); + for (var j = 1; j <= strB.length; j++) { + if (Math.abs(i - j) >= cap) { + memo[i][j] = cap; + continue; + } + memo[i][j] = Math.min( + memo[i - 1][j] + 1, + memo[i][j - 1] + 1, + memo[i - 1][j - 1] + + (ch === strB.charCodeAt(j - 1) ? 0 : 1) + ); + } + } + + return memo[strA.length][strB.length]; +} + +},{"../config":36,"./flag":47,"./getProperties":53,"./isProxyEnabled":57}],63:[function(require,module,exports){ +/*! + * Chai - test utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/*! + * Module dependencies + */ + +var flag = require('./flag'); + +/** + * ### .test(object, expression) + * + * Test and object for expression. + * + * @param {Object} object (constructed Assertion) + * @param {Arguments} chai.Assertion.prototype.assert arguments + * @namespace Utils + * @name test + */ + +module.exports = function test(obj, args) { + var negate = flag(obj, 'negate') + , expr = args[0]; + return negate ? !expr : expr; +}; + +},{"./flag":47}],64:[function(require,module,exports){ +/*! + * Chai - transferFlags utility + * Copyright(c) 2012-2014 Jake Luer + * MIT Licensed + */ + +/** + * ### .transferFlags(assertion, object, includeAll = true) + * + * Transfer all the flags for `assertion` to `object`. If + * `includeAll` is set to `false`, then the base Chai + * assertion flags (namely `object`, `ssfi`, `lockSsfi`, + * and `message`) will not be transferred. + * + * + * var newAssertion = new Assertion(); + * utils.transferFlags(assertion, newAssertion); + * + * var anotherAssertion = new Assertion(myObj); + * utils.transferFlags(assertion, anotherAssertion, false); + * + * @param {Assertion} assertion the assertion to transfer the flags from + * @param {Object} object the object to transfer the flags to; usually a new assertion + * @param {Boolean} includeAll + * @namespace Utils + * @name transferFlags + * @api private + */ + +module.exports = function transferFlags(assertion, object, includeAll) { + var flags = assertion.__flags || (assertion.__flags = Object.create(null)); + + if (!object.__flags) { + object.__flags = Object.create(null); + } + + includeAll = arguments.length === 3 ? includeAll : true; + + for (var flag in flags) { + if (includeAll || + (flag !== 'object' && flag !== 'ssfi' && flag !== 'lockSsfi' && flag != 'message')) { + object.__flags[flag] = flags[flag]; + } + } +}; + +},{}],65:[function(require,module,exports){ +'use strict'; + +/* ! + * Chai - checkError utility + * Copyright(c) 2012-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .checkError + * + * Checks that an error conforms to a given set of criteria and/or retrieves information about it. + * + * @api public + */ + +/** + * ### .compatibleInstance(thrown, errorLike) + * + * Checks if two instances are compatible (strict equal). + * Returns false if errorLike is not an instance of Error, because instances + * can only be compatible if they're both error instances. + * + * @name compatibleInstance + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleInstance(thrown, errorLike) { + return errorLike instanceof Error && thrown === errorLike; +} + +/** + * ### .compatibleConstructor(thrown, errorLike) + * + * Checks if two constructors are compatible. + * This function can receive either an error constructor or + * an error instance as the `errorLike` argument. + * Constructors are compatible if they're the same or if one is + * an instance of another. + * + * @name compatibleConstructor + * @param {Error} thrown error + * @param {Error|ErrorConstructor} errorLike object to compare against + * @namespace Utils + * @api public + */ + +function compatibleConstructor(thrown, errorLike) { + if (errorLike instanceof Error) { + // If `errorLike` is an instance of any error we compare their constructors + return thrown.constructor === errorLike.constructor || thrown instanceof errorLike.constructor; + } else if (errorLike.prototype instanceof Error || errorLike === Error) { + // If `errorLike` is a constructor that inherits from Error, we compare `thrown` to `errorLike` directly + return thrown.constructor === errorLike || thrown instanceof errorLike; + } + + return false; +} + +/** + * ### .compatibleMessage(thrown, errMatcher) + * + * Checks if an error's message is compatible with a matcher (String or RegExp). + * If the message contains the String or passes the RegExp test, + * it is considered compatible. + * + * @name compatibleMessage + * @param {Error} thrown error + * @param {String|RegExp} errMatcher to look for into the message + * @namespace Utils + * @api public + */ + +function compatibleMessage(thrown, errMatcher) { + var comparisonString = typeof thrown === 'string' ? thrown : thrown.message; + if (errMatcher instanceof RegExp) { + return errMatcher.test(comparisonString); + } else if (typeof errMatcher === 'string') { + return comparisonString.indexOf(errMatcher) !== -1; // eslint-disable-line no-magic-numbers + } + + return false; +} + +/** + * ### .getFunctionName(constructorFn) + * + * Returns the name of a function. + * This also includes a polyfill function if `constructorFn.name` is not defined. + * + * @name getFunctionName + * @param {Function} constructorFn + * @namespace Utils + * @api private + */ + +var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\(\/]+)/; +function getFunctionName(constructorFn) { + var name = ''; + if (typeof constructorFn.name === 'undefined') { + // Here we run a polyfill if constructorFn.name is not defined + var match = String(constructorFn).match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + name = constructorFn.name; + } + + return name; +} + +/** + * ### .getConstructorName(errorLike) + * + * Gets the constructor name for an Error instance or constructor itself. + * + * @name getConstructorName + * @param {Error|ErrorConstructor} errorLike + * @namespace Utils + * @api public + */ + +function getConstructorName(errorLike) { + var constructorName = errorLike; + if (errorLike instanceof Error) { + constructorName = getFunctionName(errorLike.constructor); + } else if (typeof errorLike === 'function') { + // If `err` is not an instance of Error it is an error constructor itself or another function. + // If we've got a common function we get its name, otherwise we may need to create a new instance + // of the error just in case it's a poorly-constructed error. Please see chaijs/chai/issues/45 to know more. + constructorName = getFunctionName(errorLike).trim() || + getFunctionName(new errorLike()); // eslint-disable-line new-cap + } + + return constructorName; +} + +/** + * ### .getMessage(errorLike) + * + * Gets the error message from an error. + * If `err` is a String itself, we return it. + * If the error has no message, we return an empty string. + * + * @name getMessage + * @param {Error|String} errorLike + * @namespace Utils + * @api public + */ + +function getMessage(errorLike) { + var msg = ''; + if (errorLike && errorLike.message) { + msg = errorLike.message; + } else if (typeof errorLike === 'string') { + msg = errorLike; + } + + return msg; +} + +module.exports = { + compatibleInstance: compatibleInstance, + compatibleConstructor: compatibleConstructor, + compatibleMessage: compatibleMessage, + getMessage: getMessage, + getConstructorName: getConstructorName, +}; + +},{}],66:[function(require,module,exports){ +'use strict'; +/* globals Symbol: false, Uint8Array: false, WeakMap: false */ +/*! + * deep-eql + * Copyright(c) 2013 Jake Luer + * MIT Licensed + */ + +var type = require('type-detect'); +function FakeMap() { + this._key = 'chai/deep-eql__' + Math.random() + Date.now(); +} + +FakeMap.prototype = { + get: function getMap(key) { + return key[this._key]; + }, + set: function setMap(key, value) { + if (Object.isExtensible(key)) { + Object.defineProperty(key, this._key, { + value: value, + configurable: true, + }); + } + }, +}; + +var MemoizeMap = typeof WeakMap === 'function' ? WeakMap : FakeMap; +/*! + * Check to see if the MemoizeMap has recorded a result of the two operands + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @returns {Boolean|null} result +*/ +function memoizeCompare(leftHandOperand, rightHandOperand, memoizeMap) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return null; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + var result = leftHandMap.get(rightHandOperand); + if (typeof result === 'boolean') { + return result; + } + } + return null; +} + +/*! + * Set the result of the equality into the MemoizeMap + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {MemoizeMap} memoizeMap + * @param {Boolean} result +*/ +function memoizeSet(leftHandOperand, rightHandOperand, memoizeMap, result) { + // Technically, WeakMap keys can *only* be objects, not primitives. + if (!memoizeMap || isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + return; + } + var leftHandMap = memoizeMap.get(leftHandOperand); + if (leftHandMap) { + leftHandMap.set(rightHandOperand, result); + } else { + leftHandMap = new MemoizeMap(); + leftHandMap.set(rightHandOperand, result); + memoizeMap.set(leftHandOperand, leftHandMap); + } +} + +/*! + * Primary Export + */ + +module.exports = deepEqual; +module.exports.MemoizeMap = MemoizeMap; + +/** + * Assert deeply nested sameValue equality between two objects of any type. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match + */ +function deepEqual(leftHandOperand, rightHandOperand, options) { + // If we have a comparator, we can't assume anything; so bail to its check first. + if (options && options.comparator) { + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); + } + + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + return simpleResult; + } + + // Deeper comparisons are pushed through to a larger function + return extensiveDeepEqual(leftHandOperand, rightHandOperand, options); +} + +/** + * Many comparisons can be canceled out early via simple equality or primitive checks. + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @return {Boolean|null} equal match + */ +function simpleEqual(leftHandOperand, rightHandOperand) { + // Equal references (except for Numbers) can be returned early + if (leftHandOperand === rightHandOperand) { + // Handle +-0 cases + return leftHandOperand !== 0 || 1 / leftHandOperand === 1 / rightHandOperand; + } + + // handle NaN cases + if ( + leftHandOperand !== leftHandOperand && // eslint-disable-line no-self-compare + rightHandOperand !== rightHandOperand // eslint-disable-line no-self-compare + ) { + return true; + } + + // Anything that is not an 'object', i.e. symbols, functions, booleans, numbers, + // strings, and undefined, can be compared by reference. + if (isPrimitive(leftHandOperand) || isPrimitive(rightHandOperand)) { + // Easy out b/c it would have passed the first equality check + return false; + } + return null; +} + +/*! + * The main logic of the `deepEqual` function. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (optional) Additional options + * @param {Array} [options.comparator] (optional) Override default algorithm, determining custom equality. + * @param {Array} [options.memoize] (optional) Provide a custom memoization object which will cache the results of + complex objects for a speed boost. By passing `false` you can disable memoization, but this will cause circular + references to blow the stack. + * @return {Boolean} equal match +*/ +function extensiveDeepEqual(leftHandOperand, rightHandOperand, options) { + options = options || {}; + options.memoize = options.memoize === false ? false : options.memoize || new MemoizeMap(); + var comparator = options && options.comparator; + + // Check if a memoized result exists. + var memoizeResultLeft = memoizeCompare(leftHandOperand, rightHandOperand, options.memoize); + if (memoizeResultLeft !== null) { + return memoizeResultLeft; + } + var memoizeResultRight = memoizeCompare(rightHandOperand, leftHandOperand, options.memoize); + if (memoizeResultRight !== null) { + return memoizeResultRight; + } + + // If a comparator is present, use it. + if (comparator) { + var comparatorResult = comparator(leftHandOperand, rightHandOperand); + // Comparators may return null, in which case we want to go back to default behavior. + if (comparatorResult === false || comparatorResult === true) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, comparatorResult); + return comparatorResult; + } + // To allow comparators to override *any* behavior, we ran them first. Since it didn't decide + // what to do, we need to make sure to return the basic tests first before we move on. + var simpleResult = simpleEqual(leftHandOperand, rightHandOperand); + if (simpleResult !== null) { + // Don't memoize this, it takes longer to set/retrieve than to just compare. + return simpleResult; + } + } + + var leftHandType = type(leftHandOperand); + if (leftHandType !== type(rightHandOperand)) { + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, false); + return false; + } + + // Temporarily set the operands in the memoize object to prevent blowing the stack + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, true); + + var result = extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options); + memoizeSet(leftHandOperand, rightHandOperand, options.memoize, result); + return result; +} + +function extensiveDeepEqualByType(leftHandOperand, rightHandOperand, leftHandType, options) { + switch (leftHandType) { + case 'String': + case 'Number': + case 'Boolean': + case 'Date': + // If these types are their instance types (e.g. `new Number`) then re-deepEqual against their values + return deepEqual(leftHandOperand.valueOf(), rightHandOperand.valueOf()); + case 'Promise': + case 'Symbol': + case 'function': + case 'WeakMap': + case 'WeakSet': + case 'Error': + return leftHandOperand === rightHandOperand; + case 'Arguments': + case 'Int8Array': + case 'Uint8Array': + case 'Uint8ClampedArray': + case 'Int16Array': + case 'Uint16Array': + case 'Int32Array': + case 'Uint32Array': + case 'Float32Array': + case 'Float64Array': + case 'Array': + return iterableEqual(leftHandOperand, rightHandOperand, options); + case 'RegExp': + return regexpEqual(leftHandOperand, rightHandOperand); + case 'Generator': + return generatorEqual(leftHandOperand, rightHandOperand, options); + case 'DataView': + return iterableEqual(new Uint8Array(leftHandOperand.buffer), new Uint8Array(rightHandOperand.buffer), options); + case 'ArrayBuffer': + return iterableEqual(new Uint8Array(leftHandOperand), new Uint8Array(rightHandOperand), options); + case 'Set': + return entriesEqual(leftHandOperand, rightHandOperand, options); + case 'Map': + return entriesEqual(leftHandOperand, rightHandOperand, options); + default: + return objectEqual(leftHandOperand, rightHandOperand, options); + } +} + +/*! + * Compare two Regular Expressions for equality. + * + * @param {RegExp} leftHandOperand + * @param {RegExp} rightHandOperand + * @return {Boolean} result + */ + +function regexpEqual(leftHandOperand, rightHandOperand) { + return leftHandOperand.toString() === rightHandOperand.toString(); +} + +/*! + * Compare two Sets/Maps for equality. Faster than other equality functions. + * + * @param {Set} leftHandOperand + * @param {Set} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function entriesEqual(leftHandOperand, rightHandOperand, options) { + // IE11 doesn't support Set#entries or Set#@@iterator, so we need manually populate using Set#forEach + if (leftHandOperand.size !== rightHandOperand.size) { + return false; + } + if (leftHandOperand.size === 0) { + return true; + } + var leftHandItems = []; + var rightHandItems = []; + leftHandOperand.forEach(function gatherEntries(key, value) { + leftHandItems.push([ key, value ]); + }); + rightHandOperand.forEach(function gatherEntries(key, value) { + rightHandItems.push([ key, value ]); + }); + return iterableEqual(leftHandItems.sort(), rightHandItems.sort(), options); +} + +/*! + * Simple equality for flat iterable objects such as Arrays, TypedArrays or Node.js buffers. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function iterableEqual(leftHandOperand, rightHandOperand, options) { + var length = leftHandOperand.length; + if (length !== rightHandOperand.length) { + return false; + } + if (length === 0) { + return true; + } + var index = -1; + while (++index < length) { + if (deepEqual(leftHandOperand[index], rightHandOperand[index], options) === false) { + return false; + } + } + return true; +} + +/*! + * Simple equality for generator objects such as those returned by generator functions. + * + * @param {Iterable} leftHandOperand + * @param {Iterable} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function generatorEqual(leftHandOperand, rightHandOperand, options) { + return iterableEqual(getGeneratorEntries(leftHandOperand), getGeneratorEntries(rightHandOperand), options); +} + +/*! + * Determine if the given object has an @@iterator function. + * + * @param {Object} target + * @return {Boolean} `true` if the object has an @@iterator function. + */ +function hasIteratorFunction(target) { + return typeof Symbol !== 'undefined' && + typeof target === 'object' && + typeof Symbol.iterator !== 'undefined' && + typeof target[Symbol.iterator] === 'function'; +} + +/*! + * Gets all iterator entries from the given Object. If the Object has no @@iterator function, returns an empty array. + * This will consume the iterator - which could have side effects depending on the @@iterator implementation. + * + * @param {Object} target + * @returns {Array} an array of entries from the @@iterator function + */ +function getIteratorEntries(target) { + if (hasIteratorFunction(target)) { + try { + return getGeneratorEntries(target[Symbol.iterator]()); + } catch (iteratorError) { + return []; + } + } + return []; +} + +/*! + * Gets all entries from a Generator. This will consume the generator - which could have side effects. + * + * @param {Generator} target + * @returns {Array} an array of entries from the Generator. + */ +function getGeneratorEntries(generator) { + var generatorResult = generator.next(); + var accumulator = [ generatorResult.value ]; + while (generatorResult.done === false) { + generatorResult = generator.next(); + accumulator.push(generatorResult.value); + } + return accumulator; +} + +/*! + * Gets all own and inherited enumerable keys from a target. + * + * @param {Object} target + * @returns {Array} an array of own and inherited enumerable keys from the target. + */ +function getEnumerableKeys(target) { + var keys = []; + for (var key in target) { + keys.push(key); + } + return keys; +} + +/*! + * Determines if two objects have matching values, given a set of keys. Defers to deepEqual for the equality check of + * each key. If any value of the given key is not equal, the function will return false (early). + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Array} keys An array of keys to compare the values of leftHandOperand and rightHandOperand against + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ +function keysEqual(leftHandOperand, rightHandOperand, keys, options) { + var length = keys.length; + if (length === 0) { + return true; + } + for (var i = 0; i < length; i += 1) { + if (deepEqual(leftHandOperand[keys[i]], rightHandOperand[keys[i]], options) === false) { + return false; + } + } + return true; +} + +/*! + * Recursively check the equality of two Objects. Once basic sameness has been established it will defer to `deepEqual` + * for each enumerable key in the object. + * + * @param {Mixed} leftHandOperand + * @param {Mixed} rightHandOperand + * @param {Object} [options] (Optional) + * @return {Boolean} result + */ + +function objectEqual(leftHandOperand, rightHandOperand, options) { + var leftHandKeys = getEnumerableKeys(leftHandOperand); + var rightHandKeys = getEnumerableKeys(rightHandOperand); + if (leftHandKeys.length && leftHandKeys.length === rightHandKeys.length) { + leftHandKeys.sort(); + rightHandKeys.sort(); + if (iterableEqual(leftHandKeys, rightHandKeys) === false) { + return false; + } + return keysEqual(leftHandOperand, rightHandOperand, leftHandKeys, options); + } + + var leftHandEntries = getIteratorEntries(leftHandOperand); + var rightHandEntries = getIteratorEntries(rightHandOperand); + if (leftHandEntries.length && leftHandEntries.length === rightHandEntries.length) { + leftHandEntries.sort(); + rightHandEntries.sort(); + return iterableEqual(leftHandEntries, rightHandEntries, options); + } + + if (leftHandKeys.length === 0 && + leftHandEntries.length === 0 && + rightHandKeys.length === 0 && + rightHandEntries.length === 0) { + return true; + } + + return false; +} + +/*! + * Returns true if the argument is a primitive. + * + * This intentionally returns true for all objects that can be compared by reference, + * including functions and symbols. + * + * @param {Mixed} value + * @return {Boolean} result + */ +function isPrimitive(value) { + return value === null || typeof value !== 'object'; +} + +},{"type-detect":75}],67:[function(require,module,exports){ +'use strict'; + +/* ! + * Chai - getFuncName utility + * Copyright(c) 2012-2016 Jake Luer + * MIT Licensed + */ + +/** + * ### .getFuncName(constructorFn) + * + * Returns the name of a function. + * When a non-function instance is passed, returns `null`. + * This also includes a polyfill function if `aFunc.name` is not defined. + * + * @name getFuncName + * @param {Function} funct + * @namespace Utils + * @api public + */ + +var toString = Function.prototype.toString; +var functionNameMatch = /\s*function(?:\s|\s*\/\*[^(?:*\/)]+\*\/\s*)*([^\s\(\/]+)/; +function getFuncName(aFunc) { + if (typeof aFunc !== 'function') { + return null; + } + + var name = ''; + if (typeof Function.prototype.name === 'undefined' && typeof aFunc.name === 'undefined') { + // Here we run a polyfill if Function does not support the `name` property and if aFunc.name is not defined + var match = toString.call(aFunc).match(functionNameMatch); + if (match) { + name = match[1]; + } + } else { + // If we've got a `name` property we just use it + name = aFunc.name; + } + + return name; +} + +module.exports = getFuncName; + +},{}],68:[function(require,module,exports){ +(function (global){(function (){ +/** + * @license + * Lodash + * Copyright OpenJS Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * 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.17.19'; + + /** Used as the size to enable large array optimizations. */ + var LARGE_ARRAY_SIZE = 200; + + /** Error message constants. */ + var CORE_ERROR_TEXT = 'Unsupported core-js use. Try https://npms.io/search?q=ponyfill.', + FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used to stand-in for `undefined` hash values. */ + var HASH_UNDEFINED = '__lodash_hash_undefined__'; + + /** Used as the maximum memoize cache size. */ + var MAX_MEMOIZE_SIZE = 500; + + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; + + /** Used to compose bitmasks for cloning. */ + var CLONE_DEEP_FLAG = 1, + CLONE_FLAT_FLAG = 2, + CLONE_SYMBOLS_FLAG = 4; + + /** Used to compose bitmasks for value comparisons. */ + var COMPARE_PARTIAL_FLAG = 1, + COMPARE_UNORDERED_FLAG = 2; + + /** Used to compose bitmasks for function metadata. */ + var WRAP_BIND_FLAG = 1, + WRAP_BIND_KEY_FLAG = 2, + WRAP_CURRY_BOUND_FLAG = 4, + WRAP_CURRY_FLAG = 8, + WRAP_CURRY_RIGHT_FLAG = 16, + WRAP_PARTIAL_FLAG = 32, + WRAP_PARTIAL_RIGHT_FLAG = 64, + WRAP_ARY_FLAG = 128, + WRAP_REARG_FLAG = 256, + WRAP_FLIP_FLAG = 512; + + /** 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 = 800, + 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', WRAP_ARY_FLAG], + ['bind', WRAP_BIND_FLAG], + ['bindKey', WRAP_BIND_KEY_FLAG], + ['curry', WRAP_CURRY_FLAG], + ['curryRight', WRAP_CURRY_RIGHT_FLAG], + ['flip', WRAP_FLIP_FLAG], + ['partial', WRAP_PARTIAL_FLAG], + ['partialRight', WRAP_PARTIAL_RIGHT_FLAG], + ['rearg', WRAP_REARG_FLAG] + ]; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + asyncTag = '[object AsyncFunction]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + domExcTag = '[object DOMException]', + errorTag = '[object Error]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + mapTag = '[object Map]', + numberTag = '[object Number]', + nullTag = '[object Null]', + objectTag = '[object Object]', + promiseTag = '[object Promise]', + proxyTag = '[object Proxy]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + symbolTag = '[object Symbol]', + undefinedTag = '[object Undefined]', + 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);/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*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g; + + /** + * Used to match `RegExp` + * [syntax characters](http://ecma-international.org/ecma-262/7.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 words composed of alphanumeric characters. */ + var reAsciiWord = /[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g; + + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; + + /** + * Used to match + * [ES template delimiters](http://ecma-international.org/ecma-262/7.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 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 Unicode letters (excluding mathematical operators). */ + var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/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', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange, + 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 = '[' + rsComboRange + ']', + 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 rsMiscLower = '(?:' + rsLower + '|' + rsMisc + ')', + rsMiscUpper = '(?:' + rsUpper + '|' + rsMisc + ')', + rsOptContrLower = '(?:' + rsApos + '(?:d|ll|m|re|s|t|ve))?', + rsOptContrUpper = '(?:' + rsApos + '(?:D|LL|M|RE|S|T|VE))?', + reOptMod = rsModifier + '?', + rsOptVar = '[' + rsVarRange + ']?', + rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*', + rsOrdLower = '\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])', + rsOrdUpper = '\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])', + 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 reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); + + /** Used to match complex or compound words. */ + var reUnicodeWord = RegExp([ + rsUpper + '?' + rsLower + '+' + rsOptContrLower + '(?=' + [rsBreak, rsUpper, '$'].join('|') + ')', + rsMiscUpper + '+' + rsOptContrUpper + '(?=' + [rsBreak, rsUpper + rsMiscLower, '$'].join('|') + ')', + rsUpper + '?' + rsMiscLower + '+' + rsOptContrLower, + rsUpper + '+' + rsOptContrUpper, + rsOrdUpper, + rsOrdLower, + 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 reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); + + /** Used to detect strings that need a more robust regexp to match words. */ + var reHasUnicodeWord = /[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', '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 Unicode letters to basic Latin letters. */ + var deburredLetters = { + // Latin-1 Supplement block. + '\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', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 's' + }; + + /** 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 { + // Use `util.types` for Node.js 10+. + var types = freeModule && freeModule.require && freeModule.require('util').types; + + if (types) { + return types; + } + + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && 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; + + /*--------------------------------------------------------------------------*/ + + /** + * 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 == null ? 0 : array.length; + + 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 == null ? 0 : array.length; + + 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 == null ? 0 : array.length; + + 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 == null ? 0 : array.length; + + 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 == null ? 0 : array.length, + 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 inspect. + * @param {*} target The value to search for. + * @returns {boolean} Returns `true` if `target` is found, else `false`. + */ + function arrayIncludes(array, value) { + var length = array == null ? 0 : array.length; + 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 inspect. + * @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 == null ? 0 : array.length; + + 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 == null ? 0 : array.length, + 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 == null ? 0 : array.length; + + 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 == null ? 0 : array.length; + 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 == null ? 0 : array.length; + + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } + + /** + * Gets the size of an ASCII `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + var asciiSize = baseProperty('length'); + + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } + + /** + * Splits an ASCII `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function asciiWords(string) { + return string.match(reAsciiWord) || []; + } + + /** + * 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 inspect. + * @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 inspect. + * @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 inspect. + * @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) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** + * This function is like `baseIndexOf` except that it accepts a comparator. + * + * @private + * @param {Array} array The array to inspect. + * @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 == null ? 0 : array.length; + 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 Supplement and Latin Extended-A + * 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 `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** + * Checks if `string` contains a word composed of Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a word is found, else `false`. + */ + function hasUnicodeWord(string) { + return reHasUnicodeWord.test(string); + } + + /** + * 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 unary function that invokes `func` with its 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; + } + + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @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 strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } + + /** + * A specialized version of `_.lastIndexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @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 strictLastIndexOf(array, value, fromIndex) { + var index = fromIndex + 1; + while (index--) { + if (array[index] === value) { + return index; + } + } + return index; + } + + /** + * Gets the number of symbols in `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the string size. + */ + function stringSize(string) { + return hasUnicode(string) + ? unicodeSize(string) + : asciiSize(string); + } + + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } + + /** + * 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); + + /** + * Gets the size of a Unicode `string`. + * + * @private + * @param {string} string The string inspect. + * @returns {number} Returns the string size. + */ + function unicodeSize(string) { + var result = reUnicode.lastIndex = 0; + while (reUnicode.test(string)) { + ++result; + } + return result; + } + + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } + + /** + * Splits a Unicode `string` into an array of its words. + * + * @private + * @param {string} The string to inspect. + * @returns {Array} Returns the words of `string`. + */ + function unicodeWords(string) { + return string.match(reUnicodeWord) || []; + } + + /*--------------------------------------------------------------------------*/ + + /** + * 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 + * + * // Create a suped-up `defer` in Node.js. + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + var runInContext = (function runInContext(context) { + context = context == null ? root : _.defaults(root.Object(), context, _.pick(root, contextProps)); + + /** Built-in constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; + + /** Used for built-in method references. */ + var arrayProto = Array.prototype, + funcProto = Function.prototype, + objectProto = Object.prototype; + + /** Used to detect overreaching core-js shims. */ + var coreJsData = context['__core-js_shared__']; + + /** Used to resolve the decompiled source of functions. */ + var funcToString = funcProto.toString; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** Used to generate unique IDs. */ + var idCounter = 0; + + /** 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 + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; + + /** Used to infer the `Object` constructor. */ + var objectCtorString = funcToString.call(Object); + + /** 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, + Symbol = context.Symbol, + Uint8Array = context.Uint8Array, + allocUnsafe = Buffer ? Buffer.allocUnsafe : undefined, + getPrototype = overArg(Object.getPrototypeOf, Object), + objectCreate = Object.create, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + splice = arrayProto.splice, + spreadableSymbol = Symbol ? Symbol.isConcatSpreadable : undefined, + symIterator = Symbol ? Symbol.iterator : undefined, + symToStringTag = Symbol ? Symbol.toStringTag : undefined; + + var defineProperty = (function() { + try { + var func = getNative(Object, 'defineProperty'); + func({}, '', {}); + return func; + } catch (e) {} + }()); + + /** Mocked built-ins. */ + var ctxClearTimeout = context.clearTimeout !== root.clearTimeout && context.clearTimeout, + ctxNow = Date && Date.now !== root.Date.now && Date.now, + ctxSetTimeout = context.setTimeout !== root.setTimeout && context.setTimeout; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil, + nativeFloor = Math.floor, + nativeGetSymbols = Object.getOwnPropertySymbols, + nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined, + nativeIsFinite = context.isFinite, + nativeJoin = arrayProto.join, + nativeKeys = overArg(Object.keys, Object), + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = Date.now, + nativeParseInt = context.parseInt, + nativeRandom = Math.random, + nativeReverse = arrayProto.reverse; + + /* 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(Object, 'create'); + + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; + + /** 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 and 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 base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} proto The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function object() {} + return function(proto) { + if (!isObject(proto)) { + return {}; + } + if (objectCreate) { + return objectCreate(proto); + } + object.prototype = proto; + var result = new object; + object.prototype = undefined; + return result; + }; + }()); + + /** + * 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) as well as ES2015 template strings. 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 || (!isRight && 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 == null ? 0 : entries.length; + + 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) : {}; + this.size = 0; + } + + /** + * 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) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + + /** + * 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__; + this.size += this.has(key) ? 0 : 1; + 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 == null ? 0 : entries.length; + + 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__ = []; + this.size = 0; + } + + /** + * 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); + } + --this.size; + 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) { + ++this.size; + 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 == null ? 0 : entries.length; + + 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.size = 0; + 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) { + var result = getMapData(this, key)['delete'](key); + this.size -= result ? 1 : 0; + return result; + } + + /** + * 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) { + var data = getMapData(this, key), + size = data.size; + + data.set(key, value); + this.size += data.size == size ? 0 : 1; + 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 == null ? 0 : values.length; + + 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) { + var data = this.__data__ = new ListCache(entries); + this.size = data.size; + } + + /** + * Removes all key-value entries from the stack. + * + * @private + * @name clear + * @memberOf Stack + */ + function stackClear() { + this.__data__ = new ListCache; + this.size = 0; + } + + /** + * 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) { + var data = this.__data__, + result = data['delete'](key); + + this.size = data.size; + return result; + } + + /** + * 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 data = this.__data__; + if (data instanceof ListCache) { + var pairs = data.__data__; + if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) { + pairs.push([key, value]); + this.size = ++data.size; + return this; + } + data = this.__data__ = new MapCache(pairs); + } + data.set(key, value); + this.size = data.size; + 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; + + /*------------------------------------------------------------------------*/ + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } + } + return result; + } + + /** + * A specialized version of `_.sample` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @returns {*} Returns the random element. + */ + function arraySample(array) { + var length = array.length; + return length ? array[baseRandom(0, length - 1)] : undefined; + } + + /** + * A specialized version of `_.sampleSize` for arrays. + * + * @private + * @param {Array} array The array to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ + function arraySampleSize(array, n) { + return shuffleSelf(copyArray(array), baseClamp(n, 0, array.length)); + } + + /** + * A specialized version of `_.shuffle` for arrays. + * + * @private + * @param {Array} array The array to shuffle. + * @returns {Array} Returns the new shuffled array. + */ + function arrayShuffle(array) { + return shuffleSelf(copyArray(array)); + } + + /** + * 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)) || + (value === undefined && !(key in object))) { + baseAssignValue(object, key, value); + } + } + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.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))) { + baseAssignValue(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 inspect. + * @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 `_.assignIn` 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 baseAssignIn(object, source) { + return object && copyObject(source, keysIn(source), object); + } + + /** + * The base implementation of `assignValue` and `assignMergeValue` without + * value checks. + * + * @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 baseAssignValue(object, key, value) { + if (key == '__proto__' && defineProperty) { + defineProperty(object, key, { + 'configurable': true, + 'enumerable': true, + 'value': value, + 'writable': true + }); + } else { + object[key] = value; + } + } + + /** + * 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 to pick. + * @returns {Array} Returns the picked elements. + */ + function baseAt(object, paths) { + var index = -1, + length = paths.length, + result = Array(length), + skip = object == null; + + while (++index < length) { + result[index] = skip ? 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} bitmask The bitmask flags. + * 1 - Deep clone + * 2 - Flatten inherited properties + * 4 - Clone 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, bitmask, customizer, key, object, stack) { + var result, + isDeep = bitmask & CLONE_DEEP_FLAG, + isFlat = bitmask & CLONE_FLAT_FLAG, + isFull = bitmask & CLONE_SYMBOLS_FLAG; + + 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)) { + result = (isFlat || isFunc) ? {} : initCloneObject(value); + if (!isDeep) { + return isFlat + ? copySymbolsIn(value, baseAssignIn(result, value)) + : copySymbols(value, baseAssign(result, value)); + } + } else { + if (!cloneableTags[tag]) { + return object ? value : {}; + } + result = initCloneByTag(value, tag, 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 (isSet(value)) { + value.forEach(function(subValue) { + result.add(baseClone(subValue, bitmask, customizer, subValue, value, stack)); + }); + } else if (isMap(value)) { + value.forEach(function(subValue, key) { + result.set(key, baseClone(subValue, bitmask, customizer, key, value, stack)); + }); + } + + var keysFunc = isFull + ? (isFlat ? getAllKeysIn : getAllKeys) + : (isFlat ? keysIn : keys); + + var props = isArr ? undefined : keysFunc(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, bitmask, 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; + } + object = Object(object); + while (length--) { + var key = props[length], + predicate = source[key], + value = object[key]; + + if ((value === undefined && !(key in object)) || !predicate(value)) { + return false; + } + } + return true; + } + + /** + * 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|Object} Returns the timer id or timeout object. + */ + 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 == null ? value : iteratee(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 = castPath(path, object); + + 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` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(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) { + return object != null && hasOwnProperty.call(object, key); + } + + /** + * 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) { + path = castPath(path, object); + object = parent(object, path); + var func = object == null ? object : object[toKey(last(path))]; + return func == null ? undefined : apply(func, object, args); + } + + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; + } + + /** + * 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) && baseGetTag(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) && baseGetTag(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 {boolean} bitmask The bitmask flags. + * 1 - Unordered comparison + * 2 - Partial comparison + * @param {Function} [customizer] The function to customize comparisons. + * @param {Object} [stack] Tracks traversed `value` and `other` objects. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + */ + function baseIsEqual(value, other, bitmask, customizer, stack) { + if (value === other) { + return true; + } + if (value == null || other == null || (!isObjectLike(value) && !isObjectLike(other))) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, 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 {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} [stack] Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function baseIsEqualDeep(object, other, bitmask, customizer, equalFunc, stack) { + var objIsArr = isArray(object), + othIsArr = isArray(other), + objTag = objIsArr ? arrayTag : getTag(object), + othTag = othIsArr ? arrayTag : getTag(other); + + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + + var objIsObj = objTag == objectTag, + othIsObj = othTag == objectTag, + isSameTag = objTag == othTag; + + if (isSameTag && isBuffer(object)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack || (stack = new Stack); + return (objIsArr || isTypedArray(object)) + ? equalArrays(object, other, bitmask, customizer, equalFunc, stack) + : equalByTag(object, other, objTag, bitmask, customizer, equalFunc, stack); + } + if (!(bitmask & COMPARE_PARTIAL_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, bitmask, customizer, stack); + } + } + if (!isSameTag) { + return false; + } + stack || (stack = new Stack); + return equalObjects(object, other, bitmask, customizer, equalFunc, 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, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_FLAG, customizer, 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) ? 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 isObjectLike(value) && baseGetTag(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[baseGetTag(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 treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; + } + + /** + * The base implementation of `_.keysIn` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeysIn(object) { + if (!isObject(object)) { + return nativeKeysIn(object); + } + var isProto = isPrototype(object), + result = []; + + for (var key in object) { + if (!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); + } + } + return result; + } + + /** + * 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, COMPARE_PARTIAL_FLAG | COMPARE_UNORDERED_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; + } + baseFor(source, function(srcValue, key) { + stack || (stack = new Stack); + if (isObject(srcValue)) { + baseMergeDeep(object, source, key, srcIndex, baseMerge, customizer, stack); + } + else { + var newValue = customizer + ? customizer(safeGet(object, key), srcValue, (key + ''), object, source, stack) + : undefined; + + if (newValue === undefined) { + newValue = srcValue; + } + assignMergeValue(object, key, newValue); + } + }, keysIn); + } + + /** + * 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 = safeGet(object, key), + srcValue = safeGet(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) { + var isArr = isArray(srcValue), + isBuff = !isArr && isBuffer(srcValue), + isTyped = !isArr && !isBuff && isTypedArray(srcValue); + + newValue = srcValue; + if (isArr || isBuff || isTyped) { + if (isArray(objValue)) { + newValue = objValue; + } + else if (isArrayLikeObject(objValue)) { + newValue = copyArray(objValue); + } + else if (isBuff) { + isCommon = false; + newValue = cloneBuffer(srcValue, true); + } + else if (isTyped) { + isCommon = false; + newValue = cloneTypedArray(srcValue, true); + } + else { + newValue = []; + } + } + else if (isPlainObject(srcValue) || isArguments(srcValue)) { + newValue = objValue; + if (isArguments(objValue)) { + newValue = toPlainObject(objValue); + } + else if (!isObject(objValue) || isFunction(objValue)) { + newValue = initCloneObject(srcValue); + } + } + 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) { + if (iteratees.length) { + iteratees = arrayMap(iteratees, function(iteratee) { + if (isArray(iteratee)) { + return function(value) { + return baseGet(value, iteratee.length === 1 ? iteratee[0] : iteratee); + } + } + return iteratee; + }); + } else { + iteratees = [identity]; + } + + var index = -1; + iteratees = arrayMap(iteratees, 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[]} paths The property paths to pick. + * @returns {Object} Returns the new object. + */ + function basePick(object, paths) { + return basePickBy(object, paths, function(value, path) { + return hasIn(object, path); + }); + } + + /** + * The base implementation of `_.pickBy` without support for iteratee shorthands. + * + * @private + * @param {Object} object The source object. + * @param {string[]} paths The property paths to pick. + * @param {Function} predicate The function invoked per property. + * @returns {Object} Returns the new object. + */ + function basePickBy(object, paths, predicate) { + var index = -1, + length = paths.length, + result = {}; + + while (++index < length) { + var path = paths[index], + value = baseGet(object, path); + + if (predicate(value, path)) { + baseSet(result, castPath(path, object), 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 { + baseUnset(array, 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) { + return setToString(overRest(func, start, identity), func + ''); + } + + /** + * The base implementation of `_.sample`. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @returns {*} Returns the random element. + */ + function baseSample(collection) { + return arraySample(values(collection)); + } + + /** + * The base implementation of `_.sampleSize` without param guards. + * + * @private + * @param {Array|Object} collection The collection to sample. + * @param {number} n The number of elements to sample. + * @returns {Array} Returns the random elements. + */ + function baseSampleSize(collection, n) { + var array = values(collection); + return shuffleSelf(array, baseClamp(n, 0, array.length)); + } + + /** + * The base implementation of `_.set`. + * + * @private + * @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 path creation. + * @returns {Object} Returns `object`. + */ + function baseSet(object, path, value, customizer) { + if (!isObject(object)) { + return object; + } + path = castPath(path, object); + + var index = -1, + length = path.length, + lastIndex = length - 1, + nested = object; + + while (nested != null && ++index < length) { + var key = toKey(path[index]), + newValue = value; + + if (key === '__proto__' || key === 'constructor' || key === 'prototype') { + return object; + } + + if (index != lastIndex) { + var objValue = nested[key]; + newValue = customizer ? customizer(objValue, key, nested) : undefined; + if (newValue === undefined) { + newValue = isObject(objValue) + ? objValue + : (isIndex(path[index + 1]) ? [] : {}); + } + } + assignValue(nested, key, newValue); + nested = nested[key]; + } + return object; + } + + /** + * The base implementation of `setData` without support for hot loop shorting. + * + * @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 `setToString` without support for hot loop shorting. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var baseSetToString = !defineProperty ? identity : function(func, string) { + return defineProperty(func, 'toString', { + 'configurable': true, + 'enumerable': false, + 'value': constant(string), + 'writable': true + }); + }; + + /** + * The base implementation of `_.shuffle`. + * + * @private + * @param {Array|Object} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + */ + function baseShuffle(collection) { + return shuffleSelf(values(collection)); + } + + /** + * 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 == null ? low : array.length; + + 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) { + var low = 0, + high = array == null ? 0 : array.length; + if (high === 0) { + return 0; + } + + value = iteratee(value); + var 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 (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + 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 property path to unset. + * @returns {boolean} Returns `true` if the property is deleted, else `false`. + */ + function baseUnset(object, path) { + path = castPath(path, object); + object = parent(object, path); + return object == null || delete object[toKey(last(path))]; + } + + /** + * The base implementation of `_.update`. + * + * @private + * @param {Object} object The object to modify. + * @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 length = arrays.length; + if (length < 2) { + return length ? baseUniq(arrays[0]) : []; + } + var index = -1, + result = Array(length); + + while (++index < length) { + var array = arrays[index], + othIndex = -1; + + while (++othIndex < length) { + if (othIndex != index) { + result[index] = baseDifference(result[index] || array, arrays[othIndex], iteratee, comparator); + } + } + } + return baseUniq(baseFlatten(result, 1), 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. + * @param {Object} [object] The object to query keys on. + * @returns {Array} Returns the cast property path array. + */ + function castPath(value, object) { + if (isArray(value)) { + return value; + } + return isKey(value, object) ? [value] : stringToPath(toString(value)); + } + + /** + * A `baseRest` alias which can be replaced with `identity` by module + * replacement plugins. + * + * @private + * @type {Function} + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + var castRest = baseRest; + + /** + * 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); + } + + /** + * A simple wrapper around the global [`clearTimeout`](https://mdn.io/clearTimeout). + * + * @private + * @param {number|Object} id The timer id or timeout object of the timer to clear. + */ + var clearTimeout = ctxClearTimeout || function(id) { + return root.clearTimeout(id); + }; + + /** + * 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 length = buffer.length, + result = allocUnsafe ? allocUnsafe(length) : new buffer.constructor(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 `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 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) { + var isNew = !object; + 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; + + if (newValue === undefined) { + newValue = source[key]; + } + if (isNew) { + baseAssignValue(object, key, newValue); + } else { + assignValue(object, key, newValue); + } + } + return object; + } + + /** + * Copies own symbols 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); + } + + /** + * Copies own and inherited symbols 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 copySymbolsIn(source, object) { + return copyObject(source, getSymbolsIn(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 & WRAP_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 = hasUnicode(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/7.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 flatRest(function(funcs) { + 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] == (WRAP_ARY_FLAG | WRAP_CURRY_FLAG | WRAP_PARTIAL_FLAG | WRAP_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)) { + 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 & WRAP_ARY_FLAG, + isBind = bitmask & WRAP_BIND_FLAG, + isBindKey = bitmask & WRAP_BIND_KEY_FLAG, + isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG), + isFlip = bitmask & WRAP_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 flatRest(function(iteratees) { + iteratees = arrayMap(iteratees, 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 hasUnicode(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 & WRAP_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 & WRAP_CURRY_FLAG, + newHolders = isCurry ? holders : undefined, + newHoldersRight = isCurry ? undefined : holders, + newPartials = isCurry ? partials : undefined, + newPartialsRight = isCurry ? undefined : partials; + + bitmask |= (isCurry ? WRAP_PARTIAL_FLAG : WRAP_PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? WRAP_PARTIAL_RIGHT_FLAG : WRAP_PARTIAL_FLAG); + + if (!(bitmask & WRAP_CURRY_BOUND_FLAG)) { + bitmask &= ~(WRAP_BIND_FLAG | WRAP_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 = precision == null ? 0 : nativeMin(toInteger(precision), 292); + if (precision && nativeIsFinite(number)) { + // 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. + * 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 & WRAP_BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(WRAP_PARTIAL_FLAG | WRAP_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 & WRAP_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] === undefined + ? (isBindKey ? 0 : func.length) + : nativeMax(newData[9] - length, 0); + + if (!arity && bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG)) { + bitmask &= ~(WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG); + } + if (!bitmask || bitmask == WRAP_BIND_FLAG) { + var result = createBind(func, bitmask, thisArg); + } else if (bitmask == WRAP_CURRY_FLAG || bitmask == WRAP_CURRY_RIGHT_FLAG) { + result = createCurry(func, bitmask, arity); + } else if ((bitmask == WRAP_PARTIAL_FLAG || bitmask == (WRAP_BIND_FLAG | WRAP_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); + } + + /** + * Used by `_.defaults` to customize its `_.assignIn` use to assign properties + * of source objects to the destination object for all destination properties + * that resolve to `undefined`. + * + * @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 customDefaultsAssignIn(objValue, srcValue, key, object) { + if (objValue === undefined || + (eq(objValue, objectProto[key]) && !hasOwnProperty.call(object, key))) { + return srcValue; + } + return objValue; + } + + /** + * Used by `_.defaultsDeep` to customize its `_.merge` use to merge source + * objects into destination objects that are passed thru. + * + * @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 customDefaultsMerge(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, customDefaultsMerge, stack); + stack['delete'](srcValue); + } + return objValue; + } + + /** + * Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain + * objects. + * + * @private + * @param {*} value The value to inspect. + * @param {string} key The key of the property to inspect. + * @returns {*} Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`. + */ + function customOmitClone(value) { + return isPlainObject(value) ? undefined : value; + } + + /** + * 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 {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `array` and `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + arrLength = array.length, + othLength = other.length; + + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + // Check that cyclic values are equal. + var arrStacked = stack.get(array); + var othStacked = stack.get(other); + if (arrStacked && othStacked) { + return arrStacked == other && othStacked == array; + } + var index = -1, + result = true, + seen = (bitmask & COMPARE_UNORDERED_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 (!cacheHas(seen, othIndex) && + (arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!( + arrValue === othValue || + equalFunc(arrValue, othValue, bitmask, customizer, 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 {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @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, bitmask, customizer, equalFunc, 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/7.0/#sec-regexp.prototype.tostring + // for more details. + return object == (other + ''); + + case mapTag: + var convert = mapToArray; + + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_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 |= COMPARE_UNORDERED_FLAG; + + // Recursively compare objects (susceptible to call stack limits). + stack.set(object, other); + var result = equalArrays(convert(object), convert(other), bitmask, customizer, equalFunc, 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 {number} bitmask The bitmask flags. See `baseIsEqual` for more details. + * @param {Function} customizer The function to customize comparisons. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Object} stack Tracks traversed `object` and `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalObjects(object, other, bitmask, customizer, equalFunc, stack) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, + objProps = getAllKeys(object), + objLength = objProps.length, + othProps = getAllKeys(other), + othLength = othProps.length; + + if (objLength != othLength && !isPartial) { + return false; + } + var index = objLength; + while (index--) { + var key = objProps[index]; + if (!(isPartial ? key in other : hasOwnProperty.call(other, key))) { + return false; + } + } + // Check that cyclic values are equal. + var objStacked = stack.get(object); + var othStacked = stack.get(other); + if (objStacked && othStacked) { + return objStacked == other && othStacked == object; + } + 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, bitmask, customizer, 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; + } + + /** + * A specialized version of `baseRest` which flattens the rest array. + * + * @private + * @param {Function} func The function to apply a rest parameter to. + * @returns {Function} Returns the new function. + */ + function flatRest(func) { + return setToString(overRest(func, undefined, flatten), func + ''); + } + + /** + * 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 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; + } + + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag), + tag = value[symToStringTag]; + + try { + value[symToStringTag] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + + /** + * Creates an array of the own enumerable symbols of `object`. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. + */ + var getSymbols = !nativeGetSymbols ? stubArray : function(object) { + if (object == null) { + return []; + } + object = Object(object); + return arrayFilter(nativeGetSymbols(object), function(symbol) { + return propertyIsEnumerable.call(object, symbol); + }); + }; + + /** + * Creates an array of the own and inherited enumerable symbols 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 and promises in Node.js < 6. + 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 = baseGetTag(value), + Ctor = result == objectTag ? value.constructor : undefined, + ctorString = Ctor ? toSource(Ctor) : ''; + + 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 = castPath(path, object); + + var index = -1, + length = path.length, + result = false; + + while (++index < length) { + var key = toKey(path[index]); + if (!(result = object != null && hasFunc(object, key))) { + break; + } + object = object[key]; + } + if (result || ++index != length) { + return result; + } + length = object == null ? 0 : object.length; + return !!length && isLength(length) && isIndex(key, length) && + (isArray(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 = new 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`, `Map`, `Number`, `RegExp`, `Set`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @returns {Object} Returns the initialized clone. + */ + function initCloneByTag(object, tag, 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 new Ctor; + + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + return cloneRegExp(object); + + case setTag: + return new Ctor; + + case symbolTag: + return cloneSymbol(object); + } + } + + /** + * 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; + if (!length) { + return source; + } + var 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) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && 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))); + }; + } + + /** + * A specialized version of `_.memoize` which clears the memoized function's + * cache when it exceeds `MAX_MEMOIZE_SIZE`. + * + * @private + * @param {Function} func The function to have its output memoized. + * @returns {Function} Returns the new memoized function. + */ + function memoizeCapped(func) { + var result = memoize(func, function(key) { + if (cache.size === MAX_MEMOIZE_SIZE) { + cache.clear(); + } + return key; + }); + + var cache = result.cache; + return result; + } + + /** + * 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 < (WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG | WRAP_ARY_FLAG); + + var isCombo = + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_CURRY_FLAG)) || + ((srcBitmask == WRAP_ARY_FLAG) && (bitmask == WRAP_REARG_FLAG) && (data[7].length <= source[8])) || + ((srcBitmask == (WRAP_ARY_FLAG | WRAP_REARG_FLAG)) && (source[7].length <= source[8]) && (bitmask == WRAP_CURRY_FLAG)); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; + } + // Use source `thisArg` if available. + if (srcBitmask & WRAP_BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= bitmask & WRAP_BIND_FLAG ? 0 : WRAP_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 & WRAP_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; + } + + /** + * This function is like + * [`Object.keys`](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * except that it includes inherited enumerable properties. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function nativeKeysIn(object) { + var result = []; + if (object != null) { + for (var key in Object(object)) { + result.push(key); + } + } + return result; + } + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString.call(value); + } + + /** + * A specialized version of `baseRest` which transforms the rest array. + * + * @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. + * @param {Function} transform The rest array transform. + * @returns {Function} Returns the new function. + */ + function overRest(func, start, transform) { + 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] = transform(array); + return apply(func, this, otherArgs); + }; + } + + /** + * 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 < 2 ? 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; + } + + /** + * Gets the value at `key`, unless `key` is "__proto__" or "constructor". + * + * @private + * @param {Object} object The object to query. + * @param {string} key The key of the property to get. + * @returns {*} Returns the property value. + */ + function safeGet(object, key) { + if (key === 'constructor' && typeof object[key] === 'function') { + return; + } + + if (key == '__proto__') { + return; + } + + return object[key]; + } + + /** + * 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 = shortOut(baseSetData); + + /** + * A simple wrapper around the global [`setTimeout`](https://mdn.io/setTimeout). + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @returns {number|Object} Returns the timer id or timeout object. + */ + var setTimeout = ctxSetTimeout || function(func, wait) { + return root.setTimeout(func, wait); + }; + + /** + * Sets the `toString` method of `func` to return `string`. + * + * @private + * @param {Function} func The function to modify. + * @param {Function} string The `toString` result. + * @returns {Function} Returns `func`. + */ + var setToString = shortOut(baseSetToString); + + /** + * 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`. + */ + function setWrapToString(wrapper, reference, bitmask) { + var source = (reference + ''); + return setToString(wrapper, insertWrapDetails(source, updateWrapDetails(getWrapDetails(source), bitmask))); + } + + /** + * Creates a function that'll short out and invoke `identity` instead + * of `func` when it's called `HOT_COUNT` or more times in `HOT_SPAN` + * milliseconds. + * + * @private + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new shortable function. + */ + function shortOut(func) { + var count = 0, + lastCalled = 0; + + return function() { + var stamp = nativeNow(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return arguments[0]; + } + } else { + count = 0; + } + return func.apply(undefined, arguments); + }; + } + + /** + * A specialized version of `_.shuffle` which mutates and sets the size of `array`. + * + * @private + * @param {Array} array The array to shuffle. + * @param {number} [size=array.length] The size of `array`. + * @returns {Array} Returns `array`. + */ + function shuffleSelf(array, size) { + var index = -1, + length = array.length, + lastIndex = length - 1; + + size = size === undefined ? length : size; + while (++index < size) { + var rand = baseRandom(index, lastIndex), + value = array[rand]; + + array[rand] = array[index]; + array[index] = value; + } + array.length = size; + return array; + } + + /** + * Converts `string` to a property path array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the property path array. + */ + var stringToPath = memoizeCapped(function(string) { + var result = []; + if (string.charCodeAt(0) === 46 /* . */) { + result.push(''); + } + string.replace(rePropName, function(match, number, quote, subString) { + result.push(quote ? subString.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 convert. + * @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 == null ? 0 : array.length; + 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 == null ? 0 : array.length, + 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; + if (!length) { + return []; + } + var args = Array(length - 1), + array = arguments[0], + index = length; + + while (index--) { + args[index - 1] = arguments[index]; + } + return 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/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by 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. The order and references of result values are + * determined by 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`. The order and + * references of result values are determined by 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 == null ? 0 : array.length; + 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 == null ? 0 : array.length; + 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 == null ? 0 : array.length; + 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 inspect. + * @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 == null ? 0 : array.length; + 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 inspect. + * @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 == null ? 0 : array.length; + 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 == null ? 0 : array.length; + 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 == null ? 0 : array.length; + 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 == null ? 0 : array.length; + 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 == null ? 0 : pairs.length, + 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/7.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 inspect. + * @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 == null ? 0 : array.length; + 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) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 0, -1) : []; + } + + /** + * Creates an array of unique values that are included in all given arrays + * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero) + * for equality comparisons. The order and references of result values are + * determined by 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. The order and references of result values are + * determined by 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`. The order and references + * of result values are determined by 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); + + comparator = typeof comparator == 'function' ? comparator : undefined; + if (comparator) { + 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 == null ? '' : 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 == null ? 0 : array.length; + 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 inspect. + * @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 == null ? 0 : array.length; + if (!length) { + return -1; + } + var index = length; + if (fromIndex !== undefined) { + index = toInteger(fromIndex); + index = index < 0 ? nativeMax(length + index, 0) : nativeMin(index, length - 1); + } + return value === value + ? strictLastIndexOf(array, value, index) + : baseFindIndex(array, baseIsNaN, index, true); + } + + /** + * 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/7.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 = flatRest(function(array, indexes) { + var length = array == null ? 0 : array.length, + 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 == null ? array : nativeReverse.call(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 == null ? 0 : array.length; + 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 inspect. + * @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 == null ? 0 : array.length; + 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 inspect. + * @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 == null ? 0 : array.length; + 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) { + var length = array == null ? 0 : array.length; + return length ? baseSlice(array, 1, length) : []; + } + + /** + * 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 == null ? 0 : array.length; + 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/7.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); + comparator = typeof comparator == 'function' ? 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/7.0/#sec-samevaluezero) + * for equality comparisons, in which only the first occurrence of each element + * is kept. The order of result values is determined by the order they occur + * in the array. + * + * @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 order of result values is determined by the + * order they occur in the array. 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 order of result values is + * determined by the order they occur in the 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) { + comparator = typeof comparator == 'function' ? comparator : undefined; + 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/7.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 order of result values is determined + * by the order they occur in the arrays. 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 order of result values is + * determined by the order they occur in the 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); + comparator = typeof comparator == 'function' ? 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 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 = flatRest(function(paths) { + 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) { + if (hasOwnProperty.call(result, key)) { + ++result[key]; + } else { + baseAssignValue(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). + * + * **Note:** This method returns `true` for + * [empty collections](https://en.wikipedia.org/wiki/Empty_set) because + * [everything is true](https://en.wikipedia.org/wiki/Vacuous_truth) of + * elements of empty collections. + * + * @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'] + * + * // Combining several predicates using `_.overEvery` or `_.overSome`. + * _.filter(users, _.overSome([{ 'age': 36 }, ['age', 40]])); + * // => objects for ['fred', '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 inspect. + * @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 inspect. + * @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 + * + * _.forEach([1, 2], 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 { + baseAssignValue(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/7.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 inspect. + * @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', + result = isArrayLike(collection) ? Array(collection.length) : []; + + baseEach(collection, function(value) { + result[++index] = isFunc ? apply(path, 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) { + baseAssignValue(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 func = isArray(collection) ? arraySample : baseSample; + return func(collection); + } + + /** + * 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) { + if ((guard ? isIterateeCall(collection, n, guard) : n === undefined)) { + n = 1; + } else { + n = toInteger(n); + } + var func = isArray(collection) ? arraySampleSize : baseSampleSize; + return func(collection, n); + } + + /** + * 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) { + var func = isArray(collection) ? arrayShuffle : baseShuffle; + return func(collection); + } + + /** + * 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|string} 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)) { + return isString(collection) ? stringSize(collection) : collection.length; + } + var tag = getTag(collection); + if (tag == mapTag || tag == setTag) { + return collection.size; + } + return baseKeys(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': 30 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.sortBy(users, [function(o) { return o.user; }]); + * // => objects for [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 30]] + * + * _.sortBy(users, ['user', 'age']); + * // => objects for [['barney', 34], ['barney', 36], ['fred', 30], ['fred', 48]] + */ + 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. + */ + var now = ctxNow || function() { + return root.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, WRAP_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 = WRAP_BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bind)); + bitmask |= WRAP_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 = WRAP_BIND_FLAG | WRAP_BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, getHolder(bindKey)); + bitmask |= WRAP_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, WRAP_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, WRAP_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, + timeWaiting = wait - timeSinceLastCall; + + return maxing + ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) + : timeWaiting; + } + + 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. + clearTimeout(timerId); + 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 millisecond. + */ + 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, WRAP_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/7.0/#sec-properties-of-the-map-prototype-object) + * method interface of `clear`, `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 != null && 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) || cache; + return result; + }; + memoized.cache = new (memoize.Cache || MapCache); + return memoized; + } + + // Expose `MapCache`. + 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 = castRest(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, WRAP_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, WRAP_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 = flatRest(function(func, indexes) { + return createWrap(func, WRAP_REARG_FLAG, undefined, undefined, undefined, indexes); + }); + + /** + * 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/7.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 == null ? 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 '

    ' + func(text) + '

    '; + * }); + * + * p('fred, barney, & pebbles'); + * // => '

    fred, barney, & pebbles

    ' + */ + function wrap(value, wrapper) { + return partial(castFunction(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, CLONE_SYMBOLS_FLAG); + } + + /** + * 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) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_SYMBOLS_FLAG, 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, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG); + } + + /** + * 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) { + customizer = typeof customizer == 'function' ? customizer : undefined; + return baseClone(value, CLONE_DEEP_FLAG | CLONE_SYMBOLS_FLAG, 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/7.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 + */ + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); + }; + + /** + * 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(value.length) && !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) && baseGetTag(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(''); + * // => false + */ + function isElement(value) { + return isObjectLike(value) && value.nodeType === 1 && !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 (value == null) { + return true; + } + if (isArrayLike(value) && + (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' || + isBuffer(value) || isTypedArray(value) || isArguments(value))) { + return !value.length; + } + var tag = getTag(value); + if (tag == mapTag || tag == setTag) { + return !value.size; + } + if (isPrototype(value)) { + return !baseKeys(value).length; + } + for (var key in value) { + if (hasOwnProperty.call(value, key)) { + return false; + } + } + return true; + } + + /** + * 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 compared by strict equality, i.e. `===`. + * + * @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, undefined, 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; + } + var tag = baseGetTag(value); + return tag == errorTag || tag == domExcTag || + (typeof value.message == 'string' && typeof value.name == 'string' && !isPlainObject(value)); + } + + /** + * 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) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; + } + + /** + * 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 method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.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/7.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 != null && (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 != null && 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 is equivalent to `_.matches` when `source` is + * partially applied. + * + * Partial comparisons will match empty array and empty object `source` + * values against any array or object value, respectively. See `_.isEqual` + * for a list of supported value comparisons. + * + * @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(CORE_ERROR_TEXT); + } + 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) && baseGetTag(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) || baseGetTag(value) != objectTag) { + 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) && baseGetTag(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) && baseGetTag(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) && baseGetTag(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 (symIterator && value[symIterator]) { + return iteratorToArray(value[symIterator]()); + } + 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/7.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/7.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 = typeof value.valueOf == 'function' ? 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 value + ? baseClamp(toInteger(value), -MAX_SAFE_INTEGER, MAX_SAFE_INTEGER) + : (value === 0 ? value : 0); + } + + /** + * 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 convert. + * @returns {string} Returns the converted 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 (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) { + copyObject(source, keysIn(source), object); + }); + + /** + * 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 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 = flatRest(baseAt); + + /** + * 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 == null ? result : baseAssign(result, properties); + } + + /** + * 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(object, sources) { + object = Object(object); + + var index = -1; + var length = sources.length; + var guard = length > 2 ? sources[2] : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + length = 1; + } + + while (++index < length) { + var source = sources[index]; + var props = keysIn(source); + var propsIndex = -1; + var propsLength = props.length; + + while (++propsIndex < propsLength) { + var key = props[propsIndex]; + var value = object[key]; + + if (value === undefined || + (eq(value, objectProto[key]) && !hasOwnProperty.call(object, key))) { + object[key] = source[key]; + } + } + } + + return object; + }); + + /** + * 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, customDefaultsMerge); + 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 inspect. + * @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 inspect. + * @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) { + if (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + 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 (value != null && + typeof value.toString != 'function') { + value = nativeObjectToString.call(value); + } + + 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/7.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) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } + + /** + * 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) { + return isArrayLike(object) ? arrayLikeKeys(object, true) : baseKeysIn(object); + } + + /** + * 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) { + baseAssignValue(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) { + baseAssignValue(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 six 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 property paths of `object` that are not omitted. + * + * **Note:** This method is considerably slower than `_.pick`. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The source object. + * @param {...(string|string[])} [paths] The property paths 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 = flatRest(function(object, paths) { + var result = {}; + if (object == null) { + return result; + } + var isDeep = false; + paths = arrayMap(paths, function(path) { + path = castPath(path, object); + isDeep || (isDeep = path.length > 1); + return path; + }); + copyObject(object, getAllKeysIn(object), result); + if (isDeep) { + result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone); + } + var length = paths.length; + while (length--) { + baseUnset(result, paths[length]); + } + return result; + }); + + /** + * 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[])} [paths] The property paths 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 = flatRest(function(object, paths) { + return object == null ? {} : basePick(object, paths); + }); + + /** + * 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) { + if (object == null) { + return {}; + } + var props = arrayMap(getAllKeysIn(object), function(prop) { + return [prop]; + }); + predicate = getIteratee(predicate); + return basePickBy(object, props, function(value, path) { + return predicate(value, path[0]); + }); + } + + /** + * 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 = castPath(path, object); + + var index = -1, + length = path.length; + + // Ensure the loop is entered when path is empty. + if (!length) { + length = 1; + object = undefined; + } + 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), + isArrLike = isArr || isBuffer(object) || isTypedArray(object); + + iteratee = getIteratee(iteratee, 4); + if (accumulator == null) { + var Ctor = object && object.constructor; + if (isArrLike) { + accumulator = isArr ? new Ctor : []; + } + else if (isObject(object)) { + accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {}; + } + else { + accumulator = {}; + } + } + (isArrLike ? 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 == null ? [] : 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 Supplement](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) + * and [Latin Extended-A](https://en.wikipedia.org/wiki/Latin_Extended-A) + * letters 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(reLatin, 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 inspect. + * @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. + * + * 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) { + if (guard || radix == null) { + radix = 0; + } else if (radix) { + radix = +radix; + } + return nativeParseInt(toString(string).replace(reTrimStart, ''), radix || 0); + } + + /** + * 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 : string.replace(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 && hasUnicode(string)) { + return castSlice(stringToArray(string), 0, limit); + } + } + return string.split(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 inspect. + * @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 = position == null + ? 0 + : 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('<%- value %>'); + * compiled({ 'value': '