diff --git a/bower.json b/bower.json index 9a7de0f..891cea8 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "grommet", - "version": "0.1.0", + "version": "0.1.1", "main": "grommet.js", "description": "The most advanced UI framework for enterprise applications.", "authors": [ @@ -16,6 +16,13 @@ "type": "git", "url": "https://github.com/HewlettPackard/grommet.git" }, + "preferGlobal": true, + "bin": { + "grommet": "./bin/grommet.js" + }, + "engines": { + "node": ">= 0.9" + }, "dependencies": { "react": "^0.13.1", "grommet": "HewlettPackard/grommet-bower" diff --git a/css/grommet-hpe.css b/css/grommet-hpe.css index 76f45f9..12ab305 100644 --- a/css/grommet-hpe.css +++ b/css/grommet-hpe.css @@ -1,7 +1,7 @@ @charset "UTF-8"; @font-face { font-family: "Metric"; - src: url("~grommet/hpe/font/MetricWeb-Regular.woff") format('woff'); } + src: url("/grommet/scss/hpe/font/MetricWeb-Regular.woff") format('woff'); } /*! * inuitcss, by @csswizardry @@ -505,18 +505,6 @@ img { /* [2] */ max-width: none; } -/*------------------------------------*\ - #PARAGRAPHS -\*------------------------------------*/ -/** - * The `.lede` class is used to make the introductory text (usually a paragraph) - * of a document slightly larger: en.wikipedia.org/wiki/Lede_(news) - */ -.i-lede { - font-size: 18px; - font-size: 1.125rem; - line-height: 1.33333; } - @font-face { font-family: 'Source Sans Pro'; font-style: normal; @@ -743,75 +731,6 @@ html, body { width: 100%; overflow: hidden; } -/*------------------------------------*\ - #LIST-INLINE -\*------------------------------------*/ -/** - * The list-inline object simply displays a list of items in one line. - */ -.i-list-inline { - margin: 0; - padding: 0; - list-style: none; } - .i-list-inline > li { - display: inline-block; } - -/** - * Comma delimited list to semantically mark up lists of tags, etc. - * - * N.B. This component requires that you remove the whitespace between LIs. - * The simplest (and valid) way to achieve this is by omitting the - * closing `` tag. - */ -.i-list-inline--delimited > li + li:before { - content: ",\00A0"; } - -/*------------------------------------*\ - #LIST-BLOCK -\*------------------------------------*/ -/** - * The list-block object creates blocky list items out of a `ul` or `ol`. - */ -.i-list-block { - margin: 0; - padding: 0; - list-style: none; } - -.i-list-block__item, .i-list-block > li { - padding: 24px; } - -/** - * Tiny list-blocks. - */ -.i-list-block--tiny > .i-list-block__item, .i-list-block.i-list-block--tiny > li { - padding: 6px; } - -/** - * Small list-blocks. - */ -.i-list-block--small > .i-list-block__item, .i-list-block.i-list-block--small > li { - padding: 12px; } - -/*------------------------------------*\ - #LIST-UI -\*------------------------------------*/ -/** - * The UI list object creates blocky list items with a keyline separator out of - * a `ul` or `ol`. - */ -.i-list-ui, .i-list-ui__item, .i-list-ui > li { - border: 0 solid #ccc; } - -.i-list-ui { - margin: 0; - padding: 0; - list-style: none; - border-top-width: 1px; } - -.i-list-ui__item, .i-list-ui > li { - padding: 24px; - border-bottom-width: 1px; } - /*------------------------------------*\ #LIST-BARE \*------------------------------------*/ @@ -823,107 +742,6 @@ html, body { padding: 0; list-style: none; } -/*------------------------------------*\ - #BOX -\*------------------------------------*/ -/** - * The box object simply boxes off content. - */ -/** - * 1. So we can apply the `.box` class to naturally-inline elements. - */ -.i-box { - display: block; - /* [1] */ - padding: 24px; } - .i-box > :last-child { - margin-bottom: 0; } - -/** - * Small box. - */ -.i-box--small { - padding: 12px; } - -/*------------------------------------*\ - #PACK -\*------------------------------------*/ -/** - * The pack object simply causes any number of elements pack up horizontally to - * automatically fill an equal, fluid width of their parent. - */ -/** - * 1. Fill all available space. - * 2. Cause children to be automatically equally sized. - */ -.i-pack { - width: 100%; - /* [1] */ - display: table; - table-layout: fixed; - /* [2] */ } - -/** - * Cause children to adopt table-like structure. - */ -.i-pack__item { - display: table-cell; } - -/*------------------------------------*\ - #LAYOUT -\*------------------------------------*/ -/** - * The inuitcss layout system uses `box-sizing: border-box;` and - * `display: inline-block;` to create an extremely powerful, flexible - * alternative to the traditional grid system. Combine the layout items with - * the widths found in `trumps.widths`. - */ -/** - * Begin a layout group. - */ -.i-layout { - list-style: none; - margin: 0; - padding: 0; - margin-left: -24px; } - -/** - * 1. Cause columns to stack side-by-side. - * 2. Space columns apart. - * 3. Align columns to the tops of each other. - * 4. Full-width unless told to behave otherwise. - * 5. Required to combine fluid widths and fixed gutters. - */ -.i-layout__item { - display: inline-block; - /* [1] */ - padding-left: 24px; - /* [2] */ - vertical-align: top; - /* [3] */ - width: 100%; - /* [4] */ } - -/** - * Make the layout items fill up from the center outward. - */ -.i-layout--center { - text-align: center; } - .i-layout--center > .i-layout__item { - text-align: left; } - -/*------------------------------------*\ - #TABLES -\*------------------------------------*/ -.i-table { - width: 100%; } - -/** - * Lightly packed cells. - */ -.i-table--cosy th, .i-table--cosy td { - padding: 12px; } - #loading { position: absolute; width: 100%; @@ -973,34 +791,159 @@ html, body { max-width: none; } .chart { - display: block; } + display: block; + text-align: right; } .chart__grid { stroke: #ccc; } - .chart__lines-line { + .chart__graphic { + width: 100%; } + .chart__values-line { stroke-width: 3px; } - .chart__lines-line.color-index-accent-1, .chart__lines-line.color-index-accent-6 { + .chart__values-line.color-index-error { + stroke: #FF454F; } + .chart__values-line.color-index-warning { + stroke: #F3B237; } + .chart__values-line.color-index-ok { + stroke: #00B388; } + .chart__values-line.color-index-unknown { + stroke: #848484; } + .chart__values-line.color-index-disabled { + stroke: #848484; } + .chart__values-line.color-index-graph-1, .chart__values-line.color-index-graph-6 { stroke: #FF8D6D; } - .chart__lines-line.color-index-accent-2, .chart__lines-line.color-index-accent-7 { + .chart__values-line.color-index-graph-2, .chart__values-line.color-index-graph-7 { stroke: #877B75; } - .chart__lines-line.color-index-accent-3, .chart__lines-line.color-index-accent-8 { + .chart__values-line.color-index-graph-3, .chart__values-line.color-index-graph-8 { stroke: #2AD2C9; } - .chart__lines-line.color-index-accent-4, .chart__lines-line.color-index-accent-9 { + .chart__values-line.color-index-graph-4, .chart__values-line.color-index-graph-9 { stroke: #614767; } - .chart__lines-line.color-index-accent-5, .chart__lines-line.color-index-accent-10 { + .chart__values-line.color-index-graph-5, .chart__values-line.color-index-graph-10 { stroke: #617D78; } - .chart__lines-area.color-index-accent-1, .chart__lines-area.color-index-accent-6 { - fill: rgba(255, 141, 109, 0.5); } - .chart__lines-area.color-index-accent-2, .chart__lines-area.color-index-accent-7 { - fill: rgba(135, 123, 117, 0.5); } - .chart__lines-area.color-index-accent-3, .chart__lines-area.color-index-accent-8 { - fill: rgba(42, 210, 201, 0.5); } - .chart__lines-area.color-index-accent-4, .chart__lines-area.color-index-accent-9 { - fill: rgba(97, 71, 103, 0.5); } - .chart__lines-area.color-index-accent-5, .chart__lines-area.color-index-accent-10 { - fill: rgba(97, 125, 120, 0.5); } + .chart__values-area.color-index-error { + fill: rgba(255, 69, 79, 0.7); } + .chart__values-area.color-index-warning { + fill: rgba(243, 178, 55, 0.7); } + .chart__values-area.color-index-ok { + fill: rgba(0, 179, 136, 0.7); } + .chart__values-area.color-index-unknown { + fill: rgba(132, 132, 132, 0.7); } + .chart__values-area.color-index-disabled { + fill: rgba(132, 132, 132, 0.7); } + .chart__values-area.color-index-graph-1, .chart__values-area.color-index-graph-6 { + fill: rgba(255, 141, 109, 0.7); } + .chart__values-area.color-index-graph-2, .chart__values-area.color-index-graph-7 { + fill: rgba(135, 123, 117, 0.7); } + .chart__values-area.color-index-graph-3, .chart__values-area.color-index-graph-8 { + fill: rgba(42, 210, 201, 0.7); } + .chart__values-area.color-index-graph-4, .chart__values-area.color-index-graph-9 { + fill: rgba(97, 71, 103, 0.7); } + .chart__values-area.color-index-graph-5, .chart__values-area.color-index-graph-10 { + fill: rgba(97, 125, 120, 0.7); } + .chart__values-bar.color-index-error { + fill: rgba(255, 69, 79, 0.7); } + .chart__values-bar.color-index-warning { + fill: rgba(243, 178, 55, 0.7); } + .chart__values-bar.color-index-ok { + fill: rgba(0, 179, 136, 0.7); } + .chart__values-bar.color-index-unknown { + fill: rgba(132, 132, 132, 0.7); } + .chart__values-bar.color-index-disabled { + fill: rgba(132, 132, 132, 0.7); } + .chart__values-bar.color-index-graph-1, .chart__values-bar.color-index-graph-6 { + fill: rgba(255, 141, 109, 0.7); } + .chart__values-bar.color-index-graph-2, .chart__values-bar.color-index-graph-7 { + fill: rgba(135, 123, 117, 0.7); } + .chart__values-bar.color-index-graph-3, .chart__values-bar.color-index-graph-8 { + fill: rgba(42, 210, 201, 0.7); } + .chart__values-bar.color-index-graph-4, .chart__values-bar.color-index-graph-9 { + fill: rgba(97, 71, 103, 0.7); } + .chart__values-bar.color-index-graph-5, .chart__values-bar.color-index-graph-10 { + fill: rgba(97, 125, 120, 0.7); } + .chart__values-bar--active.color-index-error { + fill: #FF454F; } + .chart__values-bar--active.color-index-warning { + fill: #F3B237; } + .chart__values-bar--active.color-index-ok { + fill: #00B388; } + .chart__values-bar--active.color-index-unknown { + fill: #848484; } + .chart__values-bar--active.color-index-disabled { + fill: #848484; } + .chart__values-bar--active.color-index-graph-1, .chart__values-bar--active.color-index-graph-6 { + fill: #FF8D6D; } + .chart__values-bar--active.color-index-graph-2, .chart__values-bar--active.color-index-graph-7 { + fill: #877B75; } + .chart__values-bar--active.color-index-graph-3, .chart__values-bar--active.color-index-graph-8 { + fill: #2AD2C9; } + .chart__values-bar--active.color-index-graph-4, .chart__values-bar--active.color-index-graph-9 { + fill: #614767; } + .chart__values-bar--active.color-index-graph-5, .chart__values-bar--active.color-index-graph-10 { + fill: #617D78; } .chart__threshold { stroke-width: 2px; stroke: #333333; } + .chart__legend { + margin: 24px 0 0; + display: inline-block; + text-align: left; + list-style-type: none; } + .chart__legend-label { + text-align: right; + font-size: 20px; + font-size: 1.25rem; + line-height: 1.2; + margin-bottom: 12px; } + .chart__legend-item, .chart__legend-total { + white-space: nowrap; } + .chart__legend-item > *, .chart__legend-total > * { + vertical-align: top; } + .chart__legend-item-label, .chart__legend-total-label { + display: inline-block; + width: 96px; + color: #999; } + .chart__legend-item-value, .chart__legend-total-value { + display: inline-block; + width: 48px; + text-align: right; } + .chart__legend-item-units, .chart__legend-total-units { + margin-left: 6px; } + .chart__legend-item svg.chart__legend-item-swatch { + width: 12px; + height: 12px; + margin-top: 6px; + margin-right: 12px; + overflow: visible; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-error { + stroke: #FF454F; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-warning { + stroke: #F3B237; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-ok { + stroke: #00B388; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-unknown { + stroke: #848484; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-disabled { + stroke: #848484; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-1, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-6 { + stroke: #FF8D6D; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-2, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-7 { + stroke: #877B75; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-3, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-8 { + stroke: #2AD2C9; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-4, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-9 { + stroke: #614767; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-5, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-10 { + stroke: #617D78; } + .chart__legend-item svg.chart__legend-item-swatch path { + stroke-width: 12px; + transition-property: stroke-width; + transition-duration: 0.3s; + transition-timing-function: ease-in-out; } + .chart__legend-total { + margin-top: 6px; + border-top: 1px dotted #ccc; + padding-top: 6px; + margin-left: 24px; + color: #999; } .check-box__input { opacity: 0; @@ -1110,6 +1053,13 @@ html, body { margin-left: auto; margin-right: auto; } +@media screen and (min-width: 45em) { + .dashboard { + height: calc(100vh - 96px); } } +@media screen and (max-width: 44.9375em) { + .dashboard { + height: calc(100vh - 48px); } } + .document { width: 100%; } .document--no-contents .document__content { @@ -1176,103 +1126,142 @@ html, body { 100% { stroke-dashoffset: 0; } } -.donut { - display: inline-block; } - .donut.series-pre path { - stroke-dashoffset: 768px; } - .donut__graphic-container { - position: relative; - width: 192px; - height: 192px; } - .donut svg.donut__graphic { - position: absolute; - top: 0px; - left: 0px; - width: 100%; - height: 100%; - overflow: visible; } - .donut svg.donut__graphic path { - stroke-width: 24px; - stroke-linecap: butt; - stroke-dasharray: 768px 768px; - stroke-dashoffset: 0; - fill: none; - cursor: pointer; - -webkit-animation: draw-stroke 3s; - animation: draw-stroke 3s; } - .donut svg.donut__graphic path.donut__slice--active { - stroke-width: 36px; } - .donut__slice--color-index-error { +.donut.series-pre path { + stroke-dashoffset: 768px; } +.donut__graphic-container { + position: relative; + width: 192px; + height: 192px; } +.donut svg.donut__graphic { + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + overflow: visible; } + .donut svg.donut__graphic path { + stroke-width: 24px; + stroke-linecap: butt; + stroke-dasharray: 768px 768px; + stroke-dashoffset: 0; + fill: none; + cursor: pointer; + -webkit-animation: draw-stroke 3s; + animation: draw-stroke 3s; } + .donut svg.donut__graphic path.donut__slice--active { + stroke-width: 36px; } +.donut__slice.color-index-error { + stroke: #FF454F; } +.donut__slice.color-index-warning { + stroke: #F3B237; } +.donut__slice.color-index-ok { + stroke: #00B388; } +.donut__slice.color-index-unknown { + stroke: #848484; } +.donut__slice.color-index-disabled { + stroke: #848484; } +.donut__slice.color-index-graph-1, .donut__slice.color-index-graph-6 { + stroke: #FF8D6D; } +.donut__slice.color-index-graph-2, .donut__slice.color-index-graph-7 { + stroke: #877B75; } +.donut__slice.color-index-graph-3, .donut__slice.color-index-graph-8 { + stroke: #2AD2C9; } +.donut__slice.color-index-graph-4, .donut__slice.color-index-graph-9 { + stroke: #614767; } +.donut__slice.color-index-graph-5, .donut__slice.color-index-graph-10 { + stroke: #617D78; } +.donut__active { + position: absolute; + width: 100%; + margin-top: 60px; + text-align: center; + white-space: normal; + pointer-events: none; } + .donut__active-value { + font-size: 36px; + font-size: 2.25rem; + line-height: 38px; + font-weight: bold; } + .donut__active-units { + font-size: 24px; + font-size: 1.5rem; + line-height: inherit; + margin-left: 6px; + color: #999; + font-weight: normal; } + .donut__active-label { + width: 60%; + margin: 0px auto; } +.donut__legend { + text-align: left; + list-style-type: none; + white-space: normal; } +.donut__legend-item, .donut__legend-total { + color: #999; } + .donut__legend-item > *, .donut__legend-total > * { + vertical-align: top; } + .donut__legend-item-label, .donut__legend-total-label { + display: inline-block; + width: 96px; } + .donut__legend-item-value, .donut__legend-total-value { + display: inline-block; + width: 48px; + text-align: right; } +.donut__legend-item svg.donut__legend-item-swatch { + width: 12px; + height: 12px; + margin-top: 6px; + margin-right: 12px; + overflow: visible; } + .donut__legend-item svg.donut__legend-item-swatch.color-index-error { stroke: #FF454F; } - .donut__slice--color-index-warning { + .donut__legend-item svg.donut__legend-item-swatch.color-index-warning { stroke: #F3B237; } - .donut__slice--color-index-ok { + .donut__legend-item svg.donut__legend-item-swatch.color-index-ok { stroke: #00B388; } - .donut__slice--color-index-unknown { + .donut__legend-item svg.donut__legend-item-swatch.color-index-unknown { stroke: #848484; } - .donut__slice--color-index-disabled { + .donut__legend-item svg.donut__legend-item-swatch.color-index-disabled { stroke: #848484; } - .donut__slice--color-index-1, .donut__slice--color-index-6 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-1, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-6 { stroke: #FF8D6D; } - .donut__slice--color-index-2, .donut__slice--color-index-7 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-2, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-7 { stroke: #877B75; } - .donut__slice--color-index-3, .donut__slice--color-index-8 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-3, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-8 { stroke: #2AD2C9; } - .donut__slice--color-index-4, .donut__slice--color-index-9 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-4, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-9 { stroke: #614767; } - .donut__slice--color-index-5, .donut__slice--color-index-10 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-5, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-10 { stroke: #617D78; } - .donut__active { - position: absolute; - width: 100%; - margin-top: 72px; - text-align: center; - pointer-events: none; } - .donut__active-value { - font-size: 36px; - font-size: 2.25rem; - line-height: 38px; - font-weight: bold; } - .donut__active-units { - font-size: 24px; - font-size: 1.5rem; - line-height: inherit; - margin-left: 6px; - color: #999; - font-weight: normal; } - .donut__active-label { - width: 60%; - margin: 0px auto; } - .donut__key { - margin-top: 24px; + .donut__legend-item svg.donut__legend-item-swatch path { + stroke-width: 12px; + transition-property: stroke-width; + transition-duration: 0.3s; + transition-timing-function: ease-in-out; } +.donut__legend-item--active { + color: #333; + font-weight: bold; } + .donut__legend-item--active svg.donut__legend-item-swatch path { + stroke-width: 12px; } +.donut__legend-total { + margin-left: 24px; } + .donut__legend-total > * { + margin-top: 6px; + padding-top: 6px; + border-top: 1px dotted #ccc; } +.donut--landscape { + white-space: nowrap; } + .donut--landscape .donut__graphic-container, .donut--landscape .donut__legend { display: inline-block; - text-align: left; } - .donut__key-item { - color: #999; } - .donut__key-item > * { - vertical-align: top; } - .donut__key-item svg.donut__key-item-swatch { - width: 12px; - height: 12px; - margin-top: 6px; - margin-right: 12px; - overflow: visible; } - .donut__key-item svg.donut__key-item-swatch path { - stroke-width: 6px; - transition-property: stroke-width; - transition-duration: 0.3s; - transition-timing-function: ease-in-out; } - .donut__key-item-label { - display: inline-block; - width: 96px; } - .donut__key-item-value { - display: inline-block; - width: 48px; - text-align: right; } - .donut__key-item--active { - color: #333; } - .donut__key-item--active svg.donut__key-item-swatch path { - stroke-width: 12px; } + vertical-align: middle; } + .donut--landscape .donut__legend { + margin: 0 0 0 24px; } +.donut--portrait .donut__graphic-container, .donut--portrait .donut__legend { + display: block; } +.donut--portrait .donut__legend { + margin: 24px 0 0; } +.donut--small .donut__legend { + display: none; } .fixed-header { position: fixed; @@ -1448,16 +1437,15 @@ html, body { .header { height: 72px; } } .header__wrapper { - background-color: rgba(255, 255, 255, 0.9); } + background-color: rgba(255, 255, 255, 0.9); + padding-left: 24px; + padding-right: 24px; } @media screen and (max-width: 44.9375em) { .header__wrapper { height: 48px; } } @media screen and (min-width: 45em) { .header__wrapper { height: 72px; } } - .layer__container > .form > .header .header__wrapper { - padding-left: 24px; - padding-right: 24px; } .header__content { display: -webkit-flex; display: flex; @@ -1540,6 +1528,9 @@ html, body { left: 0px; right: 0px; z-index: 3; } } +.header--flush .header__wrapper { + padding-left: 0px; + padding-right: 0px; } .tile > .header { height: 48px; } .tile > .header .header__wrapper { @@ -1723,29 +1714,29 @@ a.active > .label .label__icon.control-icon svg { max-width: 100vw; box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.3); } .layer--align-center { - background-image: radial-gradient(circle at top, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 179, 136, 0.6)); } + background-image: radial-gradient(circle at top, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-center .layer__container { left: 50%; -webkit-transform: translateX(-50%); transform: translateX(-50%); } .layer--align-left { - background-image: radial-gradient(circle at left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 179, 136, 0.6)); } + background-image: radial-gradient(circle at left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-left .layer__container { left: 0px; -webkit-animation: slide-right 0.2s ease-in-out forwards; animation: slide-right 0.2s ease-in-out forwards; } .layer--align-right { - background-image: radial-gradient(circle at right, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 179, 136, 0.6)); } + background-image: radial-gradient(circle at right, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-right .layer__container { right: 0px; } .layer--align-top { - background-image: radial-gradient(circle at top left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 179, 136, 0.6)); } + background-image: radial-gradient(circle at top left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-top .layer__container { top: 0px; -webkit-animation: slide-down 0.2s ease-in-out forwards; animation: slide-down 0.2s ease-in-out forwards; } .layer--align-bottom { - background-image: radial-gradient(circle at bottom left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 179, 136, 0.6)); } + background-image: radial-gradient(circle at bottom left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-bottom .layer__container { bottom: 0px; } @@ -2112,7 +2103,7 @@ a.active > .label .label__icon.control-icon svg { left: 0px; right: 0px; bottom: 0px; - background-color: rgba(0, 179, 136, 0.6); + background-color: rgba(128, 128, 128, 0.6); z-index: 10; } .notifications__container { position: absolute; @@ -2363,7 +2354,7 @@ a.active > .label .label__icon.control-icon svg { left: 0px; right: 0px; bottom: 0px; - background-color: rgba(0, 179, 136, 0.6); + background-color: rgba(128, 128, 128, 0.6); z-index: 10; } .session__container { position: absolute; @@ -2429,31 +2420,43 @@ a.active > .label .label__icon.control-icon svg { display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; - -webkit-align-items: stretch; - align-items: stretch; - -webkit-align-content: stretch; - align-content: stretch; - margin: -24px; } + padding: 12px; } .tiles > * { -webkit-flex: 0 0 192px; flex: 0 0 192px; flex-grow: 1; } + .tiles--flush { + margin: -24px; } .tiles--small > * { -webkit-flex-basis: 96px; flex-basis: 96px; } + .tiles--fill { + -webkit-align-items: stretch; + align-items: stretch; + -webkit-align-content: stretch; + align-content: stretch; } + .tiles--fill > * { + -webkit-flex-grow: 1; + flex-grow: 1; } .tile { - padding: 24px; } + padding: 12px; + overflow: hidden; } @media screen and (max-width: 44.9375em) { .tile { margin: 0px; border-radius: none; } } + .tile > .header { + margin-bottom: 24px; } .tile > a { display: block; height: 100%; text-decoration: none; color: inherit; padding: 24px; } + .tile--wide { + -webkit-flex-basis: 100%; + flex-basis: 100%; } .title { overflow: hidden; @@ -2499,7 +2502,7 @@ a.active > .label .label__icon.control-icon svg { * Extend the clearfix class with Sass to avoid the `.clearfix` class appearing * over and over in your markup. */ -.clearfix:after, .i-box:after { +.clearfix:after { content: ""; display: table; clear: both; } diff --git a/css/grommet-hpe.min.css b/css/grommet-hpe.min.css index 2a203e3..257ae0a 100644 --- a/css/grommet-hpe.min.css +++ b/css/grommet-hpe.min.css @@ -1,5 +1,5 @@ -@charset "UTF-8";dfn,img{font-style:italic}img,legend{border:0}a,ins,u{text-decoration:none}a,a:visited{color:#2883d7}code.hljs,input,select,textarea{border:1px solid #ccc}.i-layout,.i-list-bare,.i-list-block,.i-list-inline,.i-list-ui{list-style:none}@font-face{font-family:Metric;src:url(~grommet/hpe/font/MetricWeb-Regular.woff)format('woff')}/*! +@charset "UTF-8";dfn,img{font-style:italic}img,legend{border:0}a,ins,u{text-decoration:none}a,a:visited{color:#2883d7}code.hljs,input,select,textarea{border:1px solid #ccc}@font-face{font-family:Metric;src:url(/grommet/scss/hpe/font/MetricWeb-Regular.woff)format('woff')}/*! * inuitcss, by @csswizardry * * github.com/inuitcss | inuitcss.com - *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,optgroup,strong{font-weight:700}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}#loading,.app{position:absolute}sup{top:-.5em}sub{bottom:-.25em}.app,.layer,.layer--align-bottom .layer__container,.login{bottom:0}img{max-width:100%;vertical-align:middle}svg:not(:root){overflow:hidden}hr{box-sizing:content-box;height:0}pre,textarea{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}#loading,.tbd{font-style:italic}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver}table{border-collapse:collapse;border-spacing:0}blockquote,body,caption,dd,dl,fieldset,figure,form,h1,h2,h3,h4,h5,h6,hr,legend,ol,p,pre,table,td,th,ul{margin:0;padding:0}abbr[title],dfn[title]{cursor:help}ins{border-bottom:1px solid}html{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-size:1em;line-height:1.5;background-color:#fff;color:#333;overflow-y:scroll;min-height:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:'Source Sans Pro',Arial,sans-serif}*,:after,:before{-webkit-box-sizing:inherit;-moz-box-sizing:inherit;box-sizing:inherit}address,blockquote,dl,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,ol,p,pre,table,ul{margin-bottom:1.5rem}.i-box>:last-child,li>ol,li>ul{margin-bottom:0}dd,ol,ul{margin-left:3rem}h6{font-size:14px;font-size:.875rem;line-height:1.71429}.gm-style img,img[height],img[width]{max-width:none}.i-lede{font-size:18px;font-size:1.125rem;line-height:1.33333}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:300;src:local('Source Sans Pro Light'),local('SourceSansPro-Light'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/toadOcfmlt9b38dHJxOBGPS42wKzre0cxmO5m5GyTsY.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:400;src:local('Source Sans Pro'),local('SourceSansPro-Regular'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/ODelI1aHBYDBqgeIAH2zlEY6Fu39Tt9XkmtSosaMoEA.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:700;src:local('Source Sans Pro Bold'),local('SourceSansPro-Bold'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/toadOcfmlt9b38dHJxOBGLlcMrNrsnL9dgADnXgYJjs.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:400;src:local('Source Sans Pro Italic'),local('SourceSansPro-It'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/M2Jd71oPJhLKp0zdtTvoMzpKUtbt71woJ25xl7KOGD0.ttf)format('truetype')}dd,h3,h4,h5,li,p{max-width:576px}.h1,h1{font-size:48px;font-size:3rem;line-height:1;font-weight:600}.h2,.h3,h2,h3{line-height:1.33333;font-size:36px}.h2,h2{font-size:2.25rem;font-weight:400}.h3,.h4,.h5,h3,h4,h5{font-weight:100}.h3,h3{font-size:2.25rem}.h4,h4{font-size:24px;font-size:1.5rem;line-height:1}.h5,h5{font-size:20px;font-size:1.25rem;line-height:1.2}a{background-color:transparent;cursor:pointer}a:hover{text-decoration:underline}a.active{color:#333}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes fadein{from{opacity:0}to{opacity:1}}input,select,textarea{font-size:16px;font-size:1rem;line-height:1.5;padding:5px 12px;border-radius:0;outline:0;margin-right:12px;background-color:inherit}input:focus,select:focus,textarea:focus{border-color:#2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}input::-moz-focus-inner,select::-moz-focus-inner,textarea::-moz-focus-inner{border:none;outline:0}input.error,select.error,textarea.error{border-color:#FF454F}input[type=button],input[type=submit]{line-height:inherit}a.button,button,input[type=button],input[type=submit]{display:inline-block;padding:4px 12px;border:2px solid #00B388;border-radius:0;background-color:inherit;text-decoration:none;cursor:pointer;text-align:center;outline:0}a.button:hover,button:hover,input[type=button]:hover,input[type=submit]:hover{background-color:#eee;border-color:#00B388}a.button.primary,button.primary,input[type=button].primary,input[type=submit].primary{background-color:#008565;border-color:#008565;color:#fff}a.button.primary:hover,button.primary:hover,input[type=button].primary:hover,input[type=submit].primary:hover{background-color:#00B388;border-color:#00B388}a.button.call-to-action,button.call-to-action,input[type=button].call-to-action,input[type=submit].call-to-action{font-size:20px;font-size:1.25rem;line-height:1.2;padding:12px 24px}a.button:focus,button:focus,input[type=button]:focus,input[type=submit]:focus{border-color:#2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}[class*=background-color-index-] a.button:hover,[class*=background-color-index-] button:hover,[class*=background-color-index-] input[type=button]:hover,[class*=background-color-index-] input[type=submit]:hover{background-color:#00B388;border-color:#00B388;text-decoration:none}select{border-color:#ccc;padding-right:24px;-webkit-appearance:none;-moz-appearance:none;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAAXNSR0IArs4c6QAAALNJREFUKBVjYBj6gHH69Olb////L8rIyJiemZl5HpuXgGoMgWpmAtW8ZgIyuIEMU6DCk0CJioaGBiaYJhAbJAaSA6kBqwUKcoiJiXUBBXKAEoxAwcM/f/6MA2liZ2dfBBS3BTKBwv+nvHr1qowRJAECU6dOdQNKzgdiKaDkNyANEuYCsp8BcWJ2dvYukADcepDAjx8/dIFia4CKuUCKQWyQGEwxkI8dTJs2rRLqduwKaCoKAOClUKEWEZS1AAAAAElFTkSuQmCC)center right 6px no-repeat;cursor:pointer}select:hover{background-color:#eee}select::-moz-focus-inner{border:none}select.plain{border:none}input[type=range]{-webkit-appearance:none;border-color:transparent;padding:0}input[type=range]:focus{outline:0}input[type=range]::-moz-focus-inner{border:none}input[type=range]::-webkit-slider-runnable-track{width:100%;height:6px;cursor:pointer;background:0 0;border:1px solid #ccc;border-radius:0}input[type=range]::-webkit-slider-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#00B388;cursor:pointer;-webkit-appearance:none;margin-top:-10px}input[type=range]::-moz-range-track{width:100%;height:6px;cursor:pointer;background:0 0;border:1px solid #ccc;border-radius:0}input[type=range]::-moz-range-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#00B388;cursor:pointer}input[type=range]::-ms-track{width:100%;height:6px;cursor:pointer;border:1px solid transparent;border-radius:0;background:0 0;border-width:16px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#2a6495;border-radius:0}input[type=range]::-ms-fill-upper{background:#3071a9;border-radius:0}input[type=range]::-ms-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#00B388;cursor:pointer}body,html{height:100%;width:100%;overflow:hidden}.i-list-inline{margin:0;padding:0}.i-list-inline>li{display:inline-block}.i-list-inline--delimited>li+li:before{content:",\00A0"}.i-list-block{margin:0;padding:0}.i-list-block>li,.i-list-block__item{padding:24px}.i-list-block--tiny>.i-list-block__item,.i-list-block.i-list-block--tiny>li{padding:6px}.i-list-block--small>.i-list-block__item,.i-list-block.i-list-block--small>li{padding:12px}.i-list-ui,.i-list-ui>li,.i-list-ui__item{border:0 solid #ccc}.i-list-ui{margin:0;padding:0;border-top-width:1px}.i-list-ui>li,.i-list-ui__item{padding:24px;border-bottom-width:1px}.i-list-bare{margin:0;padding:0}.i-box{display:block;padding:24px}.i-box--small{padding:12px}.i-pack{width:100%;display:table;table-layout:fixed}.i-pack__item{display:table-cell}.i-layout{margin:0 0 0 -24px;padding:0}.i-layout__item{display:inline-block;padding-left:24px;vertical-align:top;width:100%}.i-layout--center{text-align:center}.i-layout--center>.i-layout__item{text-align:left}.i-table{width:100%}.i-table--cosy td,.i-table--cosy th{padding:12px}.app--centered .document,.app--centered .section,.app--centered>.footer,.app--centered>div>.footer{padding-left:24px;padding-right:24px}#loading{width:100%;height:100%;background-color:#ddd;text-align:center;padding-top:100px;font-size:48px;color:#ccc}.app{top:0;left:0;right:0;overflow:auto}.app--inline{position:relative}.app--centered>.header .header__content,.app--centered>div>.header .header__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered>.footer .footer__content,.app--centered>div>.footer .footer__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered .document__content,.app--centered .section__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered .section .document{padding-left:0;padding-right:0}.app--centered .section .document__content{width:auto;max-width:none}.chart{display:block}.chart__grid{stroke:#ccc}.chart__lines-line{stroke-width:3px}.chart__lines-line.color-index-accent-1,.chart__lines-line.color-index-accent-6{stroke:#FF8D6D}.chart__lines-line.color-index-accent-2,.chart__lines-line.color-index-accent-7{stroke:#877B75}.chart__lines-line.color-index-accent-3,.chart__lines-line.color-index-accent-8{stroke:#2AD2C9}.chart__lines-line.color-index-accent-4,.chart__lines-line.color-index-accent-9{stroke:#614767}.chart__lines-line.color-index-accent-10,.chart__lines-line.color-index-accent-5{stroke:#617D78}.chart__lines-area.color-index-accent-1,.chart__lines-area.color-index-accent-6{fill:rgba(255,141,109,.5)}.chart__lines-area.color-index-accent-2,.chart__lines-area.color-index-accent-7{fill:rgba(135,123,117,.5)}.chart__lines-area.color-index-accent-3,.chart__lines-area.color-index-accent-8{fill:rgba(42,210,201,.5)}.chart__lines-area.color-index-accent-4,.chart__lines-area.color-index-accent-9{fill:rgba(97,71,103,.5)}.chart__lines-area.color-index-accent-10,.chart__lines-area.color-index-accent-5{fill:rgba(97,125,120,.5)}.chart__threshold{stroke-width:2px;stroke:#333}.check-box__input{opacity:0;position:absolute}.check-box__input:checked+label.checkbox:after{content:"";position:absolute;top:10.5px;left:4px;width:16px;height:16px;background-color:#00B388}.check-box__input:focus+label.checkbox:before{content:"";border-color:#2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}.layer__container,.login-form{box-shadow:0 2px 4px rgba(0,0,0,.3)}.check-box__label{position:relative;display:inline-block;cursor:pointer;-ms-user-select:none;user-select:none}.check-box__label,.radio-button__label{-webkit-user-select:none;-moz-user-select:none}.check-box__label:before{content:"";display:inline-block;width:24px;height:24px;margin-right:12px;vertical-align:middle;background-color:inherit;color:#008565;border:1px solid #ccc;border-radius:0;text-align:center}.donut__key-item>*,.form-field__contents>textarea{vertical-align:top}.header-color-index-neutral-1 dt,.header-color-index-neutral-1 h1,.header-color-index-neutral-1 h2,.header-color-index-neutral-1 h3,.header-color-index-neutral-1 h4,.header-color-index-neutral-1 h5,.header-color-index-neutral-1 h6,.header-color-index-neutral-4 dt,.header-color-index-neutral-4 h1,.header-color-index-neutral-4 h2,.header-color-index-neutral-4 h3,.header-color-index-neutral-4 h4,.header-color-index-neutral-4 h5,.header-color-index-neutral-4 h6{color:#60798D}.background-color-index-neutral-1,.background-color-index-neutral-4{background-color:#60798D;color:#fff}.background-color-index-neutral-1 a,.background-color-index-neutral-4 a{color:#fff}.header-color-index-neutral-2 dt,.header-color-index-neutral-2 h1,.header-color-index-neutral-2 h2,.header-color-index-neutral-2 h3,.header-color-index-neutral-2 h4,.header-color-index-neutral-2 h5,.header-color-index-neutral-2 h6,.header-color-index-neutral-5 dt,.header-color-index-neutral-5 h1,.header-color-index-neutral-5 h2,.header-color-index-neutral-5 h3,.header-color-index-neutral-5 h4,.header-color-index-neutral-5 h5,.header-color-index-neutral-5 h6{color:#617D78}.background-color-index-neutral-2,.background-color-index-neutral-5{background-color:#617D78;color:#fff}.background-color-index-neutral-2 a,.background-color-index-neutral-5 a{color:#fff}.header-color-index-neutral-3 dt,.header-color-index-neutral-3 h1,.header-color-index-neutral-3 h2,.header-color-index-neutral-3 h3,.header-color-index-neutral-3 h4,.header-color-index-neutral-3 h5,.header-color-index-neutral-3 h6,.header-color-index-neutral-6 dt,.header-color-index-neutral-6 h1,.header-color-index-neutral-6 h2,.header-color-index-neutral-6 h3,.header-color-index-neutral-6 h4,.header-color-index-neutral-6 h5,.header-color-index-neutral-6 h6{color:#877B75}.background-color-index-neutral-3,.background-color-index-neutral-6{background-color:#877B75;color:#fff}.background-color-index-neutral-3 a,.background-color-index-neutral-6 a{color:#fff}.background-color-index-accent-1,.background-color-index-accent-3{background-color:#2AD2C9;color:#fff}.background-color-index-accent-1 a,.background-color-index-accent-3 a{color:#fff}.background-color-index-accent-2,.background-color-index-accent-4{background-color:#614767;color:#fff}.background-color-index-accent-2 a,.background-color-index-accent-4 a{color:#fff}.background-color-index-grey-1,.background-color-index-grey-5{background-color:#333;color:#fff}.background-color-index-grey-1 a,.background-color-index-grey-5 a{color:#fff}.background-color-index-grey-2,.background-color-index-grey-6{background-color:#3B3B3B;color:#fff}.background-color-index-grey-2 a,.background-color-index-grey-6 a{color:#fff}.background-color-index-grey-3,.background-color-index-grey-7{background-color:#434343;color:#fff}.background-color-index-grey-3 a,.background-color-index-grey-7 a{color:#fff}.background-color-index-grey-4,.background-color-index-grey-8{background-color:#666;color:#fff}.fixed-header,.header__wrapper{background-color:rgba(255,255,255,.9)}.background-color-index-grey-4 a,.background-color-index-grey-8 a{color:#fff}.center-column{padding-left:24px;padding-right:24px}.center-column .center-column__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.document{width:100%}.document--no-contents .document__content{padding-left:0}.document section{margin-top:24px;margin-bottom:24px;padding-top:24px}.document header>img,.document section>img{margin-top:48px;margin-bottom:48px;display:block;max-width:576px}.donut,.donut__key,.donut__key-item-value{display:inline-block}@media screen and (max-width:44.9375em){.document header>img,.document section>img{max-width:100%}.document header>ol,.document header>ul,.document section>ol,.document section>ul{padding-left:24px;padding-right:24px;margin-left:0;margin-bottom:24px}}.document header>dl>dt,.document section>dl>dt{margin-top:24px;margin-bottom:6px;text-transform:uppercase}.document header>dl>dt code,.document section>dl>dt code{text-transform:none;white-space:pre-wrap}.header__content,.index-header__count,.search__layer-header{white-space:nowrap}.document header>dl>dd,.document section>dl>dd{margin-left:0}.document header>h2,.document section>h2{position:relative;padding-top:24px}.document header>h2:after,.document section>h2:after{position:absolute;content:'';top:0;left:0;right:0;border-top:1px solid #ccc}.document section:first-child{margin-top:0;padding-top:0}.document section:first-child>h2{padding-top:0}.document section:first-child>h2:after{border-top:none}.object__attribute--array>.object__attribute-value>ol>li,.session__actions,.tile>.header .header__wrapper{border-top:1px solid #ccc}@-webkit-keyframes draw-stroke{0%{stroke-dashoffset:768px}100%{stroke-dashoffset:0}}@keyframes draw-stroke{0%{stroke-dashoffset:768px}100%{stroke-dashoffset:0}}.donut.series-pre path{stroke-dashoffset:768px}.donut__graphic-container{position:relative;width:192px;height:192px}.donut svg.donut__graphic{position:absolute;top:0;left:0;width:100%;height:100%;overflow:visible}.donut svg.donut__graphic path{stroke-width:24px;stroke-linecap:butt;stroke-dasharray:768px 768px;stroke-dashoffset:0;fill:none;cursor:pointer;-webkit-animation:draw-stroke 3s;animation:draw-stroke 3s}.donut svg.donut__graphic path.donut__slice--active{stroke-width:36px}.donut__slice--color-index-error{stroke:#FF454F}.donut__slice--color-index-warning{stroke:#F3B237}.donut__slice--color-index-ok{stroke:#00B388}.donut__slice--color-index-disabled,.donut__slice--color-index-unknown{stroke:#848484}.donut__slice--color-index-1,.donut__slice--color-index-6{stroke:#FF8D6D}.donut__slice--color-index-2,.donut__slice--color-index-7{stroke:#877B75}.donut__slice--color-index-3,.donut__slice--color-index-8{stroke:#2AD2C9}.donut__slice--color-index-4,.donut__slice--color-index-9{stroke:#614767}.donut__slice--color-index-10,.donut__slice--color-index-5{stroke:#617D78}.donut__active{position:absolute;width:100%;margin-top:72px;text-align:center;pointer-events:none}.donut__active-value{font-size:36px;font-size:2.25rem;line-height:38px;font-weight:700}.donut__active-units{font-size:24px;font-size:1.5rem;line-height:inherit;margin-left:6px;color:#999;font-weight:400}.donut__active-label{width:60%;margin:0 auto}.donut__key{margin-top:24px;text-align:left}.donut__key-item{color:#999}.donut__key-item svg.donut__key-item-swatch{width:12px;height:12px;margin-top:6px;margin-right:12px;overflow:visible}.donut__key-item svg.donut__key-item-swatch path{stroke-width:6px;transition-property:stroke-width;transition-duration:.3s;transition-timing-function:ease-in-out}.control-icon,.react-gravatar{transition:all .3s ease-in-out}.donut__key-item-label{display:inline-block;width:96px}.donut__key-item-value{width:48px;text-align:right}.donut__key-item--active{color:#333}.donut__key-item--active svg.donut__key-item-swatch path{stroke-width:12px}.fixed-header{position:fixed;z-index:1}.fixed-header__container{position:absolute;top:0;left:0;right:0}.footer{min-height:48px;line-height:48px}.footer__content{display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;width:100%}.footer__content.center-column__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}@media screen and (max-width:44.9375em){.document header>dl>dd,.document section>dl>dd{padding-right:24px}.fixed-header{position:relative}.fixed-header__container{position:static}.footer__content.center-column__content>.menu:first-child{width:100%}.footer__content.center-column__content>.menu:first-child:empty{width:0;margin:0;padding:0}}.footer__content>.flex-1{-webkit-flex:1;flex:1}.footer__content>.flex-2{-webkit-flex:2;flex:2}.footer__content>.flex-3{-webkit-flex:3;flex:3}.footer__content>.flex-4{-webkit-flex:4;flex:4}.footer__content>*{margin-right:48px}.footer__content>:last-child{margin-right:0}@media screen and (max-width:44.9375em){.footer__content>:last-child{text-align:left}}@media screen and (min-width:45em)and (max-width:63.9375em){.footer__content>:last-child{text-align:left}}.footer__content a.button,.footer__content button,.footer__content input[type=button],.footer__content input[type=submit]{font-size:24px;font-size:1.5rem;line-height:inherit;min-width:96px}.footer--primary{height:auto;padding:24px}.footer--primary .footer__content{position:relative;color:#999}.footer--primary .footer__content p{padding-top:12px;margin:0;max-width:none;text-align:right;line-height:24px}@media screen and (max-width:44.9375em){.footer--primary .footer__content{display:block}}@media screen and (min-width:45em)and (max-width:63.9375em){.footer--primary .footer__content{display:block}}.footer--centered .footer__content{display:block;text-align:center}.footer--centered .footer__content>*{margin-right:auto;margin-left:auto;text-align:center}.tile>.footer{border-bottom:1px solid #ccc}.form{min-width:480px}.form fieldset{border:none;margin:0;padding-bottom:1.5rem}.form .form-fields{padding:24px}.layer .form{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;max-height:100vh}.layer .form>.footer,.layer .form>.header{-webkit-flex:0 0 auto;flex:0 0 auto}.layer .form>.form-fields{overflow:auto}.form--compact{min-width:240px}.form-field{position:relative;margin-bottom:12px;line-height:36px}.form-field:last-child,.form-field__contents>table.table--selectable{margin-bottom:0}@media screen and (min-width:45em){.form:not(.form--compact) .form-field{display:-webkit-flex;display:flex;min-width:672px}}.form-field__label{display:block;text-align:left}@media screen and (min-width:45em){.form:not(.form--compact) .form-field__label{-webkit-flex:0 0 192px;flex:0 0 192px;text-align:right;padding-right:24px;vertical-align:top}.form:not(.form--compact) .form-field__container{-webkit-flex:1 0 384px;flex:1 0 384px}}.form-field__contents button{line-height:24px}.form-field__contents>input[type=email],.form-field__contents>input[type=password],.form-field__contents>input[type=range],.form-field__contents>input[type=text],.form-field__contents>select,.form-field__contents>textarea{width:240px}.form--compact .form-field__contents>input[type=email],.form--compact .form-field__contents>input[type=password],.form--compact .form-field__contents>input[type=range],.form--compact .form-field__contents>input[type=text],.form--compact .form-field__contents>select,.form--compact .form-field__contents>textarea{width:100%;margin-right:0}.control-icon,.header__content svg,.status-icon{vertical-align:middle}.form-field__contents>.check-box,.form-field__contents>.radio-button{display:block}.form-field__contents label.checkbox,.form-field__contents label.radio{margin-right:24px}.form-field__contents>table.table--selectable tbody tr td{padding-top:0;padding-bottom:0}.form-field--error input,.form-field--error select,.form-field--error textarea{border-color:#FF454F}.form-field__help{color:#999}.form-field__error{color:#FF454F}.form--compact .form-field__error{display:block;position:absolute;top:0;right:0}@media screen and (max-width:44.9375em){.header{height:48px}}@media screen and (min-width:45em){.header{height:72px}}.layer__container>.form>.header .header__wrapper{padding-left:24px;padding-right:24px}.header__content{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;width:100%}@media screen and (max-width:44.9375em){.header__wrapper{height:48px}.header__content{line-height:48px}}@media screen and (min-width:45em){.header__wrapper{height:72px}.header__content{line-height:72px}}.header__content>*{-webkit-flex:1 0;flex:1 0}.header__content>:last-child{-webkit-flex:0 0 auto;flex:0 0 auto;text-align:right}.header__content>:first-child{-webkit-flex:1 0;flex:1 0;text-align:left}.header__content .title,.header__content>h1,.header__content>h2,.header__content>h3,.header__content>h4{margin-bottom:0;line-height:inherit}.header__content .title svg,.header__content>h1 svg,.header__content>h2 svg,.header__content>h3 svg,.header__content>h4 svg{height:48px}.header__content a{color:inherit}.header--primary{padding:0}.index-header,.index__container{position:relative;padding-left:24px}.header--primary .header__wrapper{padding-left:24px;padding-right:24px;border-bottom:none}.header--primary .header__content{-webkit-justify-content:space-between;justify-content:space-between;white-space:nowrap}.header--primary .header__content>*{-webkit-flex:auto;flex:auto}.header--primary .header__content>:last-child{-webkit-flex:0 0 auto;flex:0 0 auto}@media screen and (min-width:45em){.header--large,.header--large .header__wrapper{height:96px}.header--large .header__content{line-height:96px}.header--small,.header--small .header__wrapper{height:48px}.header--small .header__content{line-height:48px}.header--small .header__content .title svg,.header--small .header__content>h1 svg,.header--small .header__content>h2 svg,.header--small .header__content>h3 svg,.header--small .header__content>h4 svg{height:24px}.header--primary,.header--primary .header__wrapper{height:96px;line-height:96px}.header--primary .header__content{line-height:96px}.header--primary .header__wrapper{position:fixed;top:0;left:0;right:0;z-index:3}}.control-badge,.control-badge:after{width:18px;height:18px;position:absolute}.tile>.header{height:48px}.tile>.header .header__wrapper{height:48px;border-bottom:none}.tile>.header .header__content{line-height:48px}.control-icon{display:inline-block;width:48px;height:48px;cursor:pointer;fill:#999;stroke:#999}.control-icon--active,.control-icon:hover{fill:#000;stroke:#000}.control-badge{top:0;right:0;border-radius:0;background-color:#60798D;text-align:center;font-size:16px;font-size:1rem;line-height:18px}.control-badge:after{content:'';right:0;border-radius:0;border:1px solid #fff}.status-icon{width:24px;height:24px}.status-icon .status-icon__base{fill:#848484}.status-icon-error .status-icon__base{fill:#FF454F}.status-icon-warning .status-icon__base{fill:#F3B237}.status-icon-ok .status-icon__base{fill:#00B388}.status-icon-disabled .status-icon__base,.status-icon-unknown .status-icon__base{fill:#848484}.status-icon-label .status-icon__base{fill:#999}.status-icon__detail{fill:#fff}.status-icon--large{width:48px;height:48px}.status-icon--small{width:12px;height:12px}.status-icon--small .status-icon__detail{display:none}@-webkit-keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.icon-changing{width:24px;height:24px;-webkit-animation:rotate 1.5s linear infinite;animation:rotate 1.5s linear infinite}.icon-changing--small{width:12px;height:12px}.icon-spinning{width:24px;height:24px;-webkit-animation:rotate 4s steps(4,end)infinite;animation:rotate 4s steps(4,end)infinite}.icon-spinning--small{width:12px;height:12px}.index__container{padding-right:24px;padding-bottom:24px}.index__header{height:48px;line-height:48px}.index__items{padding-top:96px;width:100%}.index__more{padding-top:24px}.index__error{color:#FF454F}.index-header{font-size:30px;font-size:1.875rem;line-height:inherit;padding-right:24px;display:-webkit-flex;display:flex}.index-header__search{-webkit-flex:1;flex:1}.index-header__count{-webkit-flex:0 0 auto;flex:0 0 auto;min-width:192px;margin-left:24px;color:#999;text-align:left}.index-header__out-of{margin-left:12px;font-size:16px;font-size:1rem;line-height:1.5;display:none}.index-header__out-of--active{display:inline}.index-table{width:100%}.index-tiles .tile>.header svg{margin-right:12px}.index-tiles .tile>:not(.header){display:block}a.active>.label .label__icon.control-icon svg{fill:#000;stroke:#000}.layer{position:fixed;top:0;left:0;right:0;overflow:none;z-index:10}.layer__container{position:absolute;background-color:rgba(255,255,255,.95);overflow:none;border-radius:0;max-height:100vh;max-width:100vw}.layer--align-center{background-image:radial-gradient(circle at top,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,179,136,.6))}.layer--align-center .layer__container{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.layer--align-left{background-image:radial-gradient(circle at left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,179,136,.6))}.layer--align-left .layer__container{left:0;-webkit-animation:slide-right .2s ease-in-out forwards;animation:slide-right .2s ease-in-out forwards}.layer--align-right{background-image:radial-gradient(circle at right,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,179,136,.6))}.layer--align-right .layer__container{right:0}.layer--align-top{background-image:radial-gradient(circle at top left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,179,136,.6))}.layer--align-top .layer__container{top:0;-webkit-animation:slide-down .2s ease-in-out forwards;animation:slide-down .2s ease-in-out forwards}.layer--align-bottom{background-image:radial-gradient(circle at bottom left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,179,136,.6))}@-webkit-keyframes slide-right{0%{left:-100vw}100%{left:0}}@keyframes slide-right{0%{left:-100vw}100%{left:0}}@-webkit-keyframes slide-down{0%{top:-100vh}100%{top:0}}@keyframes slide-down{0%{top:-100vh}100%{top:0}}@media screen and (min-width:45em){.label__icon{display:none}}.notifications__container,.panel{background-color:#fff;border-bottom:1px solid #ccc}.login{position:absolute;top:0;left:0;right:0;overflow:hidden;z-index:100}.login__background{position:absolute;max-width:none}.login__background--portrait{width:auto;height:100%}.login__background--landscape{height:auto;width:100%}.login__container{position:relative;width:384px;margin:96px auto;z-index:1;animation-name:fadein;animation-duration:.5s}.login-form,.login__container{-webkit-animation-duration:.5s;-webkit-animation-name:fadein}@media screen and (max-width:44.9375em){.label__text{display:none}.login__container{margin:48px 0;width:100%;border-radius:0}}.login__footer{position:absolute;left:0;right:0;bottom:6px;padding:6px 24px;background-color:rgba(255,255,255,.9);text-align:center}.login-form{width:384px;padding:24px 24px 48px;background-color:rgba(255,255,255,.95);border:1px solid #ccc;border-radius:0;text-align:center;z-index:1;animation-name:fadein;animation-duration:.5s}@media screen and (max-width:44.9375em){.login-form{width:100%;border-radius:0}}.login-form__logo{display:inline-block;width:48px;height:48px;margin-bottom:24px}.login-form fieldset{text-align:left;border:none;margin-bottom:0}.login-form fieldset input,.login-form__error{margin-bottom:12px}.login-form fieldset>*{width:100%;display:block}.login-form__submit{margin-top:24px;width:100%;background-color:#00B388;color:#fff;font-size:24px;font-size:1.5rem;line-height:inherit}.login-form__error{color:#FF454F;text-align:left}.menu--inline.menu--left,.menu__layer--align-right .menu__control,.menu__layer--left{text-align:right}.login-form__footer{margin-top:12px;display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;line-height:36px}.menu,.menu__layer{line-height:inherit}.menu{display:inline-block;font-size:20px;font-size:1.25rem}.menu__control--fixed-label .menu__control-icon,.menu__layer .menu__control-drop-icon{display:none}.menu a:not(.button){color:gray}.menu a:not(.button):hover{color:#333}.menu a:not(.button).active{color:#008565}.menu:focus{outline:0;margin:-1px;border:1px solid #2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}.menu__control{cursor:pointer}.menu__control-drop-icon{width:24px;height:24px;margin-top:-6px;margin-left:12px;stroke:#999}.menu--inline.menu--small .menu__control-icon svg,.menu--small .menu__control-icon svg,.menu__layer--small .menu__control-icon svg{width:18px;height:18px}@media screen and (max-width:44.9375em){.menu__control--labelled .menu__control-drop-icon,.menu__control--labelled .menu__control-label{display:none}}@media screen and (min-width:45em){.menu__control--labelled .menu__control-icon{display:none}}.menu__layer{position:fixed;z-index:5;font-size:24px;font-size:1.5rem;background-color:#fff;border:none;border-radius:0;box-shadow:0 2px 4px rgba(0,0,0,.3)}.menu__layer .menu__control-label{padding-left:24px}.menu__layer a{padding:12px 24px}.menu__layer a:hover{text-decoration:none;background-color:rgba(0,0,0,.1)}.menu--controlled{display:inline-block;cursor:pointer}.menu--inline.menu--left>*{margin-left:24px;margin-right:0}.menu--inline.menu--left>:first-child{margin-left:0}.menu--inline.menu--right>*{margin-left:0;margin-right:24px}.menu--inline.menu--right>:last-child{margin-right:0}@media screen and (max-width:44.9375em){.menu--inline.menu--down:empty{width:0;margin:0;padding:0}}[class*=background-color-index-] .menu--inline a,[class*=background-color-index-] .menu--inline a.active,[class*=background-color-index-] .menu--inline a:hover{color:inherit}[class*=background-color-index-] .menu--inline.menu--left a,[class*=background-color-index-] .menu--inline.menu--right a{text-decoration:none}[class*=background-color-index-] .menu--inline.menu--left a:hover:not(.active):not(.button),[class*=background-color-index-] .menu--inline.menu--right a:hover:not(.active):not(.button){text-decoration:underline}.tile>a,.title a:hover,[class*=background-color-index-] .menu--inline.menu--down a:hover{text-decoration:none}[class*=background-color-index-] .menu--inline.menu--down a{padding:12px;border:1px solid transparent}[class*=background-color-index-] .menu--inline.menu--down a:hover:not(.active){border-color:rgba(0,0,0,.2)}[class*=background-color-index-] .menu--inline.menu--down a.active{background-color:rgba(0,0,0,.2)}.menu--small{font-size:16px;font-size:1rem;line-height:1.5}.menu--small .menu__control-drop-icon{margin-left:6px}.menu--primary{display:block;padding:0 24px 24px;max-height:100vh;overflow:auto}.menu--inline.menu--left>*,.menu--inline.menu--right>*,.menu__layer--left>*,.menu__layer--right>*{display:inline-block}.menu--primary>.header:first-child{margin-left:-24px;margin-right:-24px;margin-bottom:24px}.menu--inline.menu--right,.menu__layer--right,.object,.object__attribute-name{text-align:left}.menu--inline.menu--small,.menu__layer--small{font-size:1em}.menu--inline.menu--small .menu__control-label,.menu__layer--small .menu__control-label{padding:12px}.menu--inline.menu--small a,.menu__layer--small a{padding:6px 12px}.menu--inline.menu--down>*,.menu--inline.menu--up>*,.menu__layer--down>*,.menu__layer--up>*{display:block}.meter,.meter__label,.object__attribute-name{display:inline-block}.menu--inline.menu--down h1,.menu--inline.menu--down h2,.menu--inline.menu--down h3,.menu--inline.menu--down h4,.menu--inline.menu--down h5,.menu--inline.menu--down h6,.menu--inline.menu--up h1,.menu--inline.menu--up h2,.menu--inline.menu--up h3,.menu--inline.menu--up h4,.menu--inline.menu--up h5,.menu--inline.menu--up h6,.menu__layer--down h1,.menu__layer--down h2,.menu__layer--down h3,.menu__layer--down h4,.menu__layer--down h5,.menu__layer--down h6,.menu__layer--up h1,.menu__layer--up h2,.menu__layer--up h3,.menu__layer--up h4,.menu__layer--up h5,.menu__layer--up h6{margin:24px 0 0;padding:12px 0;border-top:1px solid #ccc;min-width:192px}.menu--inline.menu--down h1:first-child,.menu--inline.menu--down h2:first-child,.menu--inline.menu--down h3:first-child,.menu--inline.menu--down h4:first-child,.menu--inline.menu--down h5:first-child,.menu--inline.menu--down h6:first-child,.menu--inline.menu--up h1:first-child,.menu--inline.menu--up h2:first-child,.menu--inline.menu--up h3:first-child,.menu--inline.menu--up h4:first-child,.menu--inline.menu--up h5:first-child,.menu--inline.menu--up h6:first-child,.menu__layer--down h1:first-child,.menu__layer--down h2:first-child,.menu__layer--down h3:first-child,.menu__layer--down h4:first-child,.menu__layer--down h5:first-child,.menu__layer--down h6:first-child,.menu__layer--up h1:first-child,.menu__layer--up h2:first-child,.menu__layer--up h3:first-child,.menu__layer--up h4:first-child,.menu__layer--up h5:first-child,.menu__layer--up h6:first-child{margin-top:0}@-webkit-keyframes draw-meter{0%{stroke-dashoffset:192px}100%{stroke-dashoffset:0}}@keyframes draw-meter{0%{stroke-dashoffset:192px}100%{stroke-dashoffset:0}}.meter__graphic{width:192px;height:24px;background-color:#eee}.notifications-control__icon,.notifications__icon{vertical-align:middle;width:48px;height:48px}.meter__value{stroke:#00B388;stroke-width:18px;stroke-dasharray:192px 192px;stroke-dashoffset:0;-webkit-animation:draw-meter 1.5s;animation:draw-meter 1.5s}.meter__threshold{stroke:#333;stroke-width:1px}.meter__label{vertical-align:top;margin-left:12px}.meter__label-units{color:#999;margin-left:.5em}.notifications{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0,179,136,.6);z-index:10}.notifications__container{position:absolute;top:0;right:0;min-width:300px;padding:96px 24px 24px;border-left:1px solid #ccc;border-bottom-left-radius:0}.notifications__icon{position:absolute;top:24px;right:84px}.object li{width:auto}.object__attribute-name{vertical-align:top;width:192px;color:#999}.object__attribute-value{display:inline-block;vertical-align:top;margin-left:24px;text-align:left;max-width:384px}.section--centered,.settings{text-align:center}.object__attribute-value ul{padding-top:24px}.object__attribute--container>.object__attribute-name{font-weight:700}.object__attribute--unset .object__attribute-value{font-style:italic;color:#999}.object__attribute--array>.object__attribute-value>ol{position:relative}.object__attribute--array>.object__attribute-value>ol>li:first-child{border:none}.object__attribute--array>.object__attribute-value>ol>li>ul{padding-top:0}.panel{padding:24px}.panel:last-of-type{border-bottom:none}.panel__title{text-transform:uppercase;font-weight:400}.panel>a{display:block}.panel a.call-to-action,.radio-button__label,.radio-button__label:before,.search,.search__layer-contents{display:inline-block}.panel a.call-to-action{font-size:20px;font-size:1.25rem;line-height:1.2;margin-bottom:24px;text-decoration:none;padding:12px 24px;border-radius:0;color:#fff}.panel--index-1 .panel__title{color:#60798D}.panel--index-1 a.call-to-action{background-color:#60798D}.panel--index-2 .panel__title{color:#617D78}.panel--index-2 a.call-to-action{background-color:#617D78}@media screen and (max-width:44.9375em){.panel{padding:24px}.panel>h2{margin-bottom:12px}}.radio-button__input{opacity:0;position:absolute}.radio-button__input:checked+label.radio:after{content:"";position:absolute;top:10.5px;left:4px;width:16px;height:16px;background-color:#00B388;border-radius:16px}.radio-button__input:focus+label.checkbox:before{content:"";border-color:#2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}.radio-button__label{position:relative;cursor:pointer;-ms-user-select:none;user-select:none}.radio-button__label:before{content:"";width:24px;height:24px;margin-right:12px;vertical-align:middle;background-color:inherit;color:#008565;border:1px solid #ccc;border-radius:24px;text-align:center}.search:focus{outline:0;margin:-1px;border:1px solid #2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}.search--controlled,.search__control{cursor:pointer}.search__input{margin-right:0;padding:0 12px;font-size:inherit}.search__layer{position:fixed;z-index:2;font-size:20px;font-size:1.25rem;line-height:inherit;background-color:#fff;border:none;border-radius:0;box-shadow:0 2px 4px rgba(0,0,0,.3)}.search__layer--inline{margin-left:-1px}.search__layer input{margin-right:0;box-sizing:border-box}.search__layer .search__control{display:inline-block;vertical-align:top}.search__layer .search__suggestion{padding:6px 12px;cursor:pointer}.search__layer .search__suggestion:hover{background-color:rgba(0,0,0,.1)}.search--inline .search__input{width:100%;box-sizing:border-box;line-height:inherit}.section{padding-top:48px;padding-bottom:48px}.section--right .section__content{display:-webkit-flex;display:flex}.section--right .section__content.center-column__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}@media screen and (max-width:44.9375em){.section--right .section__content.center-column__content>.menu:first-child{width:100%}.section--right .section__content.center-column__content>.menu:first-child:empty{width:0;margin:0;padding:0}}.section--right .section__content>.flex-1{-webkit-flex:1;flex:1}.section--right .section__content>.flex-2{-webkit-flex:2;flex:2}.section--right .section__content>.flex-3{-webkit-flex:3;flex:3}.section--right .section__content>.flex-4{-webkit-flex:4;flex:4}@media screen and (min-width:45em){.section--right .section__content>*{margin-right:48px}.section--right .section__content>:last-child{margin-right:0}.section--right .section__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}}@media screen and (max-width:44.9375em){.section--right .section__content{-webkit-flex-direction:column;flex-direction:column}.section--right .section__content>*{margin-bottom:48px;padding-bottom:48px}.section--right .section__content>:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}}.section--compact{padding-top:0;padding-bottom:0}.section--compact .section__content{padding-top:12px;padding-bottom:12px}.section--centered .section__content>*{margin-left:auto;margin-right:auto}.react-gravatar{width:48px;height:48px;border-radius:24px;border:2px solid transparent;margin:0 24px;overflow:hidden;cursor:pointer}.react-gravatar:hover{border-color:#00B388}.session{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0,179,136,.6);z-index:10}.session__container{position:absolute;top:0;right:0;min-width:300px;padding:96px 24px 24px;background-color:#fff;border-left:1px solid #ccc;border-bottom:1px solid #ccc;border-bottom-left-radius:0}.session .react-gravatar{position:absolute;top:24px;right:24px}.session__actions{margin-top:24px;padding-top:24px}.session a{cursor:pointer}.settings{position:relative}.settings__panels{display:inline-block}.settings__panel{vertical-align:top}.table{width:100%}.table th{font-weight:100;font-size:20px;font-size:1.25rem;border-bottom:1px solid #ccc}.table td,.table th{padding:6px 12px;line-height:36px;text-align:left}.table--selectable tbody tr{cursor:pointer}.table--selectable tbody tr.table__row--selected td{background-color:#d7f5ee}.table--selectable tbody tr:hover td{background-color:rgba(0,0,0,.1)}.tbd{text-align:center;padding:96px;font-size:96px;font-size:6rem;line-height:1;background-color:#ccc;color:#fff}.tile>a,.title a{color:inherit}.tile,.tile>a{padding:24px}.tiles{display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch;margin:-24px}.tiles>*{-webkit-flex:0 0 192px;flex:0 0 192px;flex-grow:1}.tiles--small>*{-webkit-flex-basis:96px;flex-basis:96px}@media screen and (max-width:44.9375em){.tile{margin:0;border-radius:none}}.tile>a{display:block;height:100%}.title{overflow:hidden;text-overflow:ellipsis;font-weight:400;margin-right:24px}[class*=background-color-index-] .title a:hover{text-decoration:underline}.title img,.title svg:not(.control-icon){margin-right:12px}@media screen and (max-width:44.9375em){.title{font-size:32px;font-size:2rem;line-height:inherit}.title img,.title svg:not(.control-icon){height:24px}}@media screen and (min-width:45em){.title{font-size:40px;font-size:2.5rem;line-height:inherit}.title img,.title svg:not(.control-icon){height:48px}}.title--menu .control-icon{margin-left:12px}.title--menu:hover{cursor:pointer}.title--menu:hover .control-icon{stroke:#00B388}.clearfix:after,.i-box:after{content:"";display:table;clear:both} \ No newline at end of file + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,optgroup,strong{font-weight:700}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}#loading,.app{position:absolute}sup{top:-.5em}sub{bottom:-.25em}.app,.layer,.layer--align-bottom .layer__container,.login{bottom:0}img{max-width:100%;vertical-align:middle}svg:not(:root){overflow:hidden}hr{box-sizing:content-box;height:0}pre,textarea{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}#loading,.tbd{font-style:italic}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver}table{border-collapse:collapse;border-spacing:0}blockquote,body,caption,dd,dl,fieldset,figure,form,h1,h2,h3,h4,h5,h6,hr,legend,ol,p,pre,table,td,th,ul{margin:0;padding:0}abbr[title],dfn[title]{cursor:help}ins{border-bottom:1px solid}html{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-size:1em;line-height:1.5;background-color:#fff;color:#333;overflow-y:scroll;min-height:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:'Source Sans Pro',Arial,sans-serif}*,:after,:before{-webkit-box-sizing:inherit;-moz-box-sizing:inherit;box-sizing:inherit}address,blockquote,dl,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,ol,p,pre,table,ul{margin-bottom:1.5rem}dd,ol,ul{margin-left:3rem}h6{font-size:14px;font-size:.875rem;line-height:1.71429}li>ol,li>ul{margin-bottom:0}.gm-style img,img[height],img[width]{max-width:none}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:300;src:local('Source Sans Pro Light'),local('SourceSansPro-Light'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/toadOcfmlt9b38dHJxOBGPS42wKzre0cxmO5m5GyTsY.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:400;src:local('Source Sans Pro'),local('SourceSansPro-Regular'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/ODelI1aHBYDBqgeIAH2zlEY6Fu39Tt9XkmtSosaMoEA.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:700;src:local('Source Sans Pro Bold'),local('SourceSansPro-Bold'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/toadOcfmlt9b38dHJxOBGLlcMrNrsnL9dgADnXgYJjs.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:400;src:local('Source Sans Pro Italic'),local('SourceSansPro-It'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/M2Jd71oPJhLKp0zdtTvoMzpKUtbt71woJ25xl7KOGD0.ttf)format('truetype')}dd,h3,h4,h5,li,p{max-width:576px}.h1,h1{font-size:48px;font-size:3rem;line-height:1;font-weight:600}.h2,.h3,h2,h3{line-height:1.33333;font-size:36px}.h2,h2{font-size:2.25rem;font-weight:400}.h3,.h4,.h5,h3,h4,h5{font-weight:100}.h3,h3{font-size:2.25rem}.h4,h4{font-size:24px;font-size:1.5rem;line-height:1}.h5,h5{font-size:20px;font-size:1.25rem;line-height:1.2}a{background-color:transparent;cursor:pointer}a:hover{text-decoration:underline}a.active{color:#333}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes fadein{from{opacity:0}to{opacity:1}}input,select,textarea{font-size:16px;font-size:1rem;line-height:1.5;padding:5px 12px;border-radius:0;outline:0;margin-right:12px;background-color:inherit}input:focus,select:focus,textarea:focus{border-color:#2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}input::-moz-focus-inner,select::-moz-focus-inner,textarea::-moz-focus-inner{border:none;outline:0}input.error,select.error,textarea.error{border-color:#FF454F}input[type=button],input[type=submit]{line-height:inherit}a.button,button,input[type=button],input[type=submit]{display:inline-block;padding:4px 12px;border:2px solid #00B388;border-radius:0;background-color:inherit;text-decoration:none;cursor:pointer;text-align:center;outline:0}a.button:hover,button:hover,input[type=button]:hover,input[type=submit]:hover{background-color:#eee;border-color:#00B388}a.button.primary,button.primary,input[type=button].primary,input[type=submit].primary{background-color:#008565;border-color:#008565;color:#fff}a.button.primary:hover,button.primary:hover,input[type=button].primary:hover,input[type=submit].primary:hover{background-color:#00B388;border-color:#00B388}a.button.call-to-action,button.call-to-action,input[type=button].call-to-action,input[type=submit].call-to-action{font-size:20px;font-size:1.25rem;line-height:1.2;padding:12px 24px}a.button:focus,button:focus,input[type=button]:focus,input[type=submit]:focus{border-color:#2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}[class*=background-color-index-] a.button:hover,[class*=background-color-index-] button:hover,[class*=background-color-index-] input[type=button]:hover,[class*=background-color-index-] input[type=submit]:hover{background-color:#00B388;border-color:#00B388;text-decoration:none}select{border-color:#ccc;padding-right:24px;-webkit-appearance:none;-moz-appearance:none;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAAXNSR0IArs4c6QAAALNJREFUKBVjYBj6gHH69Olb////L8rIyJiemZl5HpuXgGoMgWpmAtW8ZgIyuIEMU6DCk0CJioaGBiaYJhAbJAaSA6kBqwUKcoiJiXUBBXKAEoxAwcM/f/6MA2liZ2dfBBS3BTKBwv+nvHr1qowRJAECU6dOdQNKzgdiKaDkNyANEuYCsp8BcWJ2dvYukADcepDAjx8/dIFia4CKuUCKQWyQGEwxkI8dTJs2rRLqduwKaCoKAOClUKEWEZS1AAAAAElFTkSuQmCC)center right 6px no-repeat;cursor:pointer}select:hover{background-color:#eee}select::-moz-focus-inner{border:none}select.plain{border:none}input[type=range]{-webkit-appearance:none;border-color:transparent;padding:0}input[type=range]:focus{outline:0}input[type=range]::-moz-focus-inner{border:none}input[type=range]::-webkit-slider-runnable-track{width:100%;height:6px;cursor:pointer;background:0 0;border:1px solid #ccc;border-radius:0}input[type=range]::-webkit-slider-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#00B388;cursor:pointer;-webkit-appearance:none;margin-top:-10px}input[type=range]::-moz-range-track{width:100%;height:6px;cursor:pointer;background:0 0;border:1px solid #ccc;border-radius:0}input[type=range]::-moz-range-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#00B388;cursor:pointer}input[type=range]::-ms-track{width:100%;height:6px;cursor:pointer;border:1px solid transparent;border-radius:0;background:0 0;border-width:16px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#2a6495;border-radius:0}input[type=range]::-ms-fill-upper{background:#3071a9;border-radius:0}input[type=range]::-ms-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#00B388;cursor:pointer}body,html{height:100%;width:100%;overflow:hidden}.i-list-bare{margin:0;padding:0;list-style:none}.app--centered .document,.app--centered .section,.app--centered>.footer,.app--centered>div>.footer{padding-left:24px;padding-right:24px}#loading{width:100%;height:100%;background-color:#ddd;text-align:center;padding-top:100px;font-size:48px;color:#ccc}.app{top:0;left:0;right:0;overflow:auto}.app--inline{position:relative}.app--centered>.header .header__content,.app--centered>div>.header .header__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered>.footer .footer__content,.app--centered>div>.footer .footer__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered .document__content,.app--centered .section__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered .section .document{padding-left:0;padding-right:0}.app--centered .section .document__content{width:auto;max-width:none}.chart{display:block;text-align:right}.chart__grid{stroke:#ccc}.chart__graphic{width:100%}.chart__values-line{stroke-width:3px}.chart__values-line.color-index-error{stroke:#FF454F}.chart__values-line.color-index-warning{stroke:#F3B237}.chart__values-line.color-index-ok{stroke:#00B388}.chart__values-line.color-index-disabled,.chart__values-line.color-index-unknown{stroke:#848484}.chart__values-line.color-index-graph-1,.chart__values-line.color-index-graph-6{stroke:#FF8D6D}.chart__values-line.color-index-graph-2,.chart__values-line.color-index-graph-7{stroke:#877B75}.chart__values-line.color-index-graph-3,.chart__values-line.color-index-graph-8{stroke:#2AD2C9}.chart__values-line.color-index-graph-4,.chart__values-line.color-index-graph-9{stroke:#614767}.chart__values-line.color-index-graph-10,.chart__values-line.color-index-graph-5{stroke:#617D78}.chart__values-area.color-index-error{fill:rgba(255,69,79,.7)}.chart__values-area.color-index-warning{fill:rgba(243,178,55,.7)}.chart__values-area.color-index-ok{fill:rgba(0,179,136,.7)}.chart__values-area.color-index-disabled,.chart__values-area.color-index-unknown{fill:rgba(132,132,132,.7)}.chart__values-area.color-index-graph-1,.chart__values-area.color-index-graph-6{fill:rgba(255,141,109,.7)}.chart__values-area.color-index-graph-2,.chart__values-area.color-index-graph-7{fill:rgba(135,123,117,.7)}.chart__values-area.color-index-graph-3,.chart__values-area.color-index-graph-8{fill:rgba(42,210,201,.7)}.chart__values-area.color-index-graph-4,.chart__values-area.color-index-graph-9{fill:rgba(97,71,103,.7)}.chart__values-area.color-index-graph-10,.chart__values-area.color-index-graph-5{fill:rgba(97,125,120,.7)}.chart__values-bar.color-index-error{fill:rgba(255,69,79,.7)}.chart__values-bar.color-index-warning{fill:rgba(243,178,55,.7)}.chart__values-bar.color-index-ok{fill:rgba(0,179,136,.7)}.chart__values-bar.color-index-disabled,.chart__values-bar.color-index-unknown{fill:rgba(132,132,132,.7)}.chart__values-bar.color-index-graph-1,.chart__values-bar.color-index-graph-6{fill:rgba(255,141,109,.7)}.chart__values-bar.color-index-graph-2,.chart__values-bar.color-index-graph-7{fill:rgba(135,123,117,.7)}.chart__values-bar.color-index-graph-3,.chart__values-bar.color-index-graph-8{fill:rgba(42,210,201,.7)}.chart__values-bar.color-index-graph-4,.chart__values-bar.color-index-graph-9{fill:rgba(97,71,103,.7)}.chart__values-bar.color-index-graph-10,.chart__values-bar.color-index-graph-5{fill:rgba(97,125,120,.7)}.chart__values-bar--active.color-index-error{fill:#FF454F}.chart__values-bar--active.color-index-warning{fill:#F3B237}.chart__values-bar--active.color-index-ok{fill:#00B388}.chart__values-bar--active.color-index-disabled,.chart__values-bar--active.color-index-unknown{fill:#848484}.chart__values-bar--active.color-index-graph-1,.chart__values-bar--active.color-index-graph-6{fill:#FF8D6D}.chart__values-bar--active.color-index-graph-2,.chart__values-bar--active.color-index-graph-7{fill:#877B75}.chart__values-bar--active.color-index-graph-3,.chart__values-bar--active.color-index-graph-8{fill:#2AD2C9}.chart__values-bar--active.color-index-graph-4,.chart__values-bar--active.color-index-graph-9{fill:#614767}.chart__values-bar--active.color-index-graph-10,.chart__values-bar--active.color-index-graph-5{fill:#617D78}.chart__threshold{stroke-width:2px;stroke:#333}.chart__legend{margin:24px 0 0;display:inline-block;text-align:left;list-style-type:none}.chart__legend-label{text-align:right;font-size:20px;font-size:1.25rem;line-height:1.2;margin-bottom:12px}.chart__legend-item,.chart__legend-total{white-space:nowrap}.chart__legend-item>*,.chart__legend-total>*{vertical-align:top}.chart__legend-item-label,.chart__legend-total-label{display:inline-block;width:96px;color:#999}.chart__legend-item-value,.chart__legend-total-value{display:inline-block;width:48px;text-align:right}.chart__legend-item-units,.chart__legend-total-units{margin-left:6px}.chart__legend-item svg.chart__legend-item-swatch{width:12px;height:12px;margin-top:6px;margin-right:12px;overflow:visible}.chart__legend-item svg.chart__legend-item-swatch.color-index-error{stroke:#FF454F}.chart__legend-item svg.chart__legend-item-swatch.color-index-warning{stroke:#F3B237}.chart__legend-item svg.chart__legend-item-swatch.color-index-ok{stroke:#00B388}.chart__legend-item svg.chart__legend-item-swatch.color-index-disabled,.chart__legend-item svg.chart__legend-item-swatch.color-index-unknown{stroke:#848484}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-1,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-6{stroke:#FF8D6D}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-2,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-7{stroke:#877B75}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-3,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-8{stroke:#2AD2C9}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-4,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-9{stroke:#614767}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-10,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-5{stroke:#617D78}.chart__legend-item svg.chart__legend-item-swatch path{stroke-width:12px;transition-property:stroke-width;transition-duration:.3s;transition-timing-function:ease-in-out}.chart__legend-total{margin-top:6px;border-top:1px dotted #ccc;padding-top:6px;margin-left:24px;color:#999}.check-box__input{opacity:0;position:absolute}.check-box__input:checked+label.checkbox:after{content:"";position:absolute;top:10.5px;left:4px;width:16px;height:16px;background-color:#00B388}.check-box__input:focus+label.checkbox:before{content:"";border-color:#2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}.layer__container,.login-form{box-shadow:0 2px 4px rgba(0,0,0,.3)}.check-box__label{position:relative;display:inline-block;cursor:pointer;-ms-user-select:none;user-select:none}.check-box__label,.radio-button__label{-webkit-user-select:none;-moz-user-select:none}.check-box__label:before{content:"";display:inline-block;width:24px;height:24px;margin-right:12px;vertical-align:middle;background-color:inherit;color:#008565;border:1px solid #ccc;border-radius:0;text-align:center}.header-color-index-neutral-1 dt,.header-color-index-neutral-1 h1,.header-color-index-neutral-1 h2,.header-color-index-neutral-1 h3,.header-color-index-neutral-1 h4,.header-color-index-neutral-1 h5,.header-color-index-neutral-1 h6,.header-color-index-neutral-4 dt,.header-color-index-neutral-4 h1,.header-color-index-neutral-4 h2,.header-color-index-neutral-4 h3,.header-color-index-neutral-4 h4,.header-color-index-neutral-4 h5,.header-color-index-neutral-4 h6{color:#60798D}.background-color-index-neutral-1,.background-color-index-neutral-4{background-color:#60798D;color:#fff}.background-color-index-neutral-1 a,.background-color-index-neutral-4 a{color:#fff}.header-color-index-neutral-2 dt,.header-color-index-neutral-2 h1,.header-color-index-neutral-2 h2,.header-color-index-neutral-2 h3,.header-color-index-neutral-2 h4,.header-color-index-neutral-2 h5,.header-color-index-neutral-2 h6,.header-color-index-neutral-5 dt,.header-color-index-neutral-5 h1,.header-color-index-neutral-5 h2,.header-color-index-neutral-5 h3,.header-color-index-neutral-5 h4,.header-color-index-neutral-5 h5,.header-color-index-neutral-5 h6{color:#617D78}.background-color-index-neutral-2,.background-color-index-neutral-5{background-color:#617D78;color:#fff}.background-color-index-neutral-2 a,.background-color-index-neutral-5 a{color:#fff}.header-color-index-neutral-3 dt,.header-color-index-neutral-3 h1,.header-color-index-neutral-3 h2,.header-color-index-neutral-3 h3,.header-color-index-neutral-3 h4,.header-color-index-neutral-3 h5,.header-color-index-neutral-3 h6,.header-color-index-neutral-6 dt,.header-color-index-neutral-6 h1,.header-color-index-neutral-6 h2,.header-color-index-neutral-6 h3,.header-color-index-neutral-6 h4,.header-color-index-neutral-6 h5,.header-color-index-neutral-6 h6{color:#877B75}.background-color-index-neutral-3,.background-color-index-neutral-6{background-color:#877B75;color:#fff}.background-color-index-neutral-3 a,.background-color-index-neutral-6 a{color:#fff}.background-color-index-accent-1,.background-color-index-accent-3{background-color:#2AD2C9;color:#fff}.background-color-index-accent-1 a,.background-color-index-accent-3 a{color:#fff}.background-color-index-accent-2,.background-color-index-accent-4{background-color:#614767;color:#fff}.background-color-index-accent-2 a,.background-color-index-accent-4 a{color:#fff}.background-color-index-grey-1,.background-color-index-grey-5{background-color:#333;color:#fff}.background-color-index-grey-1 a,.background-color-index-grey-5 a{color:#fff}.background-color-index-grey-2,.background-color-index-grey-6{background-color:#3B3B3B;color:#fff}.background-color-index-grey-2 a,.background-color-index-grey-6 a{color:#fff}.background-color-index-grey-3,.background-color-index-grey-7{background-color:#434343;color:#fff}.background-color-index-grey-3 a,.background-color-index-grey-7 a{color:#fff}.background-color-index-grey-4,.background-color-index-grey-8{background-color:#666;color:#fff}.fixed-header,.header__wrapper{background-color:rgba(255,255,255,.9)}.background-color-index-grey-4 a,.background-color-index-grey-8 a{color:#fff}.center-column{padding-left:24px;padding-right:24px}.center-column .center-column__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}@media screen and (min-width:45em){.dashboard{height:calc(100vh - 96px)}}.document{width:100%}.document--no-contents .document__content{padding-left:0}.document section{margin-top:24px;margin-bottom:24px;padding-top:24px}.document header>img,.document section>img{margin-top:48px;margin-bottom:48px;display:block;max-width:576px}@media screen and (max-width:44.9375em){.dashboard{height:calc(100vh - 48px)}.document header>img,.document section>img{max-width:100%}.document header>ol,.document header>ul,.document section>ol,.document section>ul{padding-left:24px;padding-right:24px;margin-left:0;margin-bottom:24px}}.document header>dl>dt,.document section>dl>dt{margin-top:24px;margin-bottom:6px;text-transform:uppercase}.document header>dl>dt code,.document section>dl>dt code{text-transform:none;white-space:pre-wrap}.document header>dl>dd,.document section>dl>dd{margin-left:0}.document header>h2,.document section>h2{position:relative;padding-top:24px}.document header>h2:after,.document section>h2:after{position:absolute;content:'';top:0;left:0;right:0;border-top:1px solid #ccc}.document section:first-child{margin-top:0;padding-top:0}.document section:first-child>h2{padding-top:0}.document section:first-child>h2:after{border-top:none}@-webkit-keyframes draw-stroke{0%{stroke-dashoffset:768px}100%{stroke-dashoffset:0}}@keyframes draw-stroke{0%{stroke-dashoffset:768px}100%{stroke-dashoffset:0}}.donut.series-pre path{stroke-dashoffset:768px}.donut__graphic-container{position:relative;width:192px;height:192px}.donut svg.donut__graphic{position:absolute;top:0;left:0;width:100%;height:100%;overflow:visible}.donut svg.donut__graphic path{stroke-width:24px;stroke-linecap:butt;stroke-dasharray:768px 768px;stroke-dashoffset:0;fill:none;cursor:pointer;-webkit-animation:draw-stroke 3s;animation:draw-stroke 3s}.donut svg.donut__graphic path.donut__slice--active{stroke-width:36px}.donut__slice.color-index-error{stroke:#FF454F}.donut__slice.color-index-warning{stroke:#F3B237}.donut__slice.color-index-ok{stroke:#00B388}.donut__slice.color-index-disabled,.donut__slice.color-index-unknown{stroke:#848484}.donut__slice.color-index-graph-1,.donut__slice.color-index-graph-6{stroke:#FF8D6D}.donut__slice.color-index-graph-2,.donut__slice.color-index-graph-7{stroke:#877B75}.donut__slice.color-index-graph-3,.donut__slice.color-index-graph-8{stroke:#2AD2C9}.donut__slice.color-index-graph-4,.donut__slice.color-index-graph-9{stroke:#614767}.donut__slice.color-index-graph-10,.donut__slice.color-index-graph-5{stroke:#617D78}.donut__active{position:absolute;width:100%;margin-top:60px;text-align:center;white-space:normal;pointer-events:none}.donut__active-value{font-size:36px;font-size:2.25rem;line-height:38px;font-weight:700}.donut__active-units{font-size:24px;font-size:1.5rem;line-height:inherit;margin-left:6px;color:#999;font-weight:400}.donut__active-label{width:60%;margin:0 auto}.donut__legend{text-align:left;list-style-type:none;white-space:normal}.donut--landscape,.header__content,.index-header__count,.search__layer-header{white-space:nowrap}.donut__legend-item,.donut__legend-total{color:#999}.donut__legend-item>*,.donut__legend-total>*{vertical-align:top}.donut__legend-item-label,.donut__legend-total-label{display:inline-block;width:96px}.donut__legend-item-value,.donut__legend-total-value{display:inline-block;width:48px;text-align:right}.donut__legend-item svg.donut__legend-item-swatch{width:12px;height:12px;margin-top:6px;margin-right:12px;overflow:visible}.donut__legend-item svg.donut__legend-item-swatch.color-index-error{stroke:#FF454F}.donut__legend-item svg.donut__legend-item-swatch.color-index-warning{stroke:#F3B237}.donut__legend-item svg.donut__legend-item-swatch.color-index-ok{stroke:#00B388}.donut__legend-item svg.donut__legend-item-swatch.color-index-disabled,.donut__legend-item svg.donut__legend-item-swatch.color-index-unknown{stroke:#848484}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-1,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-6{stroke:#FF8D6D}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-2,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-7{stroke:#877B75}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-3,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-8{stroke:#2AD2C9}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-4,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-9{stroke:#614767}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-10,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-5{stroke:#617D78}.donut__legend-item svg.donut__legend-item-swatch path{stroke-width:12px;transition-property:stroke-width;transition-duration:.3s;transition-timing-function:ease-in-out}.control-icon,.react-gravatar{transition:all .3s ease-in-out}.donut__legend-item--active{color:#333;font-weight:700}.donut__legend-item--active svg.donut__legend-item-swatch path{stroke-width:12px}.donut__legend-total{margin-left:24px}.donut__legend-total>*{margin-top:6px;padding-top:6px;border-top:1px dotted #ccc}.object__attribute--array>.object__attribute-value>ol>li,.session__actions,.tile>.header .header__wrapper{border-top:1px solid #ccc}.donut--landscape .donut__graphic-container,.donut--landscape .donut__legend{display:inline-block;vertical-align:middle}.donut--landscape .donut__legend{margin:0 0 0 24px}.donut--portrait .donut__graphic-container,.donut--portrait .donut__legend{display:block}.donut--portrait .donut__legend{margin:24px 0 0}.donut--small .donut__legend{display:none}.fixed-header{position:fixed;z-index:1}.fixed-header__container{position:absolute;top:0;left:0;right:0}.footer{min-height:48px;line-height:48px}.footer__content{display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;width:100%}.footer__content.center-column__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}@media screen and (max-width:44.9375em){.document header>dl>dd,.document section>dl>dd{padding-right:24px}.fixed-header{position:relative}.fixed-header__container{position:static}.footer__content.center-column__content>.menu:first-child{width:100%}.footer__content.center-column__content>.menu:first-child:empty{width:0;margin:0;padding:0}}.footer__content>.flex-1{-webkit-flex:1;flex:1}.footer__content>.flex-2{-webkit-flex:2;flex:2}.footer__content>.flex-3{-webkit-flex:3;flex:3}.footer__content>.flex-4{-webkit-flex:4;flex:4}.footer__content>*{margin-right:48px}.footer__content>:last-child{margin-right:0}@media screen and (max-width:44.9375em){.footer__content>:last-child{text-align:left}}@media screen and (min-width:45em)and (max-width:63.9375em){.footer__content>:last-child{text-align:left}}.footer__content a.button,.footer__content button,.footer__content input[type=button],.footer__content input[type=submit]{font-size:24px;font-size:1.5rem;line-height:inherit;min-width:96px}.footer--primary{height:auto;padding:24px}.footer--primary .footer__content{position:relative;color:#999}.footer--primary .footer__content p{padding-top:12px;margin:0;max-width:none;text-align:right;line-height:24px}@media screen and (max-width:44.9375em){.footer--primary .footer__content{display:block}}@media screen and (min-width:45em)and (max-width:63.9375em){.footer--primary .footer__content{display:block}}.footer--centered .footer__content{display:block;text-align:center}.footer--centered .footer__content>*{margin-right:auto;margin-left:auto;text-align:center}.tile>.footer{border-bottom:1px solid #ccc}.form{min-width:480px}.form fieldset{border:none;margin:0;padding-bottom:1.5rem}.form .form-fields{padding:24px}.layer .form{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;max-height:100vh}.layer .form>.footer,.layer .form>.header{-webkit-flex:0 0 auto;flex:0 0 auto}.layer .form>.form-fields{overflow:auto}.form--compact{min-width:240px}.form-field{position:relative;margin-bottom:12px;line-height:36px}.form-field:last-child,.form-field__contents>table.table--selectable{margin-bottom:0}@media screen and (min-width:45em){.form:not(.form--compact) .form-field{display:-webkit-flex;display:flex;min-width:672px}}.form-field__label{display:block;text-align:left}@media screen and (min-width:45em){.form:not(.form--compact) .form-field__label{-webkit-flex:0 0 192px;flex:0 0 192px;text-align:right;padding-right:24px;vertical-align:top}.form:not(.form--compact) .form-field__container{-webkit-flex:1 0 384px;flex:1 0 384px}}.form-field__contents button{line-height:24px}.form-field__contents>input[type=email],.form-field__contents>input[type=password],.form-field__contents>input[type=range],.form-field__contents>input[type=text],.form-field__contents>select,.form-field__contents>textarea{width:240px}.form--compact .form-field__contents>input[type=email],.form--compact .form-field__contents>input[type=password],.form--compact .form-field__contents>input[type=range],.form--compact .form-field__contents>input[type=text],.form--compact .form-field__contents>select,.form--compact .form-field__contents>textarea{width:100%;margin-right:0}.form-field__contents>textarea{vertical-align:top}.control-icon,.header__content svg,.status-icon{vertical-align:middle}.form-field__contents>.check-box,.form-field__contents>.radio-button{display:block}.form-field__contents label.checkbox,.form-field__contents label.radio{margin-right:24px}.form-field__contents>table.table--selectable tbody tr td{padding-top:0;padding-bottom:0}.form-field--error input,.form-field--error select,.form-field--error textarea{border-color:#FF454F}.form-field__help{color:#999}.form-field__error{color:#FF454F}.form--compact .form-field__error{display:block;position:absolute;top:0;right:0}@media screen and (max-width:44.9375em){.header{height:48px}}@media screen and (min-width:45em){.header{height:72px}}.header__wrapper{padding-left:24px;padding-right:24px}.header__content{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;width:100%}@media screen and (max-width:44.9375em){.header__wrapper{height:48px}.header__content{line-height:48px}}@media screen and (min-width:45em){.header__wrapper{height:72px}.header__content{line-height:72px}}.header__content>*{-webkit-flex:1 0;flex:1 0}.header__content>:last-child{-webkit-flex:0 0 auto;flex:0 0 auto;text-align:right}.header__content>:first-child{-webkit-flex:1 0;flex:1 0;text-align:left}.header__content .title,.header__content>h1,.header__content>h2,.header__content>h3,.header__content>h4{margin-bottom:0;line-height:inherit}.header__content .title svg,.header__content>h1 svg,.header__content>h2 svg,.header__content>h3 svg,.header__content>h4 svg{height:48px}.header__content a{color:inherit}.header--primary{padding:0}.header--primary .header__wrapper{padding-left:24px;padding-right:24px;border-bottom:none}.header--primary .header__content{-webkit-justify-content:space-between;justify-content:space-between;white-space:nowrap}.header--primary .header__content>*{-webkit-flex:auto;flex:auto}.header--primary .header__content>:last-child{-webkit-flex:0 0 auto;flex:0 0 auto}@media screen and (min-width:45em){.header--large,.header--large .header__wrapper{height:96px}.header--large .header__content{line-height:96px}.header--small,.header--small .header__wrapper{height:48px}.header--small .header__content{line-height:48px}.header--small .header__content .title svg,.header--small .header__content>h1 svg,.header--small .header__content>h2 svg,.header--small .header__content>h3 svg,.header--small .header__content>h4 svg{height:24px}.header--primary,.header--primary .header__wrapper{height:96px;line-height:96px}.header--primary .header__content{line-height:96px}.header--primary .header__wrapper{position:fixed;top:0;left:0;right:0;z-index:3}}.control-badge,.control-badge:after{width:18px;height:18px;position:absolute}.header--flush .header__wrapper{padding-left:0;padding-right:0}.index-header,.index__container{position:relative;padding-left:24px}.tile>.header{height:48px}.tile>.header .header__wrapper{height:48px;border-bottom:none}.tile>.header .header__content{line-height:48px}.control-icon{display:inline-block;width:48px;height:48px;cursor:pointer;fill:#999;stroke:#999}.control-icon--active,.control-icon:hover{fill:#000;stroke:#000}.control-badge{top:0;right:0;border-radius:0;background-color:#60798D;text-align:center;font-size:16px;font-size:1rem;line-height:18px}.control-badge:after{content:'';right:0;border-radius:0;border:1px solid #fff}.status-icon{width:24px;height:24px}.status-icon .status-icon__base{fill:#848484}.status-icon-error .status-icon__base{fill:#FF454F}.status-icon-warning .status-icon__base{fill:#F3B237}.status-icon-ok .status-icon__base{fill:#00B388}.status-icon-disabled .status-icon__base,.status-icon-unknown .status-icon__base{fill:#848484}.status-icon-label .status-icon__base{fill:#999}.status-icon__detail{fill:#fff}.status-icon--large{width:48px;height:48px}.status-icon--small{width:12px;height:12px}.status-icon--small .status-icon__detail{display:none}@-webkit-keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.icon-changing{width:24px;height:24px;-webkit-animation:rotate 1.5s linear infinite;animation:rotate 1.5s linear infinite}.icon-changing--small{width:12px;height:12px}.icon-spinning{width:24px;height:24px;-webkit-animation:rotate 4s steps(4,end)infinite;animation:rotate 4s steps(4,end)infinite}.icon-spinning--small{width:12px;height:12px}.index__container{padding-right:24px;padding-bottom:24px}.index__header{height:48px;line-height:48px}.index__items{padding-top:96px;width:100%}.index__more{padding-top:24px}.index__error{color:#FF454F}.index-header{font-size:30px;font-size:1.875rem;line-height:inherit;padding-right:24px;display:-webkit-flex;display:flex}.index-header__search{-webkit-flex:1;flex:1}.index-header__count{-webkit-flex:0 0 auto;flex:0 0 auto;min-width:192px;margin-left:24px;color:#999;text-align:left}.index-header__out-of{margin-left:12px;font-size:16px;font-size:1rem;line-height:1.5;display:none}.index-header__out-of--active{display:inline}.index-table{width:100%}.index-tiles .tile>.header svg{margin-right:12px}.index-tiles .tile>:not(.header){display:block}a.active>.label .label__icon.control-icon svg{fill:#000;stroke:#000}.layer{position:fixed;top:0;left:0;right:0;overflow:none;z-index:10}.layer__container{position:absolute;background-color:rgba(255,255,255,.95);overflow:none;border-radius:0;max-height:100vh;max-width:100vw}.layer--align-center{background-image:radial-gradient(circle at top,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}.layer--align-center .layer__container{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.layer--align-left{background-image:radial-gradient(circle at left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}.layer--align-left .layer__container{left:0;-webkit-animation:slide-right .2s ease-in-out forwards;animation:slide-right .2s ease-in-out forwards}.layer--align-right{background-image:radial-gradient(circle at right,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}.layer--align-right .layer__container{right:0}.layer--align-top{background-image:radial-gradient(circle at top left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}.layer--align-top .layer__container{top:0;-webkit-animation:slide-down .2s ease-in-out forwards;animation:slide-down .2s ease-in-out forwards}.layer--align-bottom{background-image:radial-gradient(circle at bottom left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}@-webkit-keyframes slide-right{0%{left:-100vw}100%{left:0}}@keyframes slide-right{0%{left:-100vw}100%{left:0}}@-webkit-keyframes slide-down{0%{top:-100vh}100%{top:0}}@keyframes slide-down{0%{top:-100vh}100%{top:0}}@media screen and (min-width:45em){.label__icon{display:none}}.notifications__container,.panel{background-color:#fff;border-bottom:1px solid #ccc}.login{position:absolute;top:0;left:0;right:0;overflow:hidden;z-index:100}.login__background{position:absolute;max-width:none}.login__background--portrait{width:auto;height:100%}.login__background--landscape{height:auto;width:100%}.login__container{position:relative;width:384px;margin:96px auto;z-index:1;animation-name:fadein;animation-duration:.5s}.login-form,.login__container{-webkit-animation-duration:.5s;-webkit-animation-name:fadein}@media screen and (max-width:44.9375em){.label__text{display:none}.login__container{margin:48px 0;width:100%;border-radius:0}}.login__footer{position:absolute;left:0;right:0;bottom:6px;padding:6px 24px;background-color:rgba(255,255,255,.9);text-align:center}.login-form{width:384px;padding:24px 24px 48px;background-color:rgba(255,255,255,.95);border:1px solid #ccc;border-radius:0;text-align:center;z-index:1;animation-name:fadein;animation-duration:.5s}@media screen and (max-width:44.9375em){.login-form{width:100%;border-radius:0}}.login-form__logo{display:inline-block;width:48px;height:48px;margin-bottom:24px}.login-form fieldset{text-align:left;border:none;margin-bottom:0}.login-form fieldset input,.login-form__error{margin-bottom:12px}.login-form fieldset>*{width:100%;display:block}.login-form__submit{margin-top:24px;width:100%;background-color:#00B388;color:#fff;font-size:24px;font-size:1.5rem;line-height:inherit}.login-form__error{color:#FF454F;text-align:left}.menu--inline.menu--left,.menu__layer--align-right .menu__control,.menu__layer--left{text-align:right}.login-form__footer{margin-top:12px;display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;line-height:36px}.menu,.menu__layer{line-height:inherit}.menu{display:inline-block;font-size:20px;font-size:1.25rem}.menu__control--fixed-label .menu__control-icon,.menu__layer .menu__control-drop-icon{display:none}.menu a:not(.button){color:gray}.menu a:not(.button):hover{color:#333}.menu a:not(.button).active{color:#008565}.menu:focus{outline:0;margin:-1px;border:1px solid #2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}.menu__control{cursor:pointer}.menu__control-drop-icon{width:24px;height:24px;margin-top:-6px;margin-left:12px;stroke:#999}.menu--inline.menu--small .menu__control-icon svg,.menu--small .menu__control-icon svg,.menu__layer--small .menu__control-icon svg{width:18px;height:18px}@media screen and (max-width:44.9375em){.menu__control--labelled .menu__control-drop-icon,.menu__control--labelled .menu__control-label{display:none}}@media screen and (min-width:45em){.menu__control--labelled .menu__control-icon{display:none}}.menu__layer{position:fixed;z-index:5;font-size:24px;font-size:1.5rem;background-color:#fff;border:none;border-radius:0;box-shadow:0 2px 4px rgba(0,0,0,.3)}.menu__layer .menu__control-label{padding-left:24px}.menu__layer a{padding:12px 24px}.menu__layer a:hover{text-decoration:none;background-color:rgba(0,0,0,.1)}.menu--controlled{display:inline-block;cursor:pointer}.menu--inline.menu--left>*{margin-left:24px;margin-right:0}.menu--inline.menu--left>:first-child{margin-left:0}.menu--inline.menu--right>*{margin-left:0;margin-right:24px}.menu--inline.menu--right>:last-child{margin-right:0}@media screen and (max-width:44.9375em){.menu--inline.menu--down:empty{width:0;margin:0;padding:0}}[class*=background-color-index-] .menu--inline a,[class*=background-color-index-] .menu--inline a.active,[class*=background-color-index-] .menu--inline a:hover{color:inherit}[class*=background-color-index-] .menu--inline.menu--left a,[class*=background-color-index-] .menu--inline.menu--right a{text-decoration:none}[class*=background-color-index-] .menu--inline.menu--left a:hover:not(.active):not(.button),[class*=background-color-index-] .menu--inline.menu--right a:hover:not(.active):not(.button){text-decoration:underline}.tile>a,.title a:hover,[class*=background-color-index-] .menu--inline.menu--down a:hover{text-decoration:none}[class*=background-color-index-] .menu--inline.menu--down a{padding:12px;border:1px solid transparent}[class*=background-color-index-] .menu--inline.menu--down a:hover:not(.active){border-color:rgba(0,0,0,.2)}[class*=background-color-index-] .menu--inline.menu--down a.active{background-color:rgba(0,0,0,.2)}.menu--small{font-size:16px;font-size:1rem;line-height:1.5}.menu--small .menu__control-drop-icon{margin-left:6px}.menu--primary{display:block;padding:0 24px 24px;max-height:100vh;overflow:auto}.react-gravatar,.tile,.title{overflow:hidden}.menu--inline.menu--left>*,.menu--inline.menu--right>*,.menu__layer--left>*,.menu__layer--right>*{display:inline-block}.menu--primary>.header:first-child{margin-left:-24px;margin-right:-24px;margin-bottom:24px}.menu--inline.menu--right,.menu__layer--right,.object,.object__attribute-name{text-align:left}.menu--inline.menu--small,.menu__layer--small{font-size:1em}.menu--inline.menu--small .menu__control-label,.menu__layer--small .menu__control-label{padding:12px}.menu--inline.menu--small a,.menu__layer--small a{padding:6px 12px}.menu--inline.menu--down>*,.menu--inline.menu--up>*,.menu__layer--down>*,.menu__layer--up>*{display:block}.meter,.meter__label,.object__attribute-name{display:inline-block}.menu--inline.menu--down h1,.menu--inline.menu--down h2,.menu--inline.menu--down h3,.menu--inline.menu--down h4,.menu--inline.menu--down h5,.menu--inline.menu--down h6,.menu--inline.menu--up h1,.menu--inline.menu--up h2,.menu--inline.menu--up h3,.menu--inline.menu--up h4,.menu--inline.menu--up h5,.menu--inline.menu--up h6,.menu__layer--down h1,.menu__layer--down h2,.menu__layer--down h3,.menu__layer--down h4,.menu__layer--down h5,.menu__layer--down h6,.menu__layer--up h1,.menu__layer--up h2,.menu__layer--up h3,.menu__layer--up h4,.menu__layer--up h5,.menu__layer--up h6{margin:24px 0 0;padding:12px 0;border-top:1px solid #ccc;min-width:192px}.menu--inline.menu--down h1:first-child,.menu--inline.menu--down h2:first-child,.menu--inline.menu--down h3:first-child,.menu--inline.menu--down h4:first-child,.menu--inline.menu--down h5:first-child,.menu--inline.menu--down h6:first-child,.menu--inline.menu--up h1:first-child,.menu--inline.menu--up h2:first-child,.menu--inline.menu--up h3:first-child,.menu--inline.menu--up h4:first-child,.menu--inline.menu--up h5:first-child,.menu--inline.menu--up h6:first-child,.menu__layer--down h1:first-child,.menu__layer--down h2:first-child,.menu__layer--down h3:first-child,.menu__layer--down h4:first-child,.menu__layer--down h5:first-child,.menu__layer--down h6:first-child,.menu__layer--up h1:first-child,.menu__layer--up h2:first-child,.menu__layer--up h3:first-child,.menu__layer--up h4:first-child,.menu__layer--up h5:first-child,.menu__layer--up h6:first-child{margin-top:0}@-webkit-keyframes draw-meter{0%{stroke-dashoffset:192px}100%{stroke-dashoffset:0}}@keyframes draw-meter{0%{stroke-dashoffset:192px}100%{stroke-dashoffset:0}}.meter__graphic{width:192px;height:24px;background-color:#eee}.notifications-control__icon,.notifications__icon{vertical-align:middle;width:48px;height:48px}.meter__value{stroke:#00B388;stroke-width:18px;stroke-dasharray:192px 192px;stroke-dashoffset:0;-webkit-animation:draw-meter 1.5s;animation:draw-meter 1.5s}.meter__threshold{stroke:#333;stroke-width:1px}.meter__label{vertical-align:top;margin-left:12px}.meter__label-units{color:#999;margin-left:.5em}.notifications{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(128,128,128,.6);z-index:10}.notifications__container{position:absolute;top:0;right:0;min-width:300px;padding:96px 24px 24px;border-left:1px solid #ccc;border-bottom-left-radius:0}.notifications__icon{position:absolute;top:24px;right:84px}.object li{width:auto}.object__attribute-name{vertical-align:top;width:192px;color:#999}.object__attribute-value{display:inline-block;vertical-align:top;margin-left:24px;text-align:left;max-width:384px}.section--centered,.settings{text-align:center}.object__attribute-value ul{padding-top:24px}.object__attribute--container>.object__attribute-name{font-weight:700}.object__attribute--unset .object__attribute-value{font-style:italic;color:#999}.object__attribute--array>.object__attribute-value>ol{position:relative}.object__attribute--array>.object__attribute-value>ol>li:first-child{border:none}.object__attribute--array>.object__attribute-value>ol>li>ul{padding-top:0}.panel{padding:24px}.panel:last-of-type{border-bottom:none}.panel__title{text-transform:uppercase;font-weight:400}.panel>a{display:block}.panel a.call-to-action,.radio-button__label,.radio-button__label:before,.search,.search__layer-contents{display:inline-block}.panel a.call-to-action{font-size:20px;font-size:1.25rem;line-height:1.2;margin-bottom:24px;text-decoration:none;padding:12px 24px;border-radius:0;color:#fff}.panel--index-1 .panel__title{color:#60798D}.panel--index-1 a.call-to-action{background-color:#60798D}.panel--index-2 .panel__title{color:#617D78}.panel--index-2 a.call-to-action{background-color:#617D78}@media screen and (max-width:44.9375em){.panel{padding:24px}.panel>h2{margin-bottom:12px}}.radio-button__input{opacity:0;position:absolute}.radio-button__input:checked+label.radio:after{content:"";position:absolute;top:10.5px;left:4px;width:16px;height:16px;background-color:#00B388;border-radius:16px}.radio-button__input:focus+label.checkbox:before{content:"";border-color:#2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}.radio-button__label{position:relative;cursor:pointer;-ms-user-select:none;user-select:none}.radio-button__label:before{content:"";width:24px;height:24px;margin-right:12px;vertical-align:middle;background-color:inherit;color:#008565;border:1px solid #ccc;border-radius:24px;text-align:center}.search:focus{outline:0;margin:-1px;border:1px solid #2AD2C9;box-shadow:0 0 1px 1px #2AD2C9}.search--controlled,.search__control{cursor:pointer}.search__input{margin-right:0;padding:0 12px;font-size:inherit}.search__layer{position:fixed;z-index:2;font-size:20px;font-size:1.25rem;line-height:inherit;background-color:#fff;border:none;border-radius:0;box-shadow:0 2px 4px rgba(0,0,0,.3)}.search__layer--inline{margin-left:-1px}.search__layer input{margin-right:0;box-sizing:border-box}.search__layer .search__control{display:inline-block;vertical-align:top}.search__layer .search__suggestion{padding:6px 12px;cursor:pointer}.search__layer .search__suggestion:hover{background-color:rgba(0,0,0,.1)}.search--inline .search__input{width:100%;box-sizing:border-box;line-height:inherit}.section{padding-top:48px;padding-bottom:48px}.section--right .section__content{display:-webkit-flex;display:flex}.section--right .section__content.center-column__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}@media screen and (max-width:44.9375em){.section--right .section__content.center-column__content>.menu:first-child{width:100%}.section--right .section__content.center-column__content>.menu:first-child:empty{width:0;margin:0;padding:0}}.section--right .section__content>.flex-1{-webkit-flex:1;flex:1}.section--right .section__content>.flex-2{-webkit-flex:2;flex:2}.section--right .section__content>.flex-3{-webkit-flex:3;flex:3}.section--right .section__content>.flex-4{-webkit-flex:4;flex:4}@media screen and (min-width:45em){.section--right .section__content>*{margin-right:48px}.section--right .section__content>:last-child{margin-right:0}.section--right .section__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}}@media screen and (max-width:44.9375em){.section--right .section__content{-webkit-flex-direction:column;flex-direction:column}.section--right .section__content>*{margin-bottom:48px;padding-bottom:48px}.section--right .section__content>:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}}.section--compact{padding-top:0;padding-bottom:0}.section--compact .section__content{padding-top:12px;padding-bottom:12px}.section--centered .section__content>*{margin-left:auto;margin-right:auto}.react-gravatar{width:48px;height:48px;border-radius:24px;border:2px solid transparent;margin:0 24px;cursor:pointer}.react-gravatar:hover{border-color:#00B388}.session{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(128,128,128,.6);z-index:10}.session__container{position:absolute;top:0;right:0;min-width:300px;padding:96px 24px 24px;background-color:#fff;border-left:1px solid #ccc;border-bottom:1px solid #ccc;border-bottom-left-radius:0}.session .react-gravatar{position:absolute;top:24px;right:24px}.session__actions{margin-top:24px;padding-top:24px}.session a{cursor:pointer}.settings{position:relative}.settings__panels{display:inline-block}.settings__panel{vertical-align:top}.table{width:100%}.table th{font-weight:100;font-size:20px;font-size:1.25rem;border-bottom:1px solid #ccc}.table td,.table th{padding:6px 12px;line-height:36px;text-align:left}.table--selectable tbody tr{cursor:pointer}.table--selectable tbody tr.table__row--selected td{background-color:#d7f5ee}.table--selectable tbody tr:hover td{background-color:rgba(0,0,0,.1)}.tbd{text-align:center;padding:96px;font-size:96px;font-size:6rem;line-height:1;background-color:#ccc;color:#fff}.tile>a,.title a{color:inherit}.tile,.tiles{padding:12px}.tiles{display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap}.tiles>*{-webkit-flex:0 0 192px;flex:0 0 192px;flex-grow:1}.tiles--flush{margin:-24px}.tiles--small>*{-webkit-flex-basis:96px;flex-basis:96px}.tiles--fill{-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch}.tiles--fill>*{-webkit-flex-grow:1;flex-grow:1}@media screen and (max-width:44.9375em){.tile{margin:0;border-radius:none}}.tile>.header{margin-bottom:24px}.tile>a{display:block;height:100%;padding:24px}.tile--wide{-webkit-flex-basis:100%;flex-basis:100%}.title{text-overflow:ellipsis;font-weight:400;margin-right:24px}[class*=background-color-index-] .title a:hover{text-decoration:underline}.title img,.title svg:not(.control-icon){margin-right:12px}@media screen and (max-width:44.9375em){.title{font-size:32px;font-size:2rem;line-height:inherit}.title img,.title svg:not(.control-icon){height:24px}}@media screen and (min-width:45em){.title{font-size:40px;font-size:2.5rem;line-height:inherit}.title img,.title svg:not(.control-icon){height:48px}}.title--menu .control-icon{margin-left:12px}.title--menu:hover{cursor:pointer}.title--menu:hover .control-icon{stroke:#00B388}.clearfix:after{content:"";display:table;clear:both} \ No newline at end of file diff --git a/css/grommet.css b/css/grommet.css index a1564a4..680d853 100644 --- a/css/grommet.css +++ b/css/grommet.css @@ -501,18 +501,6 @@ img { /* [2] */ max-width: none; } -/*------------------------------------*\ - #PARAGRAPHS -\*------------------------------------*/ -/** - * The `.lede` class is used to make the introductory text (usually a paragraph) - * of a document slightly larger: en.wikipedia.org/wiki/Lede_(news) - */ -.i-lede { - font-size: 18px; - font-size: 1.125rem; - line-height: 1.33333; } - @font-face { font-family: 'Source Sans Pro'; font-style: normal; @@ -739,75 +727,6 @@ html, body { width: 100%; overflow: hidden; } -/*------------------------------------*\ - #LIST-INLINE -\*------------------------------------*/ -/** - * The list-inline object simply displays a list of items in one line. - */ -.i-list-inline { - margin: 0; - padding: 0; - list-style: none; } - .i-list-inline > li { - display: inline-block; } - -/** - * Comma delimited list to semantically mark up lists of tags, etc. - * - * N.B. This component requires that you remove the whitespace between LIs. - * The simplest (and valid) way to achieve this is by omitting the - * closing `` tag. - */ -.i-list-inline--delimited > li + li:before { - content: ",\00A0"; } - -/*------------------------------------*\ - #LIST-BLOCK -\*------------------------------------*/ -/** - * The list-block object creates blocky list items out of a `ul` or `ol`. - */ -.i-list-block { - margin: 0; - padding: 0; - list-style: none; } - -.i-list-block__item, .i-list-block > li { - padding: 24px; } - -/** - * Tiny list-blocks. - */ -.i-list-block--tiny > .i-list-block__item, .i-list-block.i-list-block--tiny > li { - padding: 6px; } - -/** - * Small list-blocks. - */ -.i-list-block--small > .i-list-block__item, .i-list-block.i-list-block--small > li { - padding: 12px; } - -/*------------------------------------*\ - #LIST-UI -\*------------------------------------*/ -/** - * The UI list object creates blocky list items with a keyline separator out of - * a `ul` or `ol`. - */ -.i-list-ui, .i-list-ui__item, .i-list-ui > li { - border: 0 solid #ccc; } - -.i-list-ui { - margin: 0; - padding: 0; - list-style: none; - border-top-width: 1px; } - -.i-list-ui__item, .i-list-ui > li { - padding: 24px; - border-bottom-width: 1px; } - /*------------------------------------*\ #LIST-BARE \*------------------------------------*/ @@ -819,107 +738,6 @@ html, body { padding: 0; list-style: none; } -/*------------------------------------*\ - #BOX -\*------------------------------------*/ -/** - * The box object simply boxes off content. - */ -/** - * 1. So we can apply the `.box` class to naturally-inline elements. - */ -.i-box { - display: block; - /* [1] */ - padding: 24px; } - .i-box > :last-child { - margin-bottom: 0; } - -/** - * Small box. - */ -.i-box--small { - padding: 12px; } - -/*------------------------------------*\ - #PACK -\*------------------------------------*/ -/** - * The pack object simply causes any number of elements pack up horizontally to - * automatically fill an equal, fluid width of their parent. - */ -/** - * 1. Fill all available space. - * 2. Cause children to be automatically equally sized. - */ -.i-pack { - width: 100%; - /* [1] */ - display: table; - table-layout: fixed; - /* [2] */ } - -/** - * Cause children to adopt table-like structure. - */ -.i-pack__item { - display: table-cell; } - -/*------------------------------------*\ - #LAYOUT -\*------------------------------------*/ -/** - * The inuitcss layout system uses `box-sizing: border-box;` and - * `display: inline-block;` to create an extremely powerful, flexible - * alternative to the traditional grid system. Combine the layout items with - * the widths found in `trumps.widths`. - */ -/** - * Begin a layout group. - */ -.i-layout { - list-style: none; - margin: 0; - padding: 0; - margin-left: -24px; } - -/** - * 1. Cause columns to stack side-by-side. - * 2. Space columns apart. - * 3. Align columns to the tops of each other. - * 4. Full-width unless told to behave otherwise. - * 5. Required to combine fluid widths and fixed gutters. - */ -.i-layout__item { - display: inline-block; - /* [1] */ - padding-left: 24px; - /* [2] */ - vertical-align: top; - /* [3] */ - width: 100%; - /* [4] */ } - -/** - * Make the layout items fill up from the center outward. - */ -.i-layout--center { - text-align: center; } - .i-layout--center > .i-layout__item { - text-align: left; } - -/*------------------------------------*\ - #TABLES -\*------------------------------------*/ -.i-table { - width: 100%; } - -/** - * Lightly packed cells. - */ -.i-table--cosy th, .i-table--cosy td { - padding: 12px; } - #loading { position: absolute; width: 100%; @@ -969,42 +787,179 @@ html, body { max-width: none; } .chart { - display: block; } + display: block; + text-align: right; } .chart__grid { stroke: #ccc; } - .chart__lines-line { + .chart__graphic { + width: 100%; } + .chart__values-line { stroke-width: 3px; } - .chart__lines-line.color-index-accent-1, .chart__lines-line.color-index-accent-8 { + .chart__values-line.color-index-error { + stroke: #dc442f; } + .chart__values-line.color-index-warning { + stroke: #f4b51e; } + .chart__values-line.color-index-ok { + stroke: #42a425; } + .chart__values-line.color-index-unknown { + stroke: #848484; } + .chart__values-line.color-index-disabled { + stroke: #848484; } + .chart__values-line.color-index-graph-1, .chart__values-line.color-index-graph-8 { stroke: #ff9e2c; } - .chart__lines-line.color-index-accent-2, .chart__lines-line.color-index-accent-9 { + .chart__values-line.color-index-graph-2, .chart__values-line.color-index-graph-9 { stroke: #00cee4; } - .chart__lines-line.color-index-accent-3, .chart__lines-line.color-index-accent-10 { + .chart__values-line.color-index-graph-3, .chart__values-line.color-index-graph-10 { stroke: #5b3eff; } - .chart__lines-line.color-index-accent-4, .chart__lines-line.color-index-accent-11 { + .chart__values-line.color-index-graph-4, .chart__values-line.color-index-graph-11 { stroke: #cc9933; } - .chart__lines-line.color-index-accent-5, .chart__lines-line.color-index-accent-12 { + .chart__values-line.color-index-graph-5, .chart__values-line.color-index-graph-12 { stroke: #d55af2; } - .chart__lines-line.color-index-accent-6, .chart__lines-line.color-index-accent-13 { + .chart__values-line.color-index-graph-6, .chart__values-line.color-index-graph-13 { stroke: #79a2bc; } - .chart__lines-line.color-index-accent-7, .chart__lines-line.color-index-accent-14 { + .chart__values-line.color-index-graph-7, .chart__values-line.color-index-graph-14 { stroke: #877b75; } - .chart__lines-area.color-index-accent-1, .chart__lines-area.color-index-accent-8 { - fill: rgba(255, 158, 44, 0.5); } - .chart__lines-area.color-index-accent-2, .chart__lines-area.color-index-accent-9 { - fill: rgba(0, 206, 228, 0.5); } - .chart__lines-area.color-index-accent-3, .chart__lines-area.color-index-accent-10 { - fill: rgba(91, 62, 255, 0.5); } - .chart__lines-area.color-index-accent-4, .chart__lines-area.color-index-accent-11 { - fill: rgba(204, 153, 51, 0.5); } - .chart__lines-area.color-index-accent-5, .chart__lines-area.color-index-accent-12 { - fill: rgba(213, 90, 242, 0.5); } - .chart__lines-area.color-index-accent-6, .chart__lines-area.color-index-accent-13 { - fill: rgba(121, 162, 188, 0.5); } - .chart__lines-area.color-index-accent-7, .chart__lines-area.color-index-accent-14 { - fill: rgba(135, 123, 117, 0.5); } + .chart__values-area.color-index-error { + fill: rgba(220, 68, 47, 0.7); } + .chart__values-area.color-index-warning { + fill: rgba(244, 181, 30, 0.7); } + .chart__values-area.color-index-ok { + fill: rgba(66, 164, 37, 0.7); } + .chart__values-area.color-index-unknown { + fill: rgba(132, 132, 132, 0.7); } + .chart__values-area.color-index-disabled { + fill: rgba(132, 132, 132, 0.7); } + .chart__values-area.color-index-graph-1, .chart__values-area.color-index-graph-8 { + fill: rgba(255, 158, 44, 0.7); } + .chart__values-area.color-index-graph-2, .chart__values-area.color-index-graph-9 { + fill: rgba(0, 206, 228, 0.7); } + .chart__values-area.color-index-graph-3, .chart__values-area.color-index-graph-10 { + fill: rgba(91, 62, 255, 0.7); } + .chart__values-area.color-index-graph-4, .chart__values-area.color-index-graph-11 { + fill: rgba(204, 153, 51, 0.7); } + .chart__values-area.color-index-graph-5, .chart__values-area.color-index-graph-12 { + fill: rgba(213, 90, 242, 0.7); } + .chart__values-area.color-index-graph-6, .chart__values-area.color-index-graph-13 { + fill: rgba(121, 162, 188, 0.7); } + .chart__values-area.color-index-graph-7, .chart__values-area.color-index-graph-14 { + fill: rgba(135, 123, 117, 0.7); } + .chart__values-bar.color-index-error { + fill: rgba(220, 68, 47, 0.7); } + .chart__values-bar.color-index-warning { + fill: rgba(244, 181, 30, 0.7); } + .chart__values-bar.color-index-ok { + fill: rgba(66, 164, 37, 0.7); } + .chart__values-bar.color-index-unknown { + fill: rgba(132, 132, 132, 0.7); } + .chart__values-bar.color-index-disabled { + fill: rgba(132, 132, 132, 0.7); } + .chart__values-bar.color-index-graph-1, .chart__values-bar.color-index-graph-8 { + fill: rgba(255, 158, 44, 0.7); } + .chart__values-bar.color-index-graph-2, .chart__values-bar.color-index-graph-9 { + fill: rgba(0, 206, 228, 0.7); } + .chart__values-bar.color-index-graph-3, .chart__values-bar.color-index-graph-10 { + fill: rgba(91, 62, 255, 0.7); } + .chart__values-bar.color-index-graph-4, .chart__values-bar.color-index-graph-11 { + fill: rgba(204, 153, 51, 0.7); } + .chart__values-bar.color-index-graph-5, .chart__values-bar.color-index-graph-12 { + fill: rgba(213, 90, 242, 0.7); } + .chart__values-bar.color-index-graph-6, .chart__values-bar.color-index-graph-13 { + fill: rgba(121, 162, 188, 0.7); } + .chart__values-bar.color-index-graph-7, .chart__values-bar.color-index-graph-14 { + fill: rgba(135, 123, 117, 0.7); } + .chart__values-bar--active.color-index-error { + fill: #dc442f; } + .chart__values-bar--active.color-index-warning { + fill: #f4b51e; } + .chart__values-bar--active.color-index-ok { + fill: #42a425; } + .chart__values-bar--active.color-index-unknown { + fill: #848484; } + .chart__values-bar--active.color-index-disabled { + fill: #848484; } + .chart__values-bar--active.color-index-graph-1, .chart__values-bar--active.color-index-graph-8 { + fill: #ff9e2c; } + .chart__values-bar--active.color-index-graph-2, .chart__values-bar--active.color-index-graph-9 { + fill: #00cee4; } + .chart__values-bar--active.color-index-graph-3, .chart__values-bar--active.color-index-graph-10 { + fill: #5b3eff; } + .chart__values-bar--active.color-index-graph-4, .chart__values-bar--active.color-index-graph-11 { + fill: #cc9933; } + .chart__values-bar--active.color-index-graph-5, .chart__values-bar--active.color-index-graph-12 { + fill: #d55af2; } + .chart__values-bar--active.color-index-graph-6, .chart__values-bar--active.color-index-graph-13 { + fill: #79a2bc; } + .chart__values-bar--active.color-index-graph-7, .chart__values-bar--active.color-index-graph-14 { + fill: #877b75; } .chart__threshold { stroke-width: 2px; stroke: #333333; } + .chart__legend { + margin: 24px 0 0; + display: inline-block; + text-align: left; + list-style-type: none; } + .chart__legend-label { + text-align: right; + font-size: 20px; + font-size: 1.25rem; + line-height: 1.2; + margin-bottom: 12px; } + .chart__legend-item, .chart__legend-total { + white-space: nowrap; } + .chart__legend-item > *, .chart__legend-total > * { + vertical-align: top; } + .chart__legend-item-label, .chart__legend-total-label { + display: inline-block; + width: 96px; + color: #999; } + .chart__legend-item-value, .chart__legend-total-value { + display: inline-block; + width: 48px; + text-align: right; } + .chart__legend-item-units, .chart__legend-total-units { + margin-left: 6px; } + .chart__legend-item svg.chart__legend-item-swatch { + width: 12px; + height: 12px; + margin-top: 6px; + margin-right: 12px; + overflow: visible; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-error { + stroke: #dc442f; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-warning { + stroke: #f4b51e; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-ok { + stroke: #42a425; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-unknown { + stroke: #848484; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-disabled { + stroke: #848484; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-1, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-8 { + stroke: #ff9e2c; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-2, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-9 { + stroke: #00cee4; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-3, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-10 { + stroke: #5b3eff; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-4, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-11 { + stroke: #cc9933; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-5, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-12 { + stroke: #d55af2; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-6, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-13 { + stroke: #79a2bc; } + .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-7, .chart__legend-item svg.chart__legend-item-swatch.color-index-graph-14 { + stroke: #877b75; } + .chart__legend-item svg.chart__legend-item-swatch path { + stroke-width: 12px; + transition-property: stroke-width; + transition-duration: 0.3s; + transition-timing-function: ease-in-out; } + .chart__legend-total { + margin-top: 6px; + border-top: 1px dotted #ccc; + padding-top: 6px; + margin-left: 24px; + color: #999; } .check-box__input { opacity: 0; @@ -1132,6 +1087,13 @@ html, body { margin-left: auto; margin-right: auto; } +@media screen and (min-width: 45em) { + .dashboard { + height: calc(100vh - 96px); } } +@media screen and (max-width: 44.9375em) { + .dashboard { + height: calc(100vh - 48px); } } + .document { width: 100%; } .document--no-contents .document__content { @@ -1198,107 +1160,150 @@ html, body { 100% { stroke-dashoffset: 0; } } -.donut { - display: inline-block; } - .donut.series-pre path { - stroke-dashoffset: 768px; } - .donut__graphic-container { - position: relative; - width: 192px; - height: 192px; } - .donut svg.donut__graphic { - position: absolute; - top: 0px; - left: 0px; - width: 100%; - height: 100%; - overflow: visible; } - .donut svg.donut__graphic path { - stroke-width: 24px; - stroke-linecap: butt; - stroke-dasharray: 768px 768px; - stroke-dashoffset: 0; - fill: none; - cursor: pointer; - -webkit-animation: draw-stroke 3s; - animation: draw-stroke 3s; } - .donut svg.donut__graphic path.donut__slice--active { - stroke-width: 36px; } - .donut__slice--color-index-error { +.donut.series-pre path { + stroke-dashoffset: 768px; } +.donut__graphic-container { + position: relative; + width: 192px; + height: 192px; } +.donut svg.donut__graphic { + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height: 100%; + overflow: visible; } + .donut svg.donut__graphic path { + stroke-width: 24px; + stroke-linecap: butt; + stroke-dasharray: 768px 768px; + stroke-dashoffset: 0; + fill: none; + cursor: pointer; + -webkit-animation: draw-stroke 3s; + animation: draw-stroke 3s; } + .donut svg.donut__graphic path.donut__slice--active { + stroke-width: 36px; } +.donut__slice.color-index-error { + stroke: #dc442f; } +.donut__slice.color-index-warning { + stroke: #f4b51e; } +.donut__slice.color-index-ok { + stroke: #42a425; } +.donut__slice.color-index-unknown { + stroke: #848484; } +.donut__slice.color-index-disabled { + stroke: #848484; } +.donut__slice.color-index-graph-1, .donut__slice.color-index-graph-8 { + stroke: #ff9e2c; } +.donut__slice.color-index-graph-2, .donut__slice.color-index-graph-9 { + stroke: #00cee4; } +.donut__slice.color-index-graph-3, .donut__slice.color-index-graph-10 { + stroke: #5b3eff; } +.donut__slice.color-index-graph-4, .donut__slice.color-index-graph-11 { + stroke: #cc9933; } +.donut__slice.color-index-graph-5, .donut__slice.color-index-graph-12 { + stroke: #d55af2; } +.donut__slice.color-index-graph-6, .donut__slice.color-index-graph-13 { + stroke: #79a2bc; } +.donut__slice.color-index-graph-7, .donut__slice.color-index-graph-14 { + stroke: #877b75; } +.donut__active { + position: absolute; + width: 100%; + margin-top: 60px; + text-align: center; + white-space: normal; + pointer-events: none; } + .donut__active-value { + font-size: 36px; + font-size: 2.25rem; + line-height: 38px; + font-weight: bold; } + .donut__active-units { + font-size: 24px; + font-size: 1.5rem; + line-height: inherit; + margin-left: 6px; + color: #999; + font-weight: normal; } + .donut__active-label { + width: 60%; + margin: 0px auto; } +.donut__legend { + text-align: left; + list-style-type: none; + white-space: normal; } +.donut__legend-item, .donut__legend-total { + color: #999; } + .donut__legend-item > *, .donut__legend-total > * { + vertical-align: top; } + .donut__legend-item-label, .donut__legend-total-label { + display: inline-block; + width: 96px; } + .donut__legend-item-value, .donut__legend-total-value { + display: inline-block; + width: 48px; + text-align: right; } +.donut__legend-item svg.donut__legend-item-swatch { + width: 12px; + height: 12px; + margin-top: 6px; + margin-right: 12px; + overflow: visible; } + .donut__legend-item svg.donut__legend-item-swatch.color-index-error { stroke: #dc442f; } - .donut__slice--color-index-warning { + .donut__legend-item svg.donut__legend-item-swatch.color-index-warning { stroke: #f4b51e; } - .donut__slice--color-index-ok { + .donut__legend-item svg.donut__legend-item-swatch.color-index-ok { stroke: #42a425; } - .donut__slice--color-index-unknown { + .donut__legend-item svg.donut__legend-item-swatch.color-index-unknown { stroke: #848484; } - .donut__slice--color-index-disabled { + .donut__legend-item svg.donut__legend-item-swatch.color-index-disabled { stroke: #848484; } - .donut__slice--color-index-1, .donut__slice--color-index-8 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-1, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-8 { stroke: #ff9e2c; } - .donut__slice--color-index-2, .donut__slice--color-index-9 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-2, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-9 { stroke: #00cee4; } - .donut__slice--color-index-3, .donut__slice--color-index-10 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-3, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-10 { stroke: #5b3eff; } - .donut__slice--color-index-4, .donut__slice--color-index-11 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-4, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-11 { stroke: #cc9933; } - .donut__slice--color-index-5, .donut__slice--color-index-12 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-5, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-12 { stroke: #d55af2; } - .donut__slice--color-index-6, .donut__slice--color-index-13 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-6, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-13 { stroke: #79a2bc; } - .donut__slice--color-index-7, .donut__slice--color-index-14 { + .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-7, .donut__legend-item svg.donut__legend-item-swatch.color-index-graph-14 { stroke: #877b75; } - .donut__active { - position: absolute; - width: 100%; - margin-top: 72px; - text-align: center; - pointer-events: none; } - .donut__active-value { - font-size: 36px; - font-size: 2.25rem; - line-height: 38px; - font-weight: bold; } - .donut__active-units { - font-size: 24px; - font-size: 1.5rem; - line-height: inherit; - margin-left: 6px; - color: #999; - font-weight: normal; } - .donut__active-label { - width: 60%; - margin: 0px auto; } - .donut__key { - margin-top: 24px; + .donut__legend-item svg.donut__legend-item-swatch path { + stroke-width: 12px; + transition-property: stroke-width; + transition-duration: 0.3s; + transition-timing-function: ease-in-out; } +.donut__legend-item--active { + color: #333; + font-weight: bold; } + .donut__legend-item--active svg.donut__legend-item-swatch path { + stroke-width: 12px; } +.donut__legend-total { + margin-left: 24px; } + .donut__legend-total > * { + margin-top: 6px; + padding-top: 6px; + border-top: 1px dotted #ccc; } +.donut--landscape { + white-space: nowrap; } + .donut--landscape .donut__graphic-container, .donut--landscape .donut__legend { display: inline-block; - text-align: left; } - .donut__key-item { - color: #999; } - .donut__key-item > * { - vertical-align: top; } - .donut__key-item svg.donut__key-item-swatch { - width: 12px; - height: 12px; - margin-top: 6px; - margin-right: 12px; - overflow: visible; } - .donut__key-item svg.donut__key-item-swatch path { - stroke-width: 6px; - transition-property: stroke-width; - transition-duration: 0.3s; - transition-timing-function: ease-in-out; } - .donut__key-item-label { - display: inline-block; - width: 96px; } - .donut__key-item-value { - display: inline-block; - width: 48px; - text-align: right; } - .donut__key-item--active { - color: #333; } - .donut__key-item--active svg.donut__key-item-swatch path { - stroke-width: 12px; } + vertical-align: middle; } + .donut--landscape .donut__legend { + margin: 0 0 0 24px; } +.donut--portrait .donut__graphic-container, .donut--portrait .donut__legend { + display: block; } +.donut--portrait .donut__legend { + margin: 24px 0 0; } +.donut--small .donut__legend { + display: none; } .fixed-header { position: fixed; @@ -1474,16 +1479,15 @@ html, body { .header { height: 72px; } } .header__wrapper { - background-color: rgba(255, 255, 255, 0.9); } + background-color: rgba(255, 255, 255, 0.9); + padding-left: 24px; + padding-right: 24px; } @media screen and (max-width: 44.9375em) { .header__wrapper { height: 48px; } } @media screen and (min-width: 45em) { .header__wrapper { height: 72px; } } - .layer__container > .form > .header .header__wrapper { - padding-left: 24px; - padding-right: 24px; } .header__content { display: -webkit-flex; display: flex; @@ -1566,6 +1570,9 @@ html, body { left: 0px; right: 0px; z-index: 3; } } +.header--flush .header__wrapper { + padding-left: 0px; + padding-right: 0px; } .tile > .header { height: 48px; } .tile > .header .header__wrapper { @@ -1749,29 +1756,29 @@ a.active > .label .label__icon.control-icon svg { max-width: 100vw; box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.3); } .layer--align-center { - background-image: radial-gradient(circle at top, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 128, 255, 0.6)); } + background-image: radial-gradient(circle at top, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-center .layer__container { left: 50%; -webkit-transform: translateX(-50%); transform: translateX(-50%); } .layer--align-left { - background-image: radial-gradient(circle at left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 128, 255, 0.6)); } + background-image: radial-gradient(circle at left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-left .layer__container { left: 0px; -webkit-animation: slide-right 0.2s ease-in-out forwards; animation: slide-right 0.2s ease-in-out forwards; } .layer--align-right { - background-image: radial-gradient(circle at right, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 128, 255, 0.6)); } + background-image: radial-gradient(circle at right, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-right .layer__container { right: 0px; } .layer--align-top { - background-image: radial-gradient(circle at top left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 128, 255, 0.6)); } + background-image: radial-gradient(circle at top left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-top .layer__container { top: 0px; -webkit-animation: slide-down 0.2s ease-in-out forwards; animation: slide-down 0.2s ease-in-out forwards; } .layer--align-bottom { - background-image: radial-gradient(circle at bottom left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(0, 128, 255, 0.6)); } + background-image: radial-gradient(circle at bottom left, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0.95) 20%, rgba(128, 128, 128, 0.6)); } .layer--align-bottom .layer__container { bottom: 0px; } @@ -2138,7 +2145,7 @@ a.active > .label .label__icon.control-icon svg { left: 0px; right: 0px; bottom: 0px; - background-color: rgba(0, 128, 255, 0.6); + background-color: rgba(128, 128, 128, 0.6); z-index: 10; } .notifications__container { position: absolute; @@ -2389,7 +2396,7 @@ a.active > .label .label__icon.control-icon svg { left: 0px; right: 0px; bottom: 0px; - background-color: rgba(0, 128, 255, 0.6); + background-color: rgba(128, 128, 128, 0.6); z-index: 10; } .session__container { position: absolute; @@ -2455,31 +2462,43 @@ a.active > .label .label__icon.control-icon svg { display: flex; -webkit-flex-wrap: wrap; flex-wrap: wrap; - -webkit-align-items: stretch; - align-items: stretch; - -webkit-align-content: stretch; - align-content: stretch; - margin: -24px; } + padding: 12px; } .tiles > * { -webkit-flex: 0 0 192px; flex: 0 0 192px; flex-grow: 1; } + .tiles--flush { + margin: -24px; } .tiles--small > * { -webkit-flex-basis: 96px; flex-basis: 96px; } + .tiles--fill { + -webkit-align-items: stretch; + align-items: stretch; + -webkit-align-content: stretch; + align-content: stretch; } + .tiles--fill > * { + -webkit-flex-grow: 1; + flex-grow: 1; } .tile { - padding: 24px; } + padding: 12px; + overflow: hidden; } @media screen and (max-width: 44.9375em) { .tile { margin: 0px; border-radius: none; } } + .tile > .header { + margin-bottom: 24px; } .tile > a { display: block; height: 100%; text-decoration: none; color: inherit; padding: 24px; } + .tile--wide { + -webkit-flex-basis: 100%; + flex-basis: 100%; } .title { overflow: hidden; @@ -2525,7 +2544,7 @@ a.active > .label .label__icon.control-icon svg { * Extend the clearfix class with Sass to avoid the `.clearfix` class appearing * over and over in your markup. */ -.clearfix:after, .i-box:after { +.clearfix:after { content: ""; display: table; clear: both; } diff --git a/css/grommet.min.css b/css/grommet.min.css index 8fe01c0..b289e2e 100644 --- a/css/grommet.min.css +++ b/css/grommet.min.css @@ -2,4 +2,4 @@ * inuitcss, by @csswizardry * * github.com/inuitcss | inuitcss.com - *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */dfn,img{font-style:italic}img,legend{border:0}a,ins,u{text-decoration:none}a,a:visited{color:#ff9e2c}code.hljs,input,select,textarea{border:1px solid #ccc}.i-layout,.i-list-bare,.i-list-block,.i-list-inline,.i-list-ui{list-style:none}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,optgroup,strong{font-weight:700}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}#loading,.app{position:absolute}sup{top:-.5em}sub{bottom:-.25em}.app,.layer,.layer--align-bottom .layer__container,.login{bottom:0}img{max-width:100%;vertical-align:middle}svg:not(:root){overflow:hidden}hr{box-sizing:content-box;height:0}pre,textarea{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}#loading,.tbd{font-style:italic}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver}table{border-collapse:collapse;border-spacing:0}blockquote,body,caption,dd,dl,fieldset,figure,form,h1,h2,h3,h4,h5,h6,hr,legend,ol,p,pre,table,td,th,ul{margin:0;padding:0}abbr[title],dfn[title]{cursor:help}ins{border-bottom:1px solid}html{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-size:1em;line-height:1.5;background-color:#fff;color:#333;overflow-y:scroll;min-height:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:'Source Sans Pro',Arial,sans-serif}*,:after,:before{-webkit-box-sizing:inherit;-moz-box-sizing:inherit;box-sizing:inherit}address,blockquote,dl,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,ol,p,pre,table,ul{margin-bottom:1.5rem}.i-box>:last-child,li>ol,li>ul{margin-bottom:0}dd,ol,ul{margin-left:3rem}h6{font-size:14px;font-size:.875rem;line-height:1.71429}.gm-style img,img[height],img[width]{max-width:none}.i-lede{font-size:18px;font-size:1.125rem;line-height:1.33333}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:300;src:local('Source Sans Pro Light'),local('SourceSansPro-Light'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/toadOcfmlt9b38dHJxOBGPS42wKzre0cxmO5m5GyTsY.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:400;src:local('Source Sans Pro'),local('SourceSansPro-Regular'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/ODelI1aHBYDBqgeIAH2zlEY6Fu39Tt9XkmtSosaMoEA.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:700;src:local('Source Sans Pro Bold'),local('SourceSansPro-Bold'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/toadOcfmlt9b38dHJxOBGLlcMrNrsnL9dgADnXgYJjs.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:400;src:local('Source Sans Pro Italic'),local('SourceSansPro-It'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/M2Jd71oPJhLKp0zdtTvoMzpKUtbt71woJ25xl7KOGD0.ttf)format('truetype')}dd,h3,h4,h5,li,p{max-width:576px}.h1,h1{font-size:48px;font-size:3rem;line-height:1;font-weight:600}.h2,.h3,h2,h3{line-height:1.33333;font-size:36px}.h2,h2{font-size:2.25rem;font-weight:400}.h3,.h4,.h5,h3,h4,h5{font-weight:100}.h3,h3{font-size:2.25rem}.h4,h4{font-size:24px;font-size:1.5rem;line-height:1}.h5,h5{font-size:20px;font-size:1.25rem;line-height:1.2}a{background-color:transparent;cursor:pointer}a:hover{text-decoration:underline}a.active{color:#333}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes fadein{from{opacity:0}to{opacity:1}}input,select,textarea{font-size:16px;font-size:1rem;line-height:1.5;padding:5px 12px;border-radius:4px;outline:0;margin-right:12px;background-color:inherit}input:focus,select:focus,textarea:focus{border-color:#ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}input::-moz-focus-inner,select::-moz-focus-inner,textarea::-moz-focus-inner{border:none;outline:0}input.error,select.error,textarea.error{border-color:#dc442f}input[type=button],input[type=submit]{line-height:inherit}a.button,button,input[type=button],input[type=submit]{display:inline-block;padding:4px 12px;border:2px solid #0080ff;border-radius:4px;background-color:inherit;text-decoration:none;cursor:pointer;text-align:center;outline:0}a.button:hover,button:hover,input[type=button]:hover,input[type=submit]:hover{background-color:#eee;border-color:#0080ff}a.button.primary,button.primary,input[type=button].primary,input[type=submit].primary{background-color:#0069d1;border-color:#0069d1;color:#fff}a.button.primary:hover,button.primary:hover,input[type=button].primary:hover,input[type=submit].primary:hover{background-color:#0080ff;border-color:#0080ff}a.button.call-to-action,button.call-to-action,input[type=button].call-to-action,input[type=submit].call-to-action{font-size:20px;font-size:1.25rem;line-height:1.2;padding:12px 24px}a.button:focus,button:focus,input[type=button]:focus,input[type=submit]:focus{border-color:#ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}[class*=background-color-index-] a.button:hover,[class*=background-color-index-] button:hover,[class*=background-color-index-] input[type=button]:hover,[class*=background-color-index-] input[type=submit]:hover{background-color:#0080ff;border-color:#0080ff;text-decoration:none}select{border-color:#ccc;padding-right:24px;-webkit-appearance:none;-moz-appearance:none;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAAXNSR0IArs4c6QAAALNJREFUKBVjYBj6gHH69Olb////L8rIyJiemZl5HpuXgGoMgWpmAtW8ZgIyuIEMU6DCk0CJioaGBiaYJhAbJAaSA6kBqwUKcoiJiXUBBXKAEoxAwcM/f/6MA2liZ2dfBBS3BTKBwv+nvHr1qowRJAECU6dOdQNKzgdiKaDkNyANEuYCsp8BcWJ2dvYukADcepDAjx8/dIFia4CKuUCKQWyQGEwxkI8dTJs2rRLqduwKaCoKAOClUKEWEZS1AAAAAElFTkSuQmCC)center right 6px no-repeat;cursor:pointer}select:hover{background-color:#eee}select::-moz-focus-inner{border:none}select.plain{border:none}input[type=range]{-webkit-appearance:none;border-color:transparent;padding:0}input[type=range]:focus{outline:0}input[type=range]::-moz-focus-inner{border:none}input[type=range]::-webkit-slider-runnable-track{width:100%;height:6px;cursor:pointer;background:0 0;border:1px solid #ccc;border-radius:4px}input[type=range]::-webkit-slider-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#0080ff;cursor:pointer;-webkit-appearance:none;margin-top:-10px}input[type=range]::-moz-range-track{width:100%;height:6px;cursor:pointer;background:0 0;border:1px solid #ccc;border-radius:4px}input[type=range]::-moz-range-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#0080ff;cursor:pointer}input[type=range]::-ms-track{width:100%;height:6px;cursor:pointer;border:1px solid transparent;border-radius:4px;background:0 0;border-width:16px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#2a6495;border-radius:4px}input[type=range]::-ms-fill-upper{background:#3071a9;border-radius:4px}input[type=range]::-ms-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#0080ff;cursor:pointer}body,html{height:100%;width:100%;overflow:hidden}.i-list-inline{margin:0;padding:0}.i-list-inline>li{display:inline-block}.i-list-inline--delimited>li+li:before{content:",\00A0"}.i-list-block{margin:0;padding:0}.i-list-block>li,.i-list-block__item{padding:24px}.i-list-block--tiny>.i-list-block__item,.i-list-block.i-list-block--tiny>li{padding:6px}.i-list-block--small>.i-list-block__item,.i-list-block.i-list-block--small>li{padding:12px}.i-list-ui,.i-list-ui>li,.i-list-ui__item{border:0 solid #ccc}.i-list-ui{margin:0;padding:0;border-top-width:1px}.i-list-ui>li,.i-list-ui__item{padding:24px;border-bottom-width:1px}.i-list-bare{margin:0;padding:0}.i-box{display:block;padding:24px}.i-box--small{padding:12px}.i-pack{width:100%;display:table;table-layout:fixed}.i-pack__item{display:table-cell}.i-layout{margin:0 0 0 -24px;padding:0}.i-layout__item{display:inline-block;padding-left:24px;vertical-align:top;width:100%}.i-layout--center{text-align:center}.i-layout--center>.i-layout__item{text-align:left}.i-table{width:100%}.i-table--cosy td,.i-table--cosy th{padding:12px}.app--centered .document,.app--centered .section,.app--centered>.footer,.app--centered>div>.footer{padding-left:24px;padding-right:24px}#loading{width:100%;height:100%;background-color:#ddd;text-align:center;padding-top:100px;font-size:48px;color:#ccc}.app{top:0;left:0;right:0;overflow:auto}.app--inline{position:relative}.app--centered>.header .header__content,.app--centered>div>.header .header__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered>.footer .footer__content,.app--centered>div>.footer .footer__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered .document__content,.app--centered .section__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered .section .document{padding-left:0;padding-right:0}.app--centered .section .document__content{width:auto;max-width:none}.chart{display:block}.chart__grid{stroke:#ccc}.chart__lines-line{stroke-width:3px}.chart__lines-line.color-index-accent-1,.chart__lines-line.color-index-accent-8{stroke:#ff9e2c}.chart__lines-line.color-index-accent-2,.chart__lines-line.color-index-accent-9{stroke:#00cee4}.chart__lines-line.color-index-accent-10,.chart__lines-line.color-index-accent-3{stroke:#5b3eff}.chart__lines-line.color-index-accent-11,.chart__lines-line.color-index-accent-4{stroke:#c93}.chart__lines-line.color-index-accent-12,.chart__lines-line.color-index-accent-5{stroke:#d55af2}.chart__lines-line.color-index-accent-13,.chart__lines-line.color-index-accent-6{stroke:#79a2bc}.chart__lines-line.color-index-accent-14,.chart__lines-line.color-index-accent-7{stroke:#877b75}.chart__lines-area.color-index-accent-1,.chart__lines-area.color-index-accent-8{fill:rgba(255,158,44,.5)}.chart__lines-area.color-index-accent-2,.chart__lines-area.color-index-accent-9{fill:rgba(0,206,228,.5)}.chart__lines-area.color-index-accent-10,.chart__lines-area.color-index-accent-3{fill:rgba(91,62,255,.5)}.chart__lines-area.color-index-accent-11,.chart__lines-area.color-index-accent-4{fill:rgba(204,153,51,.5)}.chart__lines-area.color-index-accent-12,.chart__lines-area.color-index-accent-5{fill:rgba(213,90,242,.5)}.chart__lines-area.color-index-accent-13,.chart__lines-area.color-index-accent-6{fill:rgba(121,162,188,.5)}.chart__lines-area.color-index-accent-14,.chart__lines-area.color-index-accent-7{fill:rgba(135,123,117,.5)}.chart__threshold{stroke-width:2px;stroke:#333}.check-box__input{opacity:0;position:absolute}.check-box__input:checked+label.checkbox:after{content:"";position:absolute;top:10.5px;left:4px;width:16px;height:16px;background-color:#0080ff}.check-box__input:focus+label.checkbox:before{content:"";border-color:#ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}.layer__container,.login-form{box-shadow:0 2px 4px rgba(0,0,0,.3)}.check-box__label{position:relative;display:inline-block;cursor:pointer;-ms-user-select:none;user-select:none}.check-box__label,.radio-button__label{-webkit-user-select:none;-moz-user-select:none}.check-box__label:before{content:"";display:inline-block;width:24px;height:24px;margin-right:12px;vertical-align:middle;background-color:inherit;color:#0069d1;border:1px solid #ccc;border-radius:4px;text-align:center}.donut__key-item>*,.form-field__contents>textarea{vertical-align:top}.header-color-index-neutral-1 dt,.header-color-index-neutral-1 h1,.header-color-index-neutral-1 h2,.header-color-index-neutral-1 h3,.header-color-index-neutral-1 h4,.header-color-index-neutral-1 h5,.header-color-index-neutral-1 h6,.header-color-index-neutral-6 dt,.header-color-index-neutral-6 h1,.header-color-index-neutral-6 h2,.header-color-index-neutral-6 h3,.header-color-index-neutral-6 h4,.header-color-index-neutral-6 h5,.header-color-index-neutral-6 h6{color:#5b3eff}.background-color-index-neutral-1,.background-color-index-neutral-6{background-color:#5b3eff;color:#fff}.background-color-index-neutral-1 a,.background-color-index-neutral-6 a{color:#fff}.header-color-index-neutral-2 dt,.header-color-index-neutral-2 h1,.header-color-index-neutral-2 h2,.header-color-index-neutral-2 h3,.header-color-index-neutral-2 h4,.header-color-index-neutral-2 h5,.header-color-index-neutral-2 h6,.header-color-index-neutral-7 dt,.header-color-index-neutral-7 h1,.header-color-index-neutral-7 h2,.header-color-index-neutral-7 h3,.header-color-index-neutral-7 h4,.header-color-index-neutral-7 h5,.header-color-index-neutral-7 h6{color:#c93}.background-color-index-neutral-2,.background-color-index-neutral-7{background-color:#c93;color:#fff}.background-color-index-neutral-2 a,.background-color-index-neutral-7 a{color:#fff}.header-color-index-neutral-3 dt,.header-color-index-neutral-3 h1,.header-color-index-neutral-3 h2,.header-color-index-neutral-3 h3,.header-color-index-neutral-3 h4,.header-color-index-neutral-3 h5,.header-color-index-neutral-3 h6,.header-color-index-neutral-8 dt,.header-color-index-neutral-8 h1,.header-color-index-neutral-8 h2,.header-color-index-neutral-8 h3,.header-color-index-neutral-8 h4,.header-color-index-neutral-8 h5,.header-color-index-neutral-8 h6{color:#d55af2}.background-color-index-neutral-3,.background-color-index-neutral-8{background-color:#d55af2;color:#fff}.background-color-index-neutral-3 a,.background-color-index-neutral-8 a{color:#fff}.header-color-index-neutral-4 dt,.header-color-index-neutral-4 h1,.header-color-index-neutral-4 h2,.header-color-index-neutral-4 h3,.header-color-index-neutral-4 h4,.header-color-index-neutral-4 h5,.header-color-index-neutral-4 h6,.header-color-index-neutral-9 dt,.header-color-index-neutral-9 h1,.header-color-index-neutral-9 h2,.header-color-index-neutral-9 h3,.header-color-index-neutral-9 h4,.header-color-index-neutral-9 h5,.header-color-index-neutral-9 h6{color:#79a2bc}.background-color-index-neutral-4,.background-color-index-neutral-9{background-color:#79a2bc;color:#fff}.background-color-index-neutral-4 a,.background-color-index-neutral-9 a{color:#fff}.header-color-index-neutral-10 dt,.header-color-index-neutral-10 h1,.header-color-index-neutral-10 h2,.header-color-index-neutral-10 h3,.header-color-index-neutral-10 h4,.header-color-index-neutral-10 h5,.header-color-index-neutral-10 h6,.header-color-index-neutral-5 dt,.header-color-index-neutral-5 h1,.header-color-index-neutral-5 h2,.header-color-index-neutral-5 h3,.header-color-index-neutral-5 h4,.header-color-index-neutral-5 h5,.header-color-index-neutral-5 h6{color:#877b75}.background-color-index-neutral-10,.background-color-index-neutral-5{background-color:#877b75;color:#fff}.background-color-index-neutral-10 a,.background-color-index-neutral-5 a{color:#fff}.background-color-index-accent-1,.background-color-index-accent-3{background-color:#ff9e2c;color:#fff}.background-color-index-accent-1 a,.background-color-index-accent-3 a{color:#fff}.background-color-index-accent-2,.background-color-index-accent-4{background-color:#00cee4;color:#fff}.background-color-index-accent-2 a,.background-color-index-accent-4 a{color:#fff}.background-color-index-grey-1,.background-color-index-grey-5{background-color:#333;color:#fff}.background-color-index-grey-1 a,.background-color-index-grey-5 a{color:#fff}.background-color-index-grey-2,.background-color-index-grey-6{background-color:#3B3B3B;color:#fff}.background-color-index-grey-2 a,.background-color-index-grey-6 a{color:#fff}.background-color-index-grey-3,.background-color-index-grey-7{background-color:#434343;color:#fff}.background-color-index-grey-3 a,.background-color-index-grey-7 a{color:#fff}.background-color-index-grey-4,.background-color-index-grey-8{background-color:#666;color:#fff}.fixed-header,.header__wrapper{background-color:rgba(255,255,255,.9)}.background-color-index-grey-4 a,.background-color-index-grey-8 a{color:#fff}.center-column{padding-left:24px;padding-right:24px}.center-column .center-column__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.document{width:100%}.document--no-contents .document__content{padding-left:0}.document section{margin-top:24px;margin-bottom:24px;padding-top:24px}.document header>img,.document section>img{margin-top:48px;margin-bottom:48px;display:block;max-width:576px}.donut,.donut__key,.donut__key-item-value{display:inline-block}@media screen and (max-width:44.9375em){.document header>img,.document section>img{max-width:100%}.document header>ol,.document header>ul,.document section>ol,.document section>ul{padding-left:24px;padding-right:24px;margin-left:0;margin-bottom:24px}}.document header>dl>dt,.document section>dl>dt{margin-top:24px;margin-bottom:6px;text-transform:uppercase}.document header>dl>dt code,.document section>dl>dt code{text-transform:none;white-space:pre-wrap}.header__content,.index-header__count,.search__layer-header{white-space:nowrap}.document header>dl>dd,.document section>dl>dd{margin-left:0}.document header>h2,.document section>h2{position:relative;padding-top:24px}.document header>h2:after,.document section>h2:after{position:absolute;content:'';top:0;left:0;right:0;border-top:1px solid #ccc}.document section:first-child{margin-top:0;padding-top:0}.document section:first-child>h2{padding-top:0}.document section:first-child>h2:after{border-top:none}.object__attribute--array>.object__attribute-value>ol>li,.session__actions,.tile>.header .header__wrapper{border-top:1px solid #ccc}@-webkit-keyframes draw-stroke{0%{stroke-dashoffset:768px}100%{stroke-dashoffset:0}}@keyframes draw-stroke{0%{stroke-dashoffset:768px}100%{stroke-dashoffset:0}}.donut.series-pre path{stroke-dashoffset:768px}.donut__graphic-container{position:relative;width:192px;height:192px}.donut svg.donut__graphic{position:absolute;top:0;left:0;width:100%;height:100%;overflow:visible}.donut svg.donut__graphic path{stroke-width:24px;stroke-linecap:butt;stroke-dasharray:768px 768px;stroke-dashoffset:0;fill:none;cursor:pointer;-webkit-animation:draw-stroke 3s;animation:draw-stroke 3s}.donut svg.donut__graphic path.donut__slice--active{stroke-width:36px}.donut__slice--color-index-error{stroke:#dc442f}.donut__slice--color-index-warning{stroke:#f4b51e}.donut__slice--color-index-ok{stroke:#42a425}.donut__slice--color-index-disabled,.donut__slice--color-index-unknown{stroke:#848484}.donut__slice--color-index-1,.donut__slice--color-index-8{stroke:#ff9e2c}.donut__slice--color-index-2,.donut__slice--color-index-9{stroke:#00cee4}.donut__slice--color-index-10,.donut__slice--color-index-3{stroke:#5b3eff}.donut__slice--color-index-11,.donut__slice--color-index-4{stroke:#c93}.donut__slice--color-index-12,.donut__slice--color-index-5{stroke:#d55af2}.donut__slice--color-index-13,.donut__slice--color-index-6{stroke:#79a2bc}.donut__slice--color-index-14,.donut__slice--color-index-7{stroke:#877b75}.donut__active{position:absolute;width:100%;margin-top:72px;text-align:center;pointer-events:none}.donut__active-value{font-size:36px;font-size:2.25rem;line-height:38px;font-weight:700}.donut__active-units{font-size:24px;font-size:1.5rem;line-height:inherit;margin-left:6px;color:#999;font-weight:400}.donut__active-label{width:60%;margin:0 auto}.donut__key{margin-top:24px;text-align:left}.donut__key-item{color:#999}.donut__key-item svg.donut__key-item-swatch{width:12px;height:12px;margin-top:6px;margin-right:12px;overflow:visible}.donut__key-item svg.donut__key-item-swatch path{stroke-width:6px;transition-property:stroke-width;transition-duration:.3s;transition-timing-function:ease-in-out}.control-icon,.react-gravatar{transition:all .3s ease-in-out}.donut__key-item-label{display:inline-block;width:96px}.donut__key-item-value{width:48px;text-align:right}.donut__key-item--active{color:#333}.donut__key-item--active svg.donut__key-item-swatch path{stroke-width:12px}.fixed-header{position:fixed;z-index:1}.fixed-header__container{position:absolute;top:0;left:0;right:0}.footer{min-height:48px;line-height:48px}.footer__content{display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;width:100%}.footer__content.center-column__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}@media screen and (max-width:44.9375em){.document header>dl>dd,.document section>dl>dd{padding-right:24px}.fixed-header{position:relative}.fixed-header__container{position:static}.footer__content.center-column__content>.menu:first-child{width:100%}.footer__content.center-column__content>.menu:first-child:empty{width:0;margin:0;padding:0}}.footer__content>.flex-1{-webkit-flex:1;flex:1}.footer__content>.flex-2{-webkit-flex:2;flex:2}.footer__content>.flex-3{-webkit-flex:3;flex:3}.footer__content>.flex-4{-webkit-flex:4;flex:4}.footer__content>*{margin-right:48px}.footer__content>:last-child{margin-right:0}@media screen and (max-width:44.9375em){.footer__content>:last-child{text-align:left}}@media screen and (min-width:45em)and (max-width:63.9375em){.footer__content>:last-child{text-align:left}}.footer__content a.button,.footer__content button,.footer__content input[type=button],.footer__content input[type=submit]{font-size:24px;font-size:1.5rem;line-height:inherit;min-width:96px}.footer--primary{height:auto;padding:24px}.footer--primary .footer__content{position:relative;color:#999}.footer--primary .footer__content p{padding-top:12px;margin:0;max-width:none;text-align:right;line-height:24px}@media screen and (max-width:44.9375em){.footer--primary .footer__content{display:block}}@media screen and (min-width:45em)and (max-width:63.9375em){.footer--primary .footer__content{display:block}}.footer--centered .footer__content{display:block;text-align:center}.footer--centered .footer__content>*{margin-right:auto;margin-left:auto;text-align:center}.tile>.footer{border-bottom:1px solid #ccc}.form{min-width:480px}.form fieldset{border:none;margin:0;padding-bottom:1.5rem}.form .form-fields{padding:24px}.layer .form{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;max-height:100vh}.layer .form>.footer,.layer .form>.header{-webkit-flex:0 0 auto;flex:0 0 auto}.layer .form>.form-fields{overflow:auto}.form--compact{min-width:240px}.form-field{position:relative;margin-bottom:12px;line-height:36px}.form-field:last-child,.form-field__contents>table.table--selectable{margin-bottom:0}@media screen and (min-width:45em){.form:not(.form--compact) .form-field{display:-webkit-flex;display:flex;min-width:672px}}.form-field__label{display:block;text-align:left}@media screen and (min-width:45em){.form:not(.form--compact) .form-field__label{-webkit-flex:0 0 192px;flex:0 0 192px;text-align:right;padding-right:24px;vertical-align:top}.form:not(.form--compact) .form-field__container{-webkit-flex:1 0 384px;flex:1 0 384px}}.form-field__contents button{line-height:24px}.form-field__contents>input[type=email],.form-field__contents>input[type=password],.form-field__contents>input[type=range],.form-field__contents>input[type=text],.form-field__contents>select,.form-field__contents>textarea{width:240px}.form--compact .form-field__contents>input[type=email],.form--compact .form-field__contents>input[type=password],.form--compact .form-field__contents>input[type=range],.form--compact .form-field__contents>input[type=text],.form--compact .form-field__contents>select,.form--compact .form-field__contents>textarea{width:100%;margin-right:0}.control-icon,.header__content svg,.status-icon{vertical-align:middle}.form-field__contents>.check-box,.form-field__contents>.radio-button{display:block}.form-field__contents label.checkbox,.form-field__contents label.radio{margin-right:24px}.form-field__contents>table.table--selectable tbody tr td{padding-top:0;padding-bottom:0}.form-field--error input,.form-field--error select,.form-field--error textarea{border-color:#dc442f}.form-field__help{color:#999}.form-field__error{color:#dc442f}.form--compact .form-field__error{display:block;position:absolute;top:0;right:0}@media screen and (max-width:44.9375em){.header{height:48px}}@media screen and (min-width:45em){.header{height:72px}}.layer__container>.form>.header .header__wrapper{padding-left:24px;padding-right:24px}.header__content{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;width:100%}@media screen and (max-width:44.9375em){.header__wrapper{height:48px}.header__content{line-height:48px}}@media screen and (min-width:45em){.header__wrapper{height:72px}.header__content{line-height:72px}}.header__content>*{-webkit-flex:1 0;flex:1 0}.header__content>:last-child{-webkit-flex:0 0 auto;flex:0 0 auto;text-align:right}.header__content>:first-child{-webkit-flex:1 0;flex:1 0;text-align:left}.header__content .title,.header__content>h1,.header__content>h2,.header__content>h3,.header__content>h4{margin-bottom:0;line-height:inherit}.header__content .title svg,.header__content>h1 svg,.header__content>h2 svg,.header__content>h3 svg,.header__content>h4 svg{height:48px}.header__content a{color:inherit}.header--primary{padding:0}.index-header,.index__container{position:relative;padding-left:24px}.header--primary .header__wrapper{padding-left:24px;padding-right:24px;border-bottom:none}.header--primary .header__content{-webkit-justify-content:space-between;justify-content:space-between;white-space:nowrap}.header--primary .header__content>*{-webkit-flex:auto;flex:auto}.header--primary .header__content>:last-child{-webkit-flex:0 0 auto;flex:0 0 auto}@media screen and (min-width:45em){.header--large,.header--large .header__wrapper{height:96px}.header--large .header__content{line-height:96px}.header--small,.header--small .header__wrapper{height:48px}.header--small .header__content{line-height:48px}.header--small .header__content .title svg,.header--small .header__content>h1 svg,.header--small .header__content>h2 svg,.header--small .header__content>h3 svg,.header--small .header__content>h4 svg{height:24px}.header--primary,.header--primary .header__wrapper{height:96px;line-height:96px}.header--primary .header__content{line-height:96px}.header--primary .header__wrapper{position:fixed;top:0;left:0;right:0;z-index:3}}.control-badge,.control-badge:after{width:18px;height:18px;position:absolute}.tile>.header{height:48px}.tile>.header .header__wrapper{height:48px;border-bottom:none}.tile>.header .header__content{line-height:48px}.control-icon{display:inline-block;width:48px;height:48px;cursor:pointer;fill:#999;stroke:#999}.control-icon--active,.control-icon:hover{fill:#000;stroke:#000}.control-badge{top:0;right:0;border-radius:4px;background-color:#5b3eff;text-align:center;font-size:16px;font-size:1rem;line-height:18px}.control-badge:after{content:'';right:0;border-radius:4px;border:1px solid #fff}.status-icon{width:24px;height:24px}.status-icon .status-icon__base{fill:#848484}.status-icon-error .status-icon__base{fill:#dc442f}.status-icon-warning .status-icon__base{fill:#f4b51e}.status-icon-ok .status-icon__base{fill:#42a425}.status-icon-disabled .status-icon__base,.status-icon-unknown .status-icon__base{fill:#848484}.status-icon-label .status-icon__base{fill:#999}.status-icon__detail{fill:#fff}.status-icon--large{width:48px;height:48px}.status-icon--small{width:12px;height:12px}.status-icon--small .status-icon__detail{display:none}@-webkit-keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.icon-changing{width:24px;height:24px;-webkit-animation:rotate 1.5s linear infinite;animation:rotate 1.5s linear infinite}.icon-changing--small{width:12px;height:12px}.icon-spinning{width:24px;height:24px;-webkit-animation:rotate 4s steps(4,end)infinite;animation:rotate 4s steps(4,end)infinite}.icon-spinning--small{width:12px;height:12px}.index__container{padding-right:24px;padding-bottom:24px}.index__header{height:48px;line-height:48px}.index__items{padding-top:96px;width:100%}.index__more{padding-top:24px}.index__error{color:#dc442f}.index-header{font-size:30px;font-size:1.875rem;line-height:inherit;padding-right:24px;display:-webkit-flex;display:flex}.index-header__search{-webkit-flex:1;flex:1}.index-header__count{-webkit-flex:0 0 auto;flex:0 0 auto;min-width:192px;margin-left:24px;color:#999;text-align:left}.index-header__out-of{margin-left:12px;font-size:16px;font-size:1rem;line-height:1.5;display:none}.index-header__out-of--active{display:inline}.index-table{width:100%}.index-tiles .tile>.header svg{margin-right:12px}.index-tiles .tile>:not(.header){display:block}a.active>.label .label__icon.control-icon svg{fill:#000;stroke:#000}.layer{position:fixed;top:0;left:0;right:0;overflow:none;z-index:10}.layer__container{position:absolute;background-color:rgba(255,255,255,.95);overflow:none;border-radius:4px;max-height:100vh;max-width:100vw}.layer--align-center{background-image:radial-gradient(circle at top,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,128,255,.6))}.layer--align-center .layer__container{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.layer--align-left{background-image:radial-gradient(circle at left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,128,255,.6))}.layer--align-left .layer__container{left:0;-webkit-animation:slide-right .2s ease-in-out forwards;animation:slide-right .2s ease-in-out forwards}.layer--align-right{background-image:radial-gradient(circle at right,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,128,255,.6))}.layer--align-right .layer__container{right:0}.layer--align-top{background-image:radial-gradient(circle at top left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,128,255,.6))}.layer--align-top .layer__container{top:0;-webkit-animation:slide-down .2s ease-in-out forwards;animation:slide-down .2s ease-in-out forwards}.layer--align-bottom{background-image:radial-gradient(circle at bottom left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(0,128,255,.6))}@-webkit-keyframes slide-right{0%{left:-100vw}100%{left:0}}@keyframes slide-right{0%{left:-100vw}100%{left:0}}@-webkit-keyframes slide-down{0%{top:-100vh}100%{top:0}}@keyframes slide-down{0%{top:-100vh}100%{top:0}}@media screen and (min-width:45em){.label__icon{display:none}}.notifications__container,.panel{background-color:#fff;border-bottom:1px solid #ccc}.login{position:absolute;top:0;left:0;right:0;overflow:hidden;z-index:100}.login__background{position:absolute;max-width:none}.login__background--portrait{width:auto;height:100%}.login__background--landscape{height:auto;width:100%}.login__container{position:relative;width:384px;margin:96px auto;z-index:1;animation-name:fadein;animation-duration:.5s}.login-form,.login__container{-webkit-animation-duration:.5s;-webkit-animation-name:fadein}@media screen and (max-width:44.9375em){.label__text{display:none}.login__container{margin:48px 0;width:100%;border-radius:0}}.login__footer{position:absolute;left:0;right:0;bottom:6px;padding:6px 24px;background-color:rgba(255,255,255,.9);text-align:center}.login-form{width:384px;padding:24px 24px 48px;background-color:rgba(255,255,255,.95);border:1px solid #ccc;border-radius:4px;text-align:center;z-index:1;animation-name:fadein;animation-duration:.5s}@media screen and (max-width:44.9375em){.login-form{width:100%;border-radius:0}}.login-form__logo{display:inline-block;width:48px;height:48px;margin-bottom:24px}.login-form fieldset{text-align:left;border:none;margin-bottom:0}.login-form fieldset input,.login-form__error{margin-bottom:12px}.login-form fieldset>*{width:100%;display:block}.login-form__submit{margin-top:24px;width:100%;background-color:#0080ff;color:#fff;font-size:24px;font-size:1.5rem;line-height:inherit}.login-form__error{color:#dc442f;text-align:left}.menu--inline.menu--left,.menu__layer--align-right .menu__control,.menu__layer--left{text-align:right}.login-form__footer{margin-top:12px;display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;line-height:36px}.menu,.menu__layer{line-height:inherit}.menu{display:inline-block;font-size:20px;font-size:1.25rem}.menu__control--fixed-label .menu__control-icon,.menu__layer .menu__control-drop-icon{display:none}.menu a:not(.button){color:gray}.menu a:not(.button):hover{color:#333}.menu a:not(.button).active{color:#0069d1}.menu:focus{outline:0;margin:-1px;border:1px solid #ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}.menu__control{cursor:pointer}.menu__control-drop-icon{width:24px;height:24px;margin-top:-6px;margin-left:12px;stroke:#999}.menu--inline.menu--small .menu__control-icon svg,.menu--small .menu__control-icon svg,.menu__layer--small .menu__control-icon svg{width:18px;height:18px}@media screen and (max-width:44.9375em){.menu__control--labelled .menu__control-drop-icon,.menu__control--labelled .menu__control-label{display:none}}@media screen and (min-width:45em){.menu__control--labelled .menu__control-icon{display:none}}.menu__layer{position:fixed;z-index:5;font-size:24px;font-size:1.5rem;background-color:#fff;border:none;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,.3)}.menu__layer .menu__control-label{padding-left:24px}.menu__layer a{padding:12px 24px}.menu__layer a:hover{text-decoration:none;background-color:rgba(0,0,0,.1)}.menu--controlled{display:inline-block;cursor:pointer}.menu--inline.menu--left>*{margin-left:24px;margin-right:0}.menu--inline.menu--left>:first-child{margin-left:0}.menu--inline.menu--right>*{margin-left:0;margin-right:24px}.menu--inline.menu--right>:last-child{margin-right:0}@media screen and (max-width:44.9375em){.menu--inline.menu--down:empty{width:0;margin:0;padding:0}}[class*=background-color-index-] .menu--inline a,[class*=background-color-index-] .menu--inline a.active,[class*=background-color-index-] .menu--inline a:hover{color:inherit}[class*=background-color-index-] .menu--inline.menu--left a,[class*=background-color-index-] .menu--inline.menu--right a{text-decoration:none}[class*=background-color-index-] .menu--inline.menu--left a:hover:not(.active):not(.button),[class*=background-color-index-] .menu--inline.menu--right a:hover:not(.active):not(.button){text-decoration:underline}.tile>a,.title a:hover,[class*=background-color-index-] .menu--inline.menu--down a:hover{text-decoration:none}[class*=background-color-index-] .menu--inline.menu--down a{padding:12px;border:1px solid transparent}[class*=background-color-index-] .menu--inline.menu--down a:hover:not(.active){border-color:rgba(0,0,0,.2)}[class*=background-color-index-] .menu--inline.menu--down a.active{background-color:rgba(0,0,0,.2)}.menu--small{font-size:16px;font-size:1rem;line-height:1.5}.menu--small .menu__control-drop-icon{margin-left:6px}.menu--primary{display:block;padding:0 24px 24px;max-height:100vh;overflow:auto}.menu--inline.menu--left>*,.menu--inline.menu--right>*,.menu__layer--left>*,.menu__layer--right>*{display:inline-block}.menu--primary>.header:first-child{margin-left:-24px;margin-right:-24px;margin-bottom:24px}.menu--inline.menu--right,.menu__layer--right,.object,.object__attribute-name{text-align:left}.menu--inline.menu--small,.menu__layer--small{font-size:1em}.menu--inline.menu--small .menu__control-label,.menu__layer--small .menu__control-label{padding:12px}.menu--inline.menu--small a,.menu__layer--small a{padding:6px 12px}.menu--inline.menu--down>*,.menu--inline.menu--up>*,.menu__layer--down>*,.menu__layer--up>*{display:block}.meter,.meter__label,.object__attribute-name{display:inline-block}.menu--inline.menu--down h1,.menu--inline.menu--down h2,.menu--inline.menu--down h3,.menu--inline.menu--down h4,.menu--inline.menu--down h5,.menu--inline.menu--down h6,.menu--inline.menu--up h1,.menu--inline.menu--up h2,.menu--inline.menu--up h3,.menu--inline.menu--up h4,.menu--inline.menu--up h5,.menu--inline.menu--up h6,.menu__layer--down h1,.menu__layer--down h2,.menu__layer--down h3,.menu__layer--down h4,.menu__layer--down h5,.menu__layer--down h6,.menu__layer--up h1,.menu__layer--up h2,.menu__layer--up h3,.menu__layer--up h4,.menu__layer--up h5,.menu__layer--up h6{margin:24px 0 0;padding:12px 0;border-top:1px solid #ccc;min-width:192px}.menu--inline.menu--down h1:first-child,.menu--inline.menu--down h2:first-child,.menu--inline.menu--down h3:first-child,.menu--inline.menu--down h4:first-child,.menu--inline.menu--down h5:first-child,.menu--inline.menu--down h6:first-child,.menu--inline.menu--up h1:first-child,.menu--inline.menu--up h2:first-child,.menu--inline.menu--up h3:first-child,.menu--inline.menu--up h4:first-child,.menu--inline.menu--up h5:first-child,.menu--inline.menu--up h6:first-child,.menu__layer--down h1:first-child,.menu__layer--down h2:first-child,.menu__layer--down h3:first-child,.menu__layer--down h4:first-child,.menu__layer--down h5:first-child,.menu__layer--down h6:first-child,.menu__layer--up h1:first-child,.menu__layer--up h2:first-child,.menu__layer--up h3:first-child,.menu__layer--up h4:first-child,.menu__layer--up h5:first-child,.menu__layer--up h6:first-child{margin-top:0}@-webkit-keyframes draw-meter{0%{stroke-dashoffset:192px}100%{stroke-dashoffset:0}}@keyframes draw-meter{0%{stroke-dashoffset:192px}100%{stroke-dashoffset:0}}.meter__graphic{width:192px;height:24px;background-color:#eee}.notifications-control__icon,.notifications__icon{vertical-align:middle;width:48px;height:48px}.meter__value{stroke:#0080ff;stroke-width:18px;stroke-dasharray:192px 192px;stroke-dashoffset:0;-webkit-animation:draw-meter 1.5s;animation:draw-meter 1.5s}.meter__threshold{stroke:#333;stroke-width:1px}.meter__label{vertical-align:top;margin-left:12px}.meter__label-units{color:#999;margin-left:.5em}.notifications{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0,128,255,.6);z-index:10}.notifications__container{position:absolute;top:0;right:0;min-width:300px;padding:96px 24px 24px;border-left:1px solid #ccc;border-bottom-left-radius:4px}.notifications__icon{position:absolute;top:24px;right:84px}.object li{width:auto}.object__attribute-name{vertical-align:top;width:192px;color:#999}.object__attribute-value{display:inline-block;vertical-align:top;margin-left:24px;text-align:left;max-width:384px}.section--centered,.settings{text-align:center}.object__attribute-value ul{padding-top:24px}.object__attribute--container>.object__attribute-name{font-weight:700}.object__attribute--unset .object__attribute-value{font-style:italic;color:#999}.object__attribute--array>.object__attribute-value>ol{position:relative}.object__attribute--array>.object__attribute-value>ol>li:first-child{border:none}.object__attribute--array>.object__attribute-value>ol>li>ul{padding-top:0}.panel{padding:24px}.panel:last-of-type{border-bottom:none}.panel__title{text-transform:uppercase;font-weight:400}.panel>a{display:block}.panel a.call-to-action,.radio-button__label,.radio-button__label:before,.search,.search__layer-contents{display:inline-block}.panel a.call-to-action{font-size:20px;font-size:1.25rem;line-height:1.2;margin-bottom:24px;text-decoration:none;padding:12px 24px;border-radius:4px;color:#fff}.panel--index-1 .panel__title{color:#5b3eff}.panel--index-1 a.call-to-action{background-color:#5b3eff}.panel--index-2 .panel__title{color:#c93}.panel--index-2 a.call-to-action{background-color:#c93}@media screen and (max-width:44.9375em){.panel{padding:24px}.panel>h2{margin-bottom:12px}}.radio-button__input{opacity:0;position:absolute}.radio-button__input:checked+label.radio:after{content:"";position:absolute;top:10.5px;left:4px;width:16px;height:16px;background-color:#0080ff;border-radius:16px}.radio-button__input:focus+label.checkbox:before{content:"";border-color:#ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}.radio-button__label{position:relative;cursor:pointer;-ms-user-select:none;user-select:none}.radio-button__label:before{content:"";width:24px;height:24px;margin-right:12px;vertical-align:middle;background-color:inherit;color:#0069d1;border:1px solid #ccc;border-radius:24px;text-align:center}.search:focus{outline:0;margin:-1px;border:1px solid #ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}.search--controlled,.search__control{cursor:pointer}.search__input{margin-right:0;padding:0 12px;font-size:inherit}.search__layer{position:fixed;z-index:2;font-size:20px;font-size:1.25rem;line-height:inherit;background-color:#fff;border:none;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,.3)}.search__layer--inline{margin-left:-1px}.search__layer input{margin-right:0;box-sizing:border-box}.search__layer .search__control{display:inline-block;vertical-align:top}.search__layer .search__suggestion{padding:6px 12px;cursor:pointer}.search__layer .search__suggestion:hover{background-color:rgba(0,0,0,.1)}.search--inline .search__input{width:100%;box-sizing:border-box;line-height:inherit}.section{padding-top:48px;padding-bottom:48px}.section--right .section__content{display:-webkit-flex;display:flex}.section--right .section__content.center-column__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}@media screen and (max-width:44.9375em){.section--right .section__content.center-column__content>.menu:first-child{width:100%}.section--right .section__content.center-column__content>.menu:first-child:empty{width:0;margin:0;padding:0}}.section--right .section__content>.flex-1{-webkit-flex:1;flex:1}.section--right .section__content>.flex-2{-webkit-flex:2;flex:2}.section--right .section__content>.flex-3{-webkit-flex:3;flex:3}.section--right .section__content>.flex-4{-webkit-flex:4;flex:4}@media screen and (min-width:45em){.section--right .section__content>*{margin-right:48px}.section--right .section__content>:last-child{margin-right:0}.section--right .section__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}}@media screen and (max-width:44.9375em){.section--right .section__content{-webkit-flex-direction:column;flex-direction:column}.section--right .section__content>*{margin-bottom:48px;padding-bottom:48px}.section--right .section__content>:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}}.section--compact{padding-top:0;padding-bottom:0}.section--compact .section__content{padding-top:12px;padding-bottom:12px}.section--centered .section__content>*{margin-left:auto;margin-right:auto}.react-gravatar{width:48px;height:48px;border-radius:24px;border:2px solid transparent;margin:0 24px;overflow:hidden;cursor:pointer}.react-gravatar:hover{border-color:#0080ff}.session{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(0,128,255,.6);z-index:10}.session__container{position:absolute;top:0;right:0;min-width:300px;padding:96px 24px 24px;background-color:#fff;border-left:1px solid #ccc;border-bottom:1px solid #ccc;border-bottom-left-radius:4px}.session .react-gravatar{position:absolute;top:24px;right:24px}.session__actions{margin-top:24px;padding-top:24px}.session a{cursor:pointer}.settings{position:relative}.settings__panels{display:inline-block}.settings__panel{vertical-align:top}.table{width:100%}.table th{font-weight:100;font-size:20px;font-size:1.25rem;border-bottom:1px solid #ccc}.table td,.table th{padding:6px 12px;line-height:36px;text-align:left}.table--selectable tbody tr{cursor:pointer}.table--selectable tbody tr.table__row--selected td{background-color:#fffffa}.table--selectable tbody tr:hover td{background-color:rgba(0,0,0,.1)}.tbd{text-align:center;padding:96px;font-size:96px;font-size:6rem;line-height:1;background-color:#ccc;color:#fff}.tile>a,.title a{color:inherit}.tile,.tile>a{padding:24px}.tiles{display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap;-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch;margin:-24px}.tiles>*{-webkit-flex:0 0 192px;flex:0 0 192px;flex-grow:1}.tiles--small>*{-webkit-flex-basis:96px;flex-basis:96px}@media screen and (max-width:44.9375em){.tile{margin:0;border-radius:none}}.tile>a{display:block;height:100%}.title{overflow:hidden;text-overflow:ellipsis;font-weight:400;margin-right:24px}[class*=background-color-index-] .title a:hover{text-decoration:underline}.title img,.title svg:not(.control-icon){margin-right:12px}@media screen and (max-width:44.9375em){.title{font-size:32px;font-size:2rem;line-height:inherit}.title img,.title svg:not(.control-icon){height:24px}}@media screen and (min-width:45em){.title{font-size:40px;font-size:2.5rem;line-height:inherit}.title img,.title svg:not(.control-icon){height:48px}}.title--menu .control-icon{margin-left:12px}.title--menu:hover{cursor:pointer}.title--menu:hover .control-icon{stroke:#0080ff}.clearfix:after,.i-box:after{content:"";display:table;clear:both} \ No newline at end of file + *//*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */dfn,img{font-style:italic}img,legend{border:0}a,ins,u{text-decoration:none}a,a:visited{color:#ff9e2c}code.hljs,input,select,textarea{border:1px solid #ccc}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,optgroup,strong{font-weight:700}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}#loading,.app{position:absolute}sup{top:-.5em}sub{bottom:-.25em}.app,.layer,.layer--align-bottom .layer__container,.login{bottom:0}img{max-width:100%;vertical-align:middle}svg:not(:root){overflow:hidden}hr{box-sizing:content-box;height:0}pre,textarea{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}#loading,.tbd{font-style:italic}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver}table{border-collapse:collapse;border-spacing:0}blockquote,body,caption,dd,dl,fieldset,figure,form,h1,h2,h3,h4,h5,h6,hr,legend,ol,p,pre,table,td,th,ul{margin:0;padding:0}abbr[title],dfn[title]{cursor:help}ins{border-bottom:1px solid}html{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;font-size:1em;line-height:1.5;background-color:#fff;color:#333;overflow-y:scroll;min-height:100%;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;font-family:'Source Sans Pro',Arial,sans-serif}*,:after,:before{-webkit-box-sizing:inherit;-moz-box-sizing:inherit;box-sizing:inherit}address,blockquote,dl,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,ol,p,pre,table,ul{margin-bottom:1.5rem}dd,ol,ul{margin-left:3rem}h6{font-size:14px;font-size:.875rem;line-height:1.71429}li>ol,li>ul{margin-bottom:0}.gm-style img,img[height],img[width]{max-width:none}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:300;src:local('Source Sans Pro Light'),local('SourceSansPro-Light'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/toadOcfmlt9b38dHJxOBGPS42wKzre0cxmO5m5GyTsY.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:400;src:local('Source Sans Pro'),local('SourceSansPro-Regular'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/ODelI1aHBYDBqgeIAH2zlEY6Fu39Tt9XkmtSosaMoEA.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:normal;font-weight:700;src:local('Source Sans Pro Bold'),local('SourceSansPro-Bold'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/toadOcfmlt9b38dHJxOBGLlcMrNrsnL9dgADnXgYJjs.ttf)format('truetype')}@font-face{font-family:'Source Sans Pro';font-style:italic;font-weight:400;src:local('Source Sans Pro Italic'),local('SourceSansPro-It'),url(http://fonts.gstatic.com/s/sourcesanspro/v9/M2Jd71oPJhLKp0zdtTvoMzpKUtbt71woJ25xl7KOGD0.ttf)format('truetype')}dd,h3,h4,h5,li,p{max-width:576px}.h1,h1{font-size:48px;font-size:3rem;line-height:1;font-weight:600}.h2,.h3,h2,h3{line-height:1.33333;font-size:36px}.h2,h2{font-size:2.25rem;font-weight:400}.h3,.h4,.h5,h3,h4,h5{font-weight:100}.h3,h3{font-size:2.25rem}.h4,h4{font-size:24px;font-size:1.5rem;line-height:1}.h5,h5{font-size:20px;font-size:1.25rem;line-height:1.2}a{background-color:transparent;cursor:pointer}a:hover{text-decoration:underline}a.active{color:#333}@-webkit-keyframes fadein{from{opacity:0}to{opacity:1}}@keyframes fadein{from{opacity:0}to{opacity:1}}input,select,textarea{font-size:16px;font-size:1rem;line-height:1.5;padding:5px 12px;border-radius:4px;outline:0;margin-right:12px;background-color:inherit}input:focus,select:focus,textarea:focus{border-color:#ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}input::-moz-focus-inner,select::-moz-focus-inner,textarea::-moz-focus-inner{border:none;outline:0}input.error,select.error,textarea.error{border-color:#dc442f}input[type=button],input[type=submit]{line-height:inherit}a.button,button,input[type=button],input[type=submit]{display:inline-block;padding:4px 12px;border:2px solid #0080ff;border-radius:4px;background-color:inherit;text-decoration:none;cursor:pointer;text-align:center;outline:0}a.button:hover,button:hover,input[type=button]:hover,input[type=submit]:hover{background-color:#eee;border-color:#0080ff}a.button.primary,button.primary,input[type=button].primary,input[type=submit].primary{background-color:#0069d1;border-color:#0069d1;color:#fff}a.button.primary:hover,button.primary:hover,input[type=button].primary:hover,input[type=submit].primary:hover{background-color:#0080ff;border-color:#0080ff}a.button.call-to-action,button.call-to-action,input[type=button].call-to-action,input[type=submit].call-to-action{font-size:20px;font-size:1.25rem;line-height:1.2;padding:12px 24px}a.button:focus,button:focus,input[type=button]:focus,input[type=submit]:focus{border-color:#ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}[class*=background-color-index-] a.button:hover,[class*=background-color-index-] button:hover,[class*=background-color-index-] input[type=button]:hover,[class*=background-color-index-] input[type=submit]:hover{background-color:#0080ff;border-color:#0080ff;text-decoration:none}select{border-color:#ccc;padding-right:24px;-webkit-appearance:none;-moz-appearance:none;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAAAXNSR0IArs4c6QAAALNJREFUKBVjYBj6gHH69Olb////L8rIyJiemZl5HpuXgGoMgWpmAtW8ZgIyuIEMU6DCk0CJioaGBiaYJhAbJAaSA6kBqwUKcoiJiXUBBXKAEoxAwcM/f/6MA2liZ2dfBBS3BTKBwv+nvHr1qowRJAECU6dOdQNKzgdiKaDkNyANEuYCsp8BcWJ2dvYukADcepDAjx8/dIFia4CKuUCKQWyQGEwxkI8dTJs2rRLqduwKaCoKAOClUKEWEZS1AAAAAElFTkSuQmCC)center right 6px no-repeat;cursor:pointer}select:hover{background-color:#eee}select::-moz-focus-inner{border:none}select.plain{border:none}input[type=range]{-webkit-appearance:none;border-color:transparent;padding:0}input[type=range]:focus{outline:0}input[type=range]::-moz-focus-inner{border:none}input[type=range]::-webkit-slider-runnable-track{width:100%;height:6px;cursor:pointer;background:0 0;border:1px solid #ccc;border-radius:4px}input[type=range]::-webkit-slider-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#0080ff;cursor:pointer;-webkit-appearance:none;margin-top:-10px}input[type=range]::-moz-range-track{width:100%;height:6px;cursor:pointer;background:0 0;border:1px solid #ccc;border-radius:4px}input[type=range]::-moz-range-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#0080ff;cursor:pointer}input[type=range]::-ms-track{width:100%;height:6px;cursor:pointer;border:1px solid transparent;border-radius:4px;background:0 0;border-width:16px 0;color:transparent}input[type=range]::-ms-fill-lower{background:#2a6495;border-radius:4px}input[type=range]::-ms-fill-upper{background:#3071a9;border-radius:4px}input[type=range]::-ms-thumb{border:none;height:24px;width:24px;border-radius:24px;background:#0080ff;cursor:pointer}body,html{height:100%;width:100%;overflow:hidden}.i-list-bare{margin:0;padding:0;list-style:none}.app--centered .document,.app--centered .section,.app--centered>.footer,.app--centered>div>.footer{padding-left:24px;padding-right:24px}#loading{width:100%;height:100%;background-color:#ddd;text-align:center;padding-top:100px;font-size:48px;color:#ccc}.app{top:0;left:0;right:0;overflow:auto}.app--inline{position:relative}.app--centered>.header .header__content,.app--centered>div>.header .header__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered>.footer .footer__content,.app--centered>div>.footer .footer__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered .document__content,.app--centered .section__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}.app--centered .section .document{padding-left:0;padding-right:0}.app--centered .section .document__content{width:auto;max-width:none}.chart{display:block;text-align:right}.chart__grid{stroke:#ccc}.chart__graphic{width:100%}.chart__values-line{stroke-width:3px}.chart__values-line.color-index-error{stroke:#dc442f}.chart__values-line.color-index-warning{stroke:#f4b51e}.chart__values-line.color-index-ok{stroke:#42a425}.chart__values-line.color-index-disabled,.chart__values-line.color-index-unknown{stroke:#848484}.chart__values-line.color-index-graph-1,.chart__values-line.color-index-graph-8{stroke:#ff9e2c}.chart__values-line.color-index-graph-2,.chart__values-line.color-index-graph-9{stroke:#00cee4}.chart__values-line.color-index-graph-10,.chart__values-line.color-index-graph-3{stroke:#5b3eff}.chart__values-line.color-index-graph-11,.chart__values-line.color-index-graph-4{stroke:#c93}.chart__values-line.color-index-graph-12,.chart__values-line.color-index-graph-5{stroke:#d55af2}.chart__values-line.color-index-graph-13,.chart__values-line.color-index-graph-6{stroke:#79a2bc}.chart__values-line.color-index-graph-14,.chart__values-line.color-index-graph-7{stroke:#877b75}.chart__values-area.color-index-error{fill:rgba(220,68,47,.7)}.chart__values-area.color-index-warning{fill:rgba(244,181,30,.7)}.chart__values-area.color-index-ok{fill:rgba(66,164,37,.7)}.chart__values-area.color-index-disabled,.chart__values-area.color-index-unknown{fill:rgba(132,132,132,.7)}.chart__values-area.color-index-graph-1,.chart__values-area.color-index-graph-8{fill:rgba(255,158,44,.7)}.chart__values-area.color-index-graph-2,.chart__values-area.color-index-graph-9{fill:rgba(0,206,228,.7)}.chart__values-area.color-index-graph-10,.chart__values-area.color-index-graph-3{fill:rgba(91,62,255,.7)}.chart__values-area.color-index-graph-11,.chart__values-area.color-index-graph-4{fill:rgba(204,153,51,.7)}.chart__values-area.color-index-graph-12,.chart__values-area.color-index-graph-5{fill:rgba(213,90,242,.7)}.chart__values-area.color-index-graph-13,.chart__values-area.color-index-graph-6{fill:rgba(121,162,188,.7)}.chart__values-area.color-index-graph-14,.chart__values-area.color-index-graph-7{fill:rgba(135,123,117,.7)}.chart__values-bar.color-index-error{fill:rgba(220,68,47,.7)}.chart__values-bar.color-index-warning{fill:rgba(244,181,30,.7)}.chart__values-bar.color-index-ok{fill:rgba(66,164,37,.7)}.chart__values-bar.color-index-disabled,.chart__values-bar.color-index-unknown{fill:rgba(132,132,132,.7)}.chart__values-bar.color-index-graph-1,.chart__values-bar.color-index-graph-8{fill:rgba(255,158,44,.7)}.chart__values-bar.color-index-graph-2,.chart__values-bar.color-index-graph-9{fill:rgba(0,206,228,.7)}.chart__values-bar.color-index-graph-10,.chart__values-bar.color-index-graph-3{fill:rgba(91,62,255,.7)}.chart__values-bar.color-index-graph-11,.chart__values-bar.color-index-graph-4{fill:rgba(204,153,51,.7)}.chart__values-bar.color-index-graph-12,.chart__values-bar.color-index-graph-5{fill:rgba(213,90,242,.7)}.chart__values-bar.color-index-graph-13,.chart__values-bar.color-index-graph-6{fill:rgba(121,162,188,.7)}.chart__values-bar.color-index-graph-14,.chart__values-bar.color-index-graph-7{fill:rgba(135,123,117,.7)}.chart__values-bar--active.color-index-error{fill:#dc442f}.chart__values-bar--active.color-index-warning{fill:#f4b51e}.chart__values-bar--active.color-index-ok{fill:#42a425}.chart__values-bar--active.color-index-disabled,.chart__values-bar--active.color-index-unknown{fill:#848484}.chart__values-bar--active.color-index-graph-1,.chart__values-bar--active.color-index-graph-8{fill:#ff9e2c}.chart__values-bar--active.color-index-graph-2,.chart__values-bar--active.color-index-graph-9{fill:#00cee4}.chart__values-bar--active.color-index-graph-10,.chart__values-bar--active.color-index-graph-3{fill:#5b3eff}.chart__values-bar--active.color-index-graph-11,.chart__values-bar--active.color-index-graph-4{fill:#c93}.chart__values-bar--active.color-index-graph-12,.chart__values-bar--active.color-index-graph-5{fill:#d55af2}.chart__values-bar--active.color-index-graph-13,.chart__values-bar--active.color-index-graph-6{fill:#79a2bc}.chart__values-bar--active.color-index-graph-14,.chart__values-bar--active.color-index-graph-7{fill:#877b75}.chart__threshold{stroke-width:2px;stroke:#333}.chart__legend{margin:24px 0 0;display:inline-block;text-align:left;list-style-type:none}.chart__legend-label{text-align:right;font-size:20px;font-size:1.25rem;line-height:1.2;margin-bottom:12px}.chart__legend-item,.chart__legend-total{white-space:nowrap}.chart__legend-item>*,.chart__legend-total>*{vertical-align:top}.chart__legend-item-label,.chart__legend-total-label{display:inline-block;width:96px;color:#999}.chart__legend-item-value,.chart__legend-total-value{display:inline-block;width:48px;text-align:right}.chart__legend-item-units,.chart__legend-total-units{margin-left:6px}.chart__legend-item svg.chart__legend-item-swatch{width:12px;height:12px;margin-top:6px;margin-right:12px;overflow:visible}.chart__legend-item svg.chart__legend-item-swatch.color-index-error{stroke:#dc442f}.chart__legend-item svg.chart__legend-item-swatch.color-index-warning{stroke:#f4b51e}.chart__legend-item svg.chart__legend-item-swatch.color-index-ok{stroke:#42a425}.chart__legend-item svg.chart__legend-item-swatch.color-index-disabled,.chart__legend-item svg.chart__legend-item-swatch.color-index-unknown{stroke:#848484}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-1,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-8{stroke:#ff9e2c}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-2,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-9{stroke:#00cee4}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-10,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-3{stroke:#5b3eff}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-11,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-4{stroke:#c93}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-12,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-5{stroke:#d55af2}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-13,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-6{stroke:#79a2bc}.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-14,.chart__legend-item svg.chart__legend-item-swatch.color-index-graph-7{stroke:#877b75}.chart__legend-item svg.chart__legend-item-swatch path{stroke-width:12px;transition-property:stroke-width;transition-duration:.3s;transition-timing-function:ease-in-out}.chart__legend-total{margin-top:6px;border-top:1px dotted #ccc;padding-top:6px;margin-left:24px;color:#999}.check-box__input{opacity:0;position:absolute}.check-box__input:checked+label.checkbox:after{content:"";position:absolute;top:10.5px;left:4px;width:16px;height:16px;background-color:#0080ff}.check-box__input:focus+label.checkbox:before{content:"";border-color:#ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}.layer__container,.login-form{box-shadow:0 2px 4px rgba(0,0,0,.3)}.check-box__label{position:relative;display:inline-block;cursor:pointer;-ms-user-select:none;user-select:none}.check-box__label,.radio-button__label{-webkit-user-select:none;-moz-user-select:none}.check-box__label:before{content:"";display:inline-block;width:24px;height:24px;margin-right:12px;vertical-align:middle;background-color:inherit;color:#0069d1;border:1px solid #ccc;border-radius:4px;text-align:center}.header-color-index-neutral-1 dt,.header-color-index-neutral-1 h1,.header-color-index-neutral-1 h2,.header-color-index-neutral-1 h3,.header-color-index-neutral-1 h4,.header-color-index-neutral-1 h5,.header-color-index-neutral-1 h6,.header-color-index-neutral-6 dt,.header-color-index-neutral-6 h1,.header-color-index-neutral-6 h2,.header-color-index-neutral-6 h3,.header-color-index-neutral-6 h4,.header-color-index-neutral-6 h5,.header-color-index-neutral-6 h6{color:#5b3eff}.background-color-index-neutral-1,.background-color-index-neutral-6{background-color:#5b3eff;color:#fff}.background-color-index-neutral-1 a,.background-color-index-neutral-6 a{color:#fff}.header-color-index-neutral-2 dt,.header-color-index-neutral-2 h1,.header-color-index-neutral-2 h2,.header-color-index-neutral-2 h3,.header-color-index-neutral-2 h4,.header-color-index-neutral-2 h5,.header-color-index-neutral-2 h6,.header-color-index-neutral-7 dt,.header-color-index-neutral-7 h1,.header-color-index-neutral-7 h2,.header-color-index-neutral-7 h3,.header-color-index-neutral-7 h4,.header-color-index-neutral-7 h5,.header-color-index-neutral-7 h6{color:#c93}.background-color-index-neutral-2,.background-color-index-neutral-7{background-color:#c93;color:#fff}.background-color-index-neutral-2 a,.background-color-index-neutral-7 a{color:#fff}.header-color-index-neutral-3 dt,.header-color-index-neutral-3 h1,.header-color-index-neutral-3 h2,.header-color-index-neutral-3 h3,.header-color-index-neutral-3 h4,.header-color-index-neutral-3 h5,.header-color-index-neutral-3 h6,.header-color-index-neutral-8 dt,.header-color-index-neutral-8 h1,.header-color-index-neutral-8 h2,.header-color-index-neutral-8 h3,.header-color-index-neutral-8 h4,.header-color-index-neutral-8 h5,.header-color-index-neutral-8 h6{color:#d55af2}.background-color-index-neutral-3,.background-color-index-neutral-8{background-color:#d55af2;color:#fff}.background-color-index-neutral-3 a,.background-color-index-neutral-8 a{color:#fff}.header-color-index-neutral-4 dt,.header-color-index-neutral-4 h1,.header-color-index-neutral-4 h2,.header-color-index-neutral-4 h3,.header-color-index-neutral-4 h4,.header-color-index-neutral-4 h5,.header-color-index-neutral-4 h6,.header-color-index-neutral-9 dt,.header-color-index-neutral-9 h1,.header-color-index-neutral-9 h2,.header-color-index-neutral-9 h3,.header-color-index-neutral-9 h4,.header-color-index-neutral-9 h5,.header-color-index-neutral-9 h6{color:#79a2bc}.background-color-index-neutral-4,.background-color-index-neutral-9{background-color:#79a2bc;color:#fff}.background-color-index-neutral-4 a,.background-color-index-neutral-9 a{color:#fff}.header-color-index-neutral-10 dt,.header-color-index-neutral-10 h1,.header-color-index-neutral-10 h2,.header-color-index-neutral-10 h3,.header-color-index-neutral-10 h4,.header-color-index-neutral-10 h5,.header-color-index-neutral-10 h6,.header-color-index-neutral-5 dt,.header-color-index-neutral-5 h1,.header-color-index-neutral-5 h2,.header-color-index-neutral-5 h3,.header-color-index-neutral-5 h4,.header-color-index-neutral-5 h5,.header-color-index-neutral-5 h6{color:#877b75}.background-color-index-neutral-10,.background-color-index-neutral-5{background-color:#877b75;color:#fff}.background-color-index-neutral-10 a,.background-color-index-neutral-5 a{color:#fff}.background-color-index-accent-1,.background-color-index-accent-3{background-color:#ff9e2c;color:#fff}.background-color-index-accent-1 a,.background-color-index-accent-3 a{color:#fff}.background-color-index-accent-2,.background-color-index-accent-4{background-color:#00cee4;color:#fff}.background-color-index-accent-2 a,.background-color-index-accent-4 a{color:#fff}.background-color-index-grey-1,.background-color-index-grey-5{background-color:#333;color:#fff}.background-color-index-grey-1 a,.background-color-index-grey-5 a{color:#fff}.background-color-index-grey-2,.background-color-index-grey-6{background-color:#3B3B3B;color:#fff}.background-color-index-grey-2 a,.background-color-index-grey-6 a{color:#fff}.background-color-index-grey-3,.background-color-index-grey-7{background-color:#434343;color:#fff}.background-color-index-grey-3 a,.background-color-index-grey-7 a{color:#fff}.background-color-index-grey-4,.background-color-index-grey-8{background-color:#666;color:#fff}.fixed-header,.header__wrapper{background-color:rgba(255,255,255,.9)}.background-color-index-grey-4 a,.background-color-index-grey-8 a{color:#fff}.center-column{padding-left:24px;padding-right:24px}.center-column .center-column__content{width:100%;max-width:960px;margin-left:auto;margin-right:auto}@media screen and (min-width:45em){.dashboard{height:calc(100vh - 96px)}}.document{width:100%}.document--no-contents .document__content{padding-left:0}.document section{margin-top:24px;margin-bottom:24px;padding-top:24px}.document header>img,.document section>img{margin-top:48px;margin-bottom:48px;display:block;max-width:576px}@media screen and (max-width:44.9375em){.dashboard{height:calc(100vh - 48px)}.document header>img,.document section>img{max-width:100%}.document header>ol,.document header>ul,.document section>ol,.document section>ul{padding-left:24px;padding-right:24px;margin-left:0;margin-bottom:24px}}.document header>dl>dt,.document section>dl>dt{margin-top:24px;margin-bottom:6px;text-transform:uppercase}.document header>dl>dt code,.document section>dl>dt code{text-transform:none;white-space:pre-wrap}.document header>dl>dd,.document section>dl>dd{margin-left:0}.document header>h2,.document section>h2{position:relative;padding-top:24px}.document header>h2:after,.document section>h2:after{position:absolute;content:'';top:0;left:0;right:0;border-top:1px solid #ccc}.document section:first-child{margin-top:0;padding-top:0}.document section:first-child>h2{padding-top:0}.document section:first-child>h2:after{border-top:none}@-webkit-keyframes draw-stroke{0%{stroke-dashoffset:768px}100%{stroke-dashoffset:0}}@keyframes draw-stroke{0%{stroke-dashoffset:768px}100%{stroke-dashoffset:0}}.donut.series-pre path{stroke-dashoffset:768px}.donut__graphic-container{position:relative;width:192px;height:192px}.donut svg.donut__graphic{position:absolute;top:0;left:0;width:100%;height:100%;overflow:visible}.donut svg.donut__graphic path{stroke-width:24px;stroke-linecap:butt;stroke-dasharray:768px 768px;stroke-dashoffset:0;fill:none;cursor:pointer;-webkit-animation:draw-stroke 3s;animation:draw-stroke 3s}.donut svg.donut__graphic path.donut__slice--active{stroke-width:36px}.donut__slice.color-index-error{stroke:#dc442f}.donut__slice.color-index-warning{stroke:#f4b51e}.donut__slice.color-index-ok{stroke:#42a425}.donut__slice.color-index-disabled,.donut__slice.color-index-unknown{stroke:#848484}.donut__slice.color-index-graph-1,.donut__slice.color-index-graph-8{stroke:#ff9e2c}.donut__slice.color-index-graph-2,.donut__slice.color-index-graph-9{stroke:#00cee4}.donut__slice.color-index-graph-10,.donut__slice.color-index-graph-3{stroke:#5b3eff}.donut__slice.color-index-graph-11,.donut__slice.color-index-graph-4{stroke:#c93}.donut__slice.color-index-graph-12,.donut__slice.color-index-graph-5{stroke:#d55af2}.donut__slice.color-index-graph-13,.donut__slice.color-index-graph-6{stroke:#79a2bc}.donut__slice.color-index-graph-14,.donut__slice.color-index-graph-7{stroke:#877b75}.donut__active{position:absolute;width:100%;margin-top:60px;text-align:center;white-space:normal;pointer-events:none}.donut__active-value{font-size:36px;font-size:2.25rem;line-height:38px;font-weight:700}.donut__active-units{font-size:24px;font-size:1.5rem;line-height:inherit;margin-left:6px;color:#999;font-weight:400}.donut__active-label{width:60%;margin:0 auto}.donut__legend{text-align:left;list-style-type:none;white-space:normal}.donut--landscape,.header__content,.index-header__count,.search__layer-header{white-space:nowrap}.donut__legend-item,.donut__legend-total{color:#999}.donut__legend-item>*,.donut__legend-total>*{vertical-align:top}.donut__legend-item-label,.donut__legend-total-label{display:inline-block;width:96px}.donut__legend-item-value,.donut__legend-total-value{display:inline-block;width:48px;text-align:right}.donut__legend-item svg.donut__legend-item-swatch{width:12px;height:12px;margin-top:6px;margin-right:12px;overflow:visible}.donut__legend-item svg.donut__legend-item-swatch.color-index-error{stroke:#dc442f}.donut__legend-item svg.donut__legend-item-swatch.color-index-warning{stroke:#f4b51e}.donut__legend-item svg.donut__legend-item-swatch.color-index-ok{stroke:#42a425}.donut__legend-item svg.donut__legend-item-swatch.color-index-disabled,.donut__legend-item svg.donut__legend-item-swatch.color-index-unknown{stroke:#848484}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-1,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-8{stroke:#ff9e2c}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-2,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-9{stroke:#00cee4}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-10,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-3{stroke:#5b3eff}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-11,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-4{stroke:#c93}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-12,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-5{stroke:#d55af2}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-13,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-6{stroke:#79a2bc}.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-14,.donut__legend-item svg.donut__legend-item-swatch.color-index-graph-7{stroke:#877b75}.donut__legend-item svg.donut__legend-item-swatch path{stroke-width:12px;transition-property:stroke-width;transition-duration:.3s;transition-timing-function:ease-in-out}.control-icon,.react-gravatar{transition:all .3s ease-in-out}.donut__legend-item--active{color:#333;font-weight:700}.donut__legend-item--active svg.donut__legend-item-swatch path{stroke-width:12px}.donut__legend-total{margin-left:24px}.donut__legend-total>*{margin-top:6px;padding-top:6px;border-top:1px dotted #ccc}.object__attribute--array>.object__attribute-value>ol>li,.session__actions,.tile>.header .header__wrapper{border-top:1px solid #ccc}.donut--landscape .donut__graphic-container,.donut--landscape .donut__legend{display:inline-block;vertical-align:middle}.donut--landscape .donut__legend{margin:0 0 0 24px}.donut--portrait .donut__graphic-container,.donut--portrait .donut__legend{display:block}.donut--portrait .donut__legend{margin:24px 0 0}.donut--small .donut__legend{display:none}.fixed-header{position:fixed;z-index:1}.fixed-header__container{position:absolute;top:0;left:0;right:0}.footer{min-height:48px;line-height:48px}.footer__content{display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;width:100%}.footer__content.center-column__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}@media screen and (max-width:44.9375em){.document header>dl>dd,.document section>dl>dd{padding-right:24px}.fixed-header{position:relative}.fixed-header__container{position:static}.footer__content.center-column__content>.menu:first-child{width:100%}.footer__content.center-column__content>.menu:first-child:empty{width:0;margin:0;padding:0}}.footer__content>.flex-1{-webkit-flex:1;flex:1}.footer__content>.flex-2{-webkit-flex:2;flex:2}.footer__content>.flex-3{-webkit-flex:3;flex:3}.footer__content>.flex-4{-webkit-flex:4;flex:4}.footer__content>*{margin-right:48px}.footer__content>:last-child{margin-right:0}@media screen and (max-width:44.9375em){.footer__content>:last-child{text-align:left}}@media screen and (min-width:45em)and (max-width:63.9375em){.footer__content>:last-child{text-align:left}}.footer__content a.button,.footer__content button,.footer__content input[type=button],.footer__content input[type=submit]{font-size:24px;font-size:1.5rem;line-height:inherit;min-width:96px}.footer--primary{height:auto;padding:24px}.footer--primary .footer__content{position:relative;color:#999}.footer--primary .footer__content p{padding-top:12px;margin:0;max-width:none;text-align:right;line-height:24px}@media screen and (max-width:44.9375em){.footer--primary .footer__content{display:block}}@media screen and (min-width:45em)and (max-width:63.9375em){.footer--primary .footer__content{display:block}}.footer--centered .footer__content{display:block;text-align:center}.footer--centered .footer__content>*{margin-right:auto;margin-left:auto;text-align:center}.tile>.footer{border-bottom:1px solid #ccc}.form{min-width:480px}.form fieldset{border:none;margin:0;padding-bottom:1.5rem}.form .form-fields{padding:24px}.layer .form{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;max-height:100vh}.layer .form>.footer,.layer .form>.header{-webkit-flex:0 0 auto;flex:0 0 auto}.layer .form>.form-fields{overflow:auto}.form--compact{min-width:240px}.form-field{position:relative;margin-bottom:12px;line-height:36px}.form-field:last-child,.form-field__contents>table.table--selectable{margin-bottom:0}@media screen and (min-width:45em){.form:not(.form--compact) .form-field{display:-webkit-flex;display:flex;min-width:672px}}.form-field__label{display:block;text-align:left}@media screen and (min-width:45em){.form:not(.form--compact) .form-field__label{-webkit-flex:0 0 192px;flex:0 0 192px;text-align:right;padding-right:24px;vertical-align:top}.form:not(.form--compact) .form-field__container{-webkit-flex:1 0 384px;flex:1 0 384px}}.form-field__contents button{line-height:24px}.form-field__contents>input[type=email],.form-field__contents>input[type=password],.form-field__contents>input[type=range],.form-field__contents>input[type=text],.form-field__contents>select,.form-field__contents>textarea{width:240px}.form--compact .form-field__contents>input[type=email],.form--compact .form-field__contents>input[type=password],.form--compact .form-field__contents>input[type=range],.form--compact .form-field__contents>input[type=text],.form--compact .form-field__contents>select,.form--compact .form-field__contents>textarea{width:100%;margin-right:0}.form-field__contents>textarea{vertical-align:top}.control-icon,.header__content svg,.status-icon{vertical-align:middle}.form-field__contents>.check-box,.form-field__contents>.radio-button{display:block}.form-field__contents label.checkbox,.form-field__contents label.radio{margin-right:24px}.form-field__contents>table.table--selectable tbody tr td{padding-top:0;padding-bottom:0}.form-field--error input,.form-field--error select,.form-field--error textarea{border-color:#dc442f}.form-field__help{color:#999}.form-field__error{color:#dc442f}.form--compact .form-field__error{display:block;position:absolute;top:0;right:0}@media screen and (max-width:44.9375em){.header{height:48px}}@media screen and (min-width:45em){.header{height:72px}}.header__wrapper{padding-left:24px;padding-right:24px}.header__content{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;width:100%}@media screen and (max-width:44.9375em){.header__wrapper{height:48px}.header__content{line-height:48px}}@media screen and (min-width:45em){.header__wrapper{height:72px}.header__content{line-height:72px}}.header__content>*{-webkit-flex:1 0;flex:1 0}.header__content>:last-child{-webkit-flex:0 0 auto;flex:0 0 auto;text-align:right}.header__content>:first-child{-webkit-flex:1 0;flex:1 0;text-align:left}.header__content .title,.header__content>h1,.header__content>h2,.header__content>h3,.header__content>h4{margin-bottom:0;line-height:inherit}.header__content .title svg,.header__content>h1 svg,.header__content>h2 svg,.header__content>h3 svg,.header__content>h4 svg{height:48px}.header__content a{color:inherit}.header--primary{padding:0}.header--primary .header__wrapper{padding-left:24px;padding-right:24px;border-bottom:none}.header--primary .header__content{-webkit-justify-content:space-between;justify-content:space-between;white-space:nowrap}.header--primary .header__content>*{-webkit-flex:auto;flex:auto}.header--primary .header__content>:last-child{-webkit-flex:0 0 auto;flex:0 0 auto}@media screen and (min-width:45em){.header--large,.header--large .header__wrapper{height:96px}.header--large .header__content{line-height:96px}.header--small,.header--small .header__wrapper{height:48px}.header--small .header__content{line-height:48px}.header--small .header__content .title svg,.header--small .header__content>h1 svg,.header--small .header__content>h2 svg,.header--small .header__content>h3 svg,.header--small .header__content>h4 svg{height:24px}.header--primary,.header--primary .header__wrapper{height:96px;line-height:96px}.header--primary .header__content{line-height:96px}.header--primary .header__wrapper{position:fixed;top:0;left:0;right:0;z-index:3}}.control-badge,.control-badge:after{width:18px;height:18px;position:absolute}.header--flush .header__wrapper{padding-left:0;padding-right:0}.index-header,.index__container{position:relative;padding-left:24px}.tile>.header{height:48px}.tile>.header .header__wrapper{height:48px;border-bottom:none}.tile>.header .header__content{line-height:48px}.control-icon{display:inline-block;width:48px;height:48px;cursor:pointer;fill:#999;stroke:#999}.control-icon--active,.control-icon:hover{fill:#000;stroke:#000}.control-badge{top:0;right:0;border-radius:4px;background-color:#5b3eff;text-align:center;font-size:16px;font-size:1rem;line-height:18px}.control-badge:after{content:'';right:0;border-radius:4px;border:1px solid #fff}.status-icon{width:24px;height:24px}.status-icon .status-icon__base{fill:#848484}.status-icon-error .status-icon__base{fill:#dc442f}.status-icon-warning .status-icon__base{fill:#f4b51e}.status-icon-ok .status-icon__base{fill:#42a425}.status-icon-disabled .status-icon__base,.status-icon-unknown .status-icon__base{fill:#848484}.status-icon-label .status-icon__base{fill:#999}.status-icon__detail{fill:#fff}.status-icon--large{width:48px;height:48px}.status-icon--small{width:12px;height:12px}.status-icon--small .status-icon__detail{display:none}@-webkit-keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes rotate{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.icon-changing{width:24px;height:24px;-webkit-animation:rotate 1.5s linear infinite;animation:rotate 1.5s linear infinite}.icon-changing--small{width:12px;height:12px}.icon-spinning{width:24px;height:24px;-webkit-animation:rotate 4s steps(4,end)infinite;animation:rotate 4s steps(4,end)infinite}.icon-spinning--small{width:12px;height:12px}.index__container{padding-right:24px;padding-bottom:24px}.index__header{height:48px;line-height:48px}.index__items{padding-top:96px;width:100%}.index__more{padding-top:24px}.index__error{color:#dc442f}.index-header{font-size:30px;font-size:1.875rem;line-height:inherit;padding-right:24px;display:-webkit-flex;display:flex}.index-header__search{-webkit-flex:1;flex:1}.index-header__count{-webkit-flex:0 0 auto;flex:0 0 auto;min-width:192px;margin-left:24px;color:#999;text-align:left}.index-header__out-of{margin-left:12px;font-size:16px;font-size:1rem;line-height:1.5;display:none}.index-header__out-of--active{display:inline}.index-table{width:100%}.index-tiles .tile>.header svg{margin-right:12px}.index-tiles .tile>:not(.header){display:block}a.active>.label .label__icon.control-icon svg{fill:#000;stroke:#000}.layer{position:fixed;top:0;left:0;right:0;overflow:none;z-index:10}.layer__container{position:absolute;background-color:rgba(255,255,255,.95);overflow:none;border-radius:4px;max-height:100vh;max-width:100vw}.layer--align-center{background-image:radial-gradient(circle at top,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}.layer--align-center .layer__container{left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}.layer--align-left{background-image:radial-gradient(circle at left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}.layer--align-left .layer__container{left:0;-webkit-animation:slide-right .2s ease-in-out forwards;animation:slide-right .2s ease-in-out forwards}.layer--align-right{background-image:radial-gradient(circle at right,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}.layer--align-right .layer__container{right:0}.layer--align-top{background-image:radial-gradient(circle at top left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}.layer--align-top .layer__container{top:0;-webkit-animation:slide-down .2s ease-in-out forwards;animation:slide-down .2s ease-in-out forwards}.layer--align-bottom{background-image:radial-gradient(circle at bottom left,rgba(255,255,255,.95),rgba(255,255,255,.95) 20%,rgba(128,128,128,.6))}@-webkit-keyframes slide-right{0%{left:-100vw}100%{left:0}}@keyframes slide-right{0%{left:-100vw}100%{left:0}}@-webkit-keyframes slide-down{0%{top:-100vh}100%{top:0}}@keyframes slide-down{0%{top:-100vh}100%{top:0}}@media screen and (min-width:45em){.label__icon{display:none}}.notifications__container,.panel{background-color:#fff;border-bottom:1px solid #ccc}.login{position:absolute;top:0;left:0;right:0;overflow:hidden;z-index:100}.login__background{position:absolute;max-width:none}.login__background--portrait{width:auto;height:100%}.login__background--landscape{height:auto;width:100%}.login__container{position:relative;width:384px;margin:96px auto;z-index:1;animation-name:fadein;animation-duration:.5s}.login-form,.login__container{-webkit-animation-duration:.5s;-webkit-animation-name:fadein}@media screen and (max-width:44.9375em){.label__text{display:none}.login__container{margin:48px 0;width:100%;border-radius:0}}.login__footer{position:absolute;left:0;right:0;bottom:6px;padding:6px 24px;background-color:rgba(255,255,255,.9);text-align:center}.login-form{width:384px;padding:24px 24px 48px;background-color:rgba(255,255,255,.95);border:1px solid #ccc;border-radius:4px;text-align:center;z-index:1;animation-name:fadein;animation-duration:.5s}@media screen and (max-width:44.9375em){.login-form{width:100%;border-radius:0}}.login-form__logo{display:inline-block;width:48px;height:48px;margin-bottom:24px}.login-form fieldset{text-align:left;border:none;margin-bottom:0}.login-form fieldset input,.login-form__error{margin-bottom:12px}.login-form fieldset>*{width:100%;display:block}.login-form__submit{margin-top:24px;width:100%;background-color:#0080ff;color:#fff;font-size:24px;font-size:1.5rem;line-height:inherit}.login-form__error{color:#dc442f;text-align:left}.menu--inline.menu--left,.menu__layer--align-right .menu__control,.menu__layer--left{text-align:right}.login-form__footer{margin-top:12px;display:-webkit-flex;display:flex;-webkit-justify-content:space-between;justify-content:space-between;line-height:36px}.menu,.menu__layer{line-height:inherit}.menu{display:inline-block;font-size:20px;font-size:1.25rem}.menu__control--fixed-label .menu__control-icon,.menu__layer .menu__control-drop-icon{display:none}.menu a:not(.button){color:gray}.menu a:not(.button):hover{color:#333}.menu a:not(.button).active{color:#0069d1}.menu:focus{outline:0;margin:-1px;border:1px solid #ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}.menu__control{cursor:pointer}.menu__control-drop-icon{width:24px;height:24px;margin-top:-6px;margin-left:12px;stroke:#999}.menu--inline.menu--small .menu__control-icon svg,.menu--small .menu__control-icon svg,.menu__layer--small .menu__control-icon svg{width:18px;height:18px}@media screen and (max-width:44.9375em){.menu__control--labelled .menu__control-drop-icon,.menu__control--labelled .menu__control-label{display:none}}@media screen and (min-width:45em){.menu__control--labelled .menu__control-icon{display:none}}.menu__layer{position:fixed;z-index:5;font-size:24px;font-size:1.5rem;background-color:#fff;border:none;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,.3)}.menu__layer .menu__control-label{padding-left:24px}.menu__layer a{padding:12px 24px}.menu__layer a:hover{text-decoration:none;background-color:rgba(0,0,0,.1)}.menu--controlled{display:inline-block;cursor:pointer}.menu--inline.menu--left>*{margin-left:24px;margin-right:0}.menu--inline.menu--left>:first-child{margin-left:0}.menu--inline.menu--right>*{margin-left:0;margin-right:24px}.menu--inline.menu--right>:last-child{margin-right:0}@media screen and (max-width:44.9375em){.menu--inline.menu--down:empty{width:0;margin:0;padding:0}}[class*=background-color-index-] .menu--inline a,[class*=background-color-index-] .menu--inline a.active,[class*=background-color-index-] .menu--inline a:hover{color:inherit}[class*=background-color-index-] .menu--inline.menu--left a,[class*=background-color-index-] .menu--inline.menu--right a{text-decoration:none}[class*=background-color-index-] .menu--inline.menu--left a:hover:not(.active):not(.button),[class*=background-color-index-] .menu--inline.menu--right a:hover:not(.active):not(.button){text-decoration:underline}.tile>a,.title a:hover,[class*=background-color-index-] .menu--inline.menu--down a:hover{text-decoration:none}[class*=background-color-index-] .menu--inline.menu--down a{padding:12px;border:1px solid transparent}[class*=background-color-index-] .menu--inline.menu--down a:hover:not(.active){border-color:rgba(0,0,0,.2)}[class*=background-color-index-] .menu--inline.menu--down a.active{background-color:rgba(0,0,0,.2)}.menu--small{font-size:16px;font-size:1rem;line-height:1.5}.menu--small .menu__control-drop-icon{margin-left:6px}.menu--primary{display:block;padding:0 24px 24px;max-height:100vh;overflow:auto}.react-gravatar,.tile,.title{overflow:hidden}.menu--inline.menu--left>*,.menu--inline.menu--right>*,.menu__layer--left>*,.menu__layer--right>*{display:inline-block}.menu--primary>.header:first-child{margin-left:-24px;margin-right:-24px;margin-bottom:24px}.menu--inline.menu--right,.menu__layer--right,.object,.object__attribute-name{text-align:left}.menu--inline.menu--small,.menu__layer--small{font-size:1em}.menu--inline.menu--small .menu__control-label,.menu__layer--small .menu__control-label{padding:12px}.menu--inline.menu--small a,.menu__layer--small a{padding:6px 12px}.menu--inline.menu--down>*,.menu--inline.menu--up>*,.menu__layer--down>*,.menu__layer--up>*{display:block}.meter,.meter__label,.object__attribute-name{display:inline-block}.menu--inline.menu--down h1,.menu--inline.menu--down h2,.menu--inline.menu--down h3,.menu--inline.menu--down h4,.menu--inline.menu--down h5,.menu--inline.menu--down h6,.menu--inline.menu--up h1,.menu--inline.menu--up h2,.menu--inline.menu--up h3,.menu--inline.menu--up h4,.menu--inline.menu--up h5,.menu--inline.menu--up h6,.menu__layer--down h1,.menu__layer--down h2,.menu__layer--down h3,.menu__layer--down h4,.menu__layer--down h5,.menu__layer--down h6,.menu__layer--up h1,.menu__layer--up h2,.menu__layer--up h3,.menu__layer--up h4,.menu__layer--up h5,.menu__layer--up h6{margin:24px 0 0;padding:12px 0;border-top:1px solid #ccc;min-width:192px}.menu--inline.menu--down h1:first-child,.menu--inline.menu--down h2:first-child,.menu--inline.menu--down h3:first-child,.menu--inline.menu--down h4:first-child,.menu--inline.menu--down h5:first-child,.menu--inline.menu--down h6:first-child,.menu--inline.menu--up h1:first-child,.menu--inline.menu--up h2:first-child,.menu--inline.menu--up h3:first-child,.menu--inline.menu--up h4:first-child,.menu--inline.menu--up h5:first-child,.menu--inline.menu--up h6:first-child,.menu__layer--down h1:first-child,.menu__layer--down h2:first-child,.menu__layer--down h3:first-child,.menu__layer--down h4:first-child,.menu__layer--down h5:first-child,.menu__layer--down h6:first-child,.menu__layer--up h1:first-child,.menu__layer--up h2:first-child,.menu__layer--up h3:first-child,.menu__layer--up h4:first-child,.menu__layer--up h5:first-child,.menu__layer--up h6:first-child{margin-top:0}@-webkit-keyframes draw-meter{0%{stroke-dashoffset:192px}100%{stroke-dashoffset:0}}@keyframes draw-meter{0%{stroke-dashoffset:192px}100%{stroke-dashoffset:0}}.meter__graphic{width:192px;height:24px;background-color:#eee}.notifications-control__icon,.notifications__icon{vertical-align:middle;width:48px;height:48px}.meter__value{stroke:#0080ff;stroke-width:18px;stroke-dasharray:192px 192px;stroke-dashoffset:0;-webkit-animation:draw-meter 1.5s;animation:draw-meter 1.5s}.meter__threshold{stroke:#333;stroke-width:1px}.meter__label{vertical-align:top;margin-left:12px}.meter__label-units{color:#999;margin-left:.5em}.notifications{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(128,128,128,.6);z-index:10}.notifications__container{position:absolute;top:0;right:0;min-width:300px;padding:96px 24px 24px;border-left:1px solid #ccc;border-bottom-left-radius:4px}.notifications__icon{position:absolute;top:24px;right:84px}.object li{width:auto}.object__attribute-name{vertical-align:top;width:192px;color:#999}.object__attribute-value{display:inline-block;vertical-align:top;margin-left:24px;text-align:left;max-width:384px}.section--centered,.settings{text-align:center}.object__attribute-value ul{padding-top:24px}.object__attribute--container>.object__attribute-name{font-weight:700}.object__attribute--unset .object__attribute-value{font-style:italic;color:#999}.object__attribute--array>.object__attribute-value>ol{position:relative}.object__attribute--array>.object__attribute-value>ol>li:first-child{border:none}.object__attribute--array>.object__attribute-value>ol>li>ul{padding-top:0}.panel{padding:24px}.panel:last-of-type{border-bottom:none}.panel__title{text-transform:uppercase;font-weight:400}.panel>a{display:block}.panel a.call-to-action,.radio-button__label,.radio-button__label:before,.search,.search__layer-contents{display:inline-block}.panel a.call-to-action{font-size:20px;font-size:1.25rem;line-height:1.2;margin-bottom:24px;text-decoration:none;padding:12px 24px;border-radius:4px;color:#fff}.panel--index-1 .panel__title{color:#5b3eff}.panel--index-1 a.call-to-action{background-color:#5b3eff}.panel--index-2 .panel__title{color:#c93}.panel--index-2 a.call-to-action{background-color:#c93}@media screen and (max-width:44.9375em){.panel{padding:24px}.panel>h2{margin-bottom:12px}}.radio-button__input{opacity:0;position:absolute}.radio-button__input:checked+label.radio:after{content:"";position:absolute;top:10.5px;left:4px;width:16px;height:16px;background-color:#0080ff;border-radius:16px}.radio-button__input:focus+label.checkbox:before{content:"";border-color:#ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}.radio-button__label{position:relative;cursor:pointer;-ms-user-select:none;user-select:none}.radio-button__label:before{content:"";width:24px;height:24px;margin-right:12px;vertical-align:middle;background-color:inherit;color:#0069d1;border:1px solid #ccc;border-radius:24px;text-align:center}.search:focus{outline:0;margin:-1px;border:1px solid #ff9e2c;box-shadow:0 0 1px 1px #ff9e2c}.search--controlled,.search__control{cursor:pointer}.search__input{margin-right:0;padding:0 12px;font-size:inherit}.search__layer{position:fixed;z-index:2;font-size:20px;font-size:1.25rem;line-height:inherit;background-color:#fff;border:none;border-radius:4px;box-shadow:0 2px 4px rgba(0,0,0,.3)}.search__layer--inline{margin-left:-1px}.search__layer input{margin-right:0;box-sizing:border-box}.search__layer .search__control{display:inline-block;vertical-align:top}.search__layer .search__suggestion{padding:6px 12px;cursor:pointer}.search__layer .search__suggestion:hover{background-color:rgba(0,0,0,.1)}.search--inline .search__input{width:100%;box-sizing:border-box;line-height:inherit}.section{padding-top:48px;padding-bottom:48px}.section--right .section__content{display:-webkit-flex;display:flex}.section--right .section__content.center-column__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}@media screen and (max-width:44.9375em){.section--right .section__content.center-column__content>.menu:first-child{width:100%}.section--right .section__content.center-column__content>.menu:first-child:empty{width:0;margin:0;padding:0}}.section--right .section__content>.flex-1{-webkit-flex:1;flex:1}.section--right .section__content>.flex-2{-webkit-flex:2;flex:2}.section--right .section__content>.flex-3{-webkit-flex:3;flex:3}.section--right .section__content>.flex-4{-webkit-flex:4;flex:4}@media screen and (min-width:45em){.section--right .section__content>*{margin-right:48px}.section--right .section__content>:last-child{margin-right:0}.section--right .section__content>.menu:first-child{-webkit-flex:0 0 auto;flex:0 0 auto;width:192px}}@media screen and (max-width:44.9375em){.section--right .section__content{-webkit-flex-direction:column;flex-direction:column}.section--right .section__content>*{margin-bottom:48px;padding-bottom:48px}.section--right .section__content>:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}}.section--compact{padding-top:0;padding-bottom:0}.section--compact .section__content{padding-top:12px;padding-bottom:12px}.section--centered .section__content>*{margin-left:auto;margin-right:auto}.react-gravatar{width:48px;height:48px;border-radius:24px;border:2px solid transparent;margin:0 24px;cursor:pointer}.react-gravatar:hover{border-color:#0080ff}.session{position:fixed;top:0;left:0;right:0;bottom:0;background-color:rgba(128,128,128,.6);z-index:10}.session__container{position:absolute;top:0;right:0;min-width:300px;padding:96px 24px 24px;background-color:#fff;border-left:1px solid #ccc;border-bottom:1px solid #ccc;border-bottom-left-radius:4px}.session .react-gravatar{position:absolute;top:24px;right:24px}.session__actions{margin-top:24px;padding-top:24px}.session a{cursor:pointer}.settings{position:relative}.settings__panels{display:inline-block}.settings__panel{vertical-align:top}.table{width:100%}.table th{font-weight:100;font-size:20px;font-size:1.25rem;border-bottom:1px solid #ccc}.table td,.table th{padding:6px 12px;line-height:36px;text-align:left}.table--selectable tbody tr{cursor:pointer}.table--selectable tbody tr.table__row--selected td{background-color:#fffffa}.table--selectable tbody tr:hover td{background-color:rgba(0,0,0,.1)}.tbd{text-align:center;padding:96px;font-size:96px;font-size:6rem;line-height:1;background-color:#ccc;color:#fff}.tile>a,.title a{color:inherit}.tile,.tiles{padding:12px}.tiles{display:-webkit-flex;display:flex;-webkit-flex-wrap:wrap;flex-wrap:wrap}.tiles>*{-webkit-flex:0 0 192px;flex:0 0 192px;flex-grow:1}.tiles--flush{margin:-24px}.tiles--small>*{-webkit-flex-basis:96px;flex-basis:96px}.tiles--fill{-webkit-align-items:stretch;align-items:stretch;-webkit-align-content:stretch;align-content:stretch}.tiles--fill>*{-webkit-flex-grow:1;flex-grow:1}@media screen and (max-width:44.9375em){.tile{margin:0;border-radius:none}}.tile>.header{margin-bottom:24px}.tile>a{display:block;height:100%;padding:24px}.tile--wide{-webkit-flex-basis:100%;flex-basis:100%}.title{text-overflow:ellipsis;font-weight:400;margin-right:24px}[class*=background-color-index-] .title a:hover{text-decoration:underline}.title img,.title svg:not(.control-icon){margin-right:12px}@media screen and (max-width:44.9375em){.title{font-size:32px;font-size:2rem;line-height:inherit}.title img,.title svg:not(.control-icon){height:24px}}@media screen and (min-width:45em){.title{font-size:40px;font-size:2.5rem;line-height:inherit}.title img,.title svg:not(.control-icon){height:48px}}.title--menu .control-icon{margin-left:12px}.title--menu:hover{cursor:pointer}.title--menu:hover .control-icon{stroke:#0080ff}.clearfix:after{content:"";display:table;clear:both} \ No newline at end of file diff --git a/grommet.js b/grommet.js index a6289fa..0ea635a 100644 --- a/grommet.js +++ b/grommet.js @@ -47,79 +47,58 @@ var Grommet = // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var SessionActions = __webpack_require__(1); - var Router = __webpack_require__(2); - var Grommet = { // Components - App: __webpack_require__(3), - CheckBox: __webpack_require__(4), - Document: __webpack_require__(5), - Donut: __webpack_require__(6), - FixedHeader: __webpack_require__(7), - Footer: __webpack_require__(8), - Form: __webpack_require__(9), - FormField: __webpack_require__(10), - Header: __webpack_require__(11), - Label: __webpack_require__(12), - Link: __webpack_require__(13), - Login: __webpack_require__(14), - LoginForm: __webpack_require__(15), - Menu: __webpack_require__(16), - Meter: __webpack_require__(17), - Panel: __webpack_require__(18), - RadioButton: __webpack_require__(19), - Search: __webpack_require__(20), - SearchCombo: __webpack_require__(21), - Section: __webpack_require__(22), - Table: __webpack_require__(23), - Tiles: __webpack_require__(24), - Tile: __webpack_require__(25), - Title: __webpack_require__(26), - Object: __webpack_require__(27), - TBD: __webpack_require__(28), + App: __webpack_require__(1), + CheckBox: __webpack_require__(2), + Document: __webpack_require__(3), + Donut: __webpack_require__(4), + FixedHeader: __webpack_require__(5), + Footer: __webpack_require__(6), + Form: __webpack_require__(7), + FormField: __webpack_require__(8), + Header: __webpack_require__(9), + Label: __webpack_require__(10), + Login: __webpack_require__(11), + LoginForm: __webpack_require__(12), + Menu: __webpack_require__(13), + Meter: __webpack_require__(14), + Panel: __webpack_require__(15), + RadioButton: __webpack_require__(16), + Search: __webpack_require__(17), + SearchCombo: __webpack_require__(18), + Section: __webpack_require__(19), + Table: __webpack_require__(20), + Tiles: __webpack_require__(21), + Tile: __webpack_require__(22), + Title: __webpack_require__(23), + Object: __webpack_require__(24), + TBD: __webpack_require__(25), Icons: { - Clear: __webpack_require__(29), - DragHandle: __webpack_require__(30), - Edit: __webpack_require__(31), - Filter: __webpack_require__(32), - Help: __webpack_require__(33), - More: __webpack_require__(34), - Next: __webpack_require__(35), - Previous: __webpack_require__(36), - Search: __webpack_require__(37), - SearchPlus: __webpack_require__(38), - Spinning: __webpack_require__(39), - Status: __webpack_require__(40) + Clear: __webpack_require__(26), + DragHandle: __webpack_require__(27), + Edit: __webpack_require__(28), + Filter: __webpack_require__(29), + Help: __webpack_require__(30), + More: __webpack_require__(31), + Next: __webpack_require__(32), + Previous: __webpack_require__(33), + Search: __webpack_require__(34), + SearchPlus: __webpack_require__(35), + Spinning: __webpack_require__(36), + Status: __webpack_require__(37) }, // Mixins Mixins: { - KeyboardAccelerators: __webpack_require__(41), - ReactLayeredComponent: __webpack_require__(42) + KeyboardAccelerators: __webpack_require__(38), + ReactLayeredComponent: __webpack_require__(39) }, - // Constants - AppConstants: __webpack_require__(43), - // Dispatchers - AppDispatcher: __webpack_require__(44), // Actions - SessionActions: SessionActions, + Actions: __webpack_require__(40), // Stores - SessionStore: __webpack_require__(45), + SessionStore: __webpack_require__(41), // Utils - Api: __webpack_require__(46), - Router: Router, - - Index: __webpack_require__(47), - - init: function (options) { - SessionActions.setup(options.login !== false); - - Router.init(options.routes, options.mainContainerId); - }, - - start: function () { - Router.start(); - } + Rest: __webpack_require__(42) }; module.exports = Grommet; @@ -131,158 +110,7 @@ var Grommet = // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var AppDispatcher = __webpack_require__(44); - var Constants = __webpack_require__(43); - var Api = __webpack_require__(46); - - module.exports = { - - setup: function () { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.SESSION_SETUP - }); - }, - - logout: function () { - console.log('!!! SessionActions logout'); - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.SESSION_LOGOUT - }); - console.log('!!! SessionActions logout A'); - Api.del(Constants.ActionTypes.SESSION_LOGOUT, '/rest/login-sessions'); - console.log('!!! SessionActions logout B'); - }, - - login: function (username, password) { - Api.post(Constants.ActionTypes.SESSION_LOGIN, '/rest/login-sessions', - {authLoginDomain: 'LOCAL', userName: username, password: password, loginMsgAck: true}, - {username: username}); - } - - }; - - -/***/ }, -/* 2 */ -/***/ function(module, exports, __webpack_require__) { - - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - - var _ = __webpack_require__(79); - var React = __webpack_require__(48); - var Router = __webpack_require__(82); - var NavActions = __webpack_require__(49); - - module.exports = { - - init: function (routes, containerId) { - this._router = Router.create({ - routes: routes - }); - - this._containerId = containerId; - - document.body.innerHTML += '
One sec...
'; - }, - - start: function () { - this._router.run(function (Handler, state) { - //console.log('!!! Router router run', state.path); - this._state = state; - NavActions.routeChange(state); - var factory = React.createFactory(Handler); - var appElement = document.getElementById(this._containerId); - if (appElement) { - React.render(factory(), appElement); - } - }.bind(this)); - }, - - // Wrap react-router.Navigation - - makePath: function (routeName, params, query) { - return(this._router.makePath(routeName, params, query)); - }, - - transitionTo: function (routeName, params, query) { - this._router.transitionTo(routeName, params, query); - }, - - replaceWith: function (routeName, params, query) { - this._router.replaceWith(routeName, params, query); - }, - - updateParam: function (name, value) { - var obj = {}; - obj[name] = value; - return _.extend({}, this._state.params, obj); - }, - - updateQueryParam: function (name, value) { - var obj = {}; - obj[name] = value; - return _.extend({}, this._state.query, obj); - }, - - makeHrefParam: function (name, value) { - return this._router.makeHref( - this._state.routes[this._state.routes.length-1].name, - this.updateQueryParam(name, value), - this._state.query); - }, - - transitionToParam: function (name, value) { - this._router.transitionTo( - this._state.routes[this._state.routes.length-1].name, - this.updateQueryParam(name, value), - this._state.query); - }, - - replaceParam: function (name, value) { - this._router.replaceWith( - this._state.routes[this._state.routes.length-1].name, - this.updateQueryParam(name, value), - this._state.query); - }, - - replaceQueryParam: function (name, value) { - this._router.replaceWith( - this._state.routes[this._state.routes.length-1].name, - this._state.params, - this.updateQueryParam(name, value)); - }, - - makeHref: function (route) { - return route; //this._router.makeHref(route, params, query); - }, - - isActive: function (routeName) { - return this._state.routes.some(function (route) { - return route.name === routeName; - }); - }, - - param: function (name) { - return this._state ? this._state.params[name] : null; - }, - - queryParams: function () { - return this._state.query; - }, - - queryParam: function (name) { - return this._state ? this._state.query[name] : null; - } - }; - - -/***/ }, -/* 3 */ -/***/ function(module, exports, __webpack_require__) { - - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - - var React = __webpack_require__(48); + var React = __webpack_require__(43); var App = React.createClass({displayName: "App", @@ -317,12 +145,12 @@ var Grommet = /***/ }, -/* 4 */ +/* 2 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var CheckBox = React.createClass({displayName: "CheckBox", @@ -351,11 +179,11 @@ var Grommet = /***/ }, -/* 5 */ +/* 3 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var GrommetDocument = React.createClass({displayName: "GrommetDocument", @@ -383,12 +211,14 @@ var Grommet = /***/ }, -/* 6 */ +/* 4 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); + + var BASE_SIZE = 192; function polarToCartesian (centerX, centerY, radius, angleInDegrees) { var angleInRadians = (angleInDegrees-90) * Math.PI / 180.0; @@ -412,7 +242,7 @@ var Grommet = var Donut = React.createClass({displayName: "Donut", propTypes: { - key: React.PropTypes.bool, + legend: React.PropTypes.bool, series: React.PropTypes.arrayOf(React.PropTypes.shape({ label: React.PropTypes.string, value: React.PropTypes.number, @@ -421,7 +251,8 @@ var Grommet = React.PropTypes.string // status ]), onClick: React.PropTypes.func - })).isRequired + })).isRequired, + units: React.PropTypes.string }, _initialTimeout: function () { @@ -437,21 +268,96 @@ var Grommet = this.setState({initial: false, activeIndex: 0}); }, + _onResize: function() { + // orientation based on available window orientation + var ratio = window.innerWidth / window.innerHeight; + if (ratio < 0.8) { + this.setState({orientation: 'portrait'}); + } else if (ratio > 1.2) { + this.setState({orientation: 'landscape'}); + } + // content based on avialable real estate + var parentElement = this.refs.donut.getDOMNode().parentNode; + var width = parentElement.offsetWidth; + var height = parentElement.offsetHeight; + if (height < BASE_SIZE || width < BASE_SIZE || + (width < (BASE_SIZE * 2) && height < (BASE_SIZE * 2))) { + this.setState({size: 'small'}); + } else { + this.setState({size: null}); + } + }, + getInitialState: function() { - return {initial: true, activeIndex: 0}; + return { + initial: true, + activeIndex: 0, + legend: false, + orientation: 'portrait' + }; }, componentDidMount: function() { this._timeout = setTimeout(this._initialTimeout, 10); this.setState({initial: true, activeIndex: 0}); + window.addEventListener('resize', this._onResize); + setTimeout(this._onResize, 10); }, componentWillUnmount: function() { clearTimeout(this._timeout); this._timeout = null; + window.removeEventListener('resize', this._onResize); + }, + + _itemColorIndex: function (item, index) { + return item.colorIndex || ('graph-' + (index + 1)); + }, + + _renderLegend: function () { + var total = 0; + + var legends = this.props.series.map(function (item, index) { + var legendClasses = ["donut__legend-item"]; + if (this.state.activeIndex === index) { + legendClasses.push("donut__legend-item--active"); + } + var colorIndex = this._itemColorIndex(item, index); + total += item.value; + + return( + React.createElement("li", {key: item.label, className: legendClasses.join(' '), + onMouseOver: this._onMouseOver.bind(this, index), + onMouseOut: this._onMouseOut.bind(this, index)}, + React.createElement("svg", {className: "donut__legend-item-swatch color-index-" + colorIndex, + viewBox: "0 0 12 12"}, + React.createElement("path", {className: item.className, d: "M 5 0 l 0 12"}) + ), + React.createElement("span", {className: "donut__legend-item-label"}, item.label), + React.createElement("span", {className: "donut__legend-item-value"}, item.value), + React.createElement("span", {className: "donut__legend-item-units"}, this.props.units) + ) + ); + }, this); + + return ( + React.createElement("ol", {className: "donut__legend"}, + legends, + React.createElement("li", {className: "donut__legend-total"}, + React.createElement("span", {className: "donut__legend-total-label"}, "Total"), + React.createElement("span", {className: "donut__legend-total-value"}, total), + React.createElement("span", {className: "donut__legend-total-units"}, this.props.units) + ) + ) + ); }, render: function() { + var classes = ["donut", "donut--" + this.state.orientation]; + if (this.state.size) { + classes.push("donut--" + this.state.size); + } + var total = 0; this.props.series.some(function (item) { total += item.value; @@ -459,22 +365,20 @@ var Grommet = var startAngle = 0; var anglePer = 360.0 / total; - var paths = {}; - var keys = {}; var value = null; var units = null; var label = null; - this.props.series.forEach(function (item, index) { + var paths = this.props.series.map(function (item, index) { var endAngle = Math.min(360, Math.max(10, startAngle + (anglePer * item.value))); var radius = (this.state.activeIndex === index) ? 78 : 72; - var commands = describeArc(96, 96, radius, startAngle, endAngle-2); + var commands = describeArc(BASE_SIZE/2, BASE_SIZE/2, radius, startAngle, endAngle-2); startAngle = endAngle; - var colorIndex = item.colorIndex || (index + 1); + var colorIndex = this._itemColorIndex(item, index); var sliceClasses = ["donut__slice"]; - sliceClasses.push("donut__slice--color-index-" + colorIndex); + sliceClasses.push("color-index-" + colorIndex); if (this.state.activeIndex === index) { sliceClasses.push("donut__slice--active"); value = item.value; @@ -482,38 +386,24 @@ var Grommet = label = item.label; } - paths[colorIndex] = ( - React.createElement("path", {fill: "none", className: sliceClasses.join(' '), d: commands, + return( + React.createElement("path", {key: item.label, fill: "none", className: sliceClasses.join(' '), d: commands, onMouseOver: this._onMouseOver.bind(null, index), onMouseOut: this._onMouseOut.bind(null, index), onClick: item.onClick}) ); - - if (this.props.key) { - - var keyItemClasses = ["donut__key-item"]; - if (this.state.activeIndex === index) { - keyItemClasses.push("donut__key-item--active"); - } - - keys[colorIndex] = ( - React.createElement("li", {key: item.className, className: keyItemClasses.join(' '), - onMouseOver: this._onMouseOver.bind(null, index), - onMouseOut: this._onMouseOut.bind(null, index)}, - React.createElement("svg", {className: "donut__key-item-swatch", viewBox: "0 0 12 12"}, - React.createElement("path", {className: item.className, d: "M 5 0 l 0 12"}) - ), - React.createElement("span", {className: "donut__key-item-label"}, item.label), - React.createElement("span", {className: "donut__key-item-value"}, item.value) - ) - ); - } }, this); + var legend = null; + if (this.props.legend) { + legend = this._renderLegend(); + } + return ( - React.createElement("div", {className: "donut"}, + React.createElement("div", {ref: "donut", className: classes.join(' ')}, React.createElement("div", {className: "donut__graphic-container"}, - React.createElement("svg", {className: "donut__graphic", viewBox: "0 0 192 192", + React.createElement("svg", {className: "donut__graphic", + viewBox: "0 0 " + BASE_SIZE + " " + BASE_SIZE, preserveAspectRatio: "xMidYMid meet"}, React.createElement("g", null, paths) ), @@ -522,13 +412,10 @@ var Grommet = value, React.createElement("span", {className: "donut__active-units"}, units) ), - React.createElement("div", {className: "donut__active-label"}, label) ) ), - React.createElement("ol", {className: "donut__key"}, - keys - ) + legend ) ); } @@ -539,12 +426,12 @@ var Grommet = /***/ }, -/* 7 */ +/* 5 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var CLASS_ROOT = "fixed-header"; @@ -590,13 +477,13 @@ var Grommet = /***/ }, -/* 8 */ +/* 6 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); - var Top = __webpack_require__(50); + var React = __webpack_require__(43); + var Top = __webpack_require__(44); var Footer = React.createClass({displayName: "Footer", @@ -685,12 +572,12 @@ var Grommet = /***/ }, -/* 9 */ +/* 7 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Form = React.createClass({displayName: "Form", @@ -720,12 +607,12 @@ var Grommet = /***/ }, -/* 10 */ +/* 8 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var FormField = React.createClass({displayName: "FormField", @@ -767,27 +654,35 @@ var Grommet = /***/ }, -/* 11 */ +/* 9 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Header = React.createClass({displayName: "Header", propTypes: { colorIndex: React.PropTypes.string, + flush: React.PropTypes.bool, large: React.PropTypes.bool, primary: React.PropTypes.bool, small: React.PropTypes.bool }, + getDefaultProps: function () { + return {flush: true, large: false, primary: false, small: false}; + }, + render: function() { var classes = ["header"]; if (this.props.primary) { classes.push("header--primary"); } + if (this.props.flush) { + classes.push("header--flush"); + } if (this.props.large) { classes.push("header--large"); } @@ -819,12 +714,12 @@ var Grommet = /***/ }, -/* 12 */ +/* 10 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Label = React.createClass({displayName: "Label", @@ -856,44 +751,12 @@ var Grommet = /***/ }, -/* 13 */ -/***/ function(module, exports, __webpack_require__) { - - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - - var React = __webpack_require__(48); - var Router = __webpack_require__(2); - - var Link = React.createClass({displayName: "Link", - - _onClick: function (event) { - event.preventDefault(); - if (this.props.onClick) { - this.props.onClick(event); - } - Router.transitionTo(event.currentTarget.getAttribute('href')); - }, - - render: function() { - return ( - React.createElement("a", {className: this.props.className, href: this.props.href, onClick: this._onClick}, - this.props.children - ) - ); - } - - }); - - module.exports = Link; - - -/***/ }, -/* 14 */ +/* 11 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Login = React.createClass({displayName: "Login", @@ -921,7 +784,7 @@ var Grommet = componentDidMount: function() { window.addEventListener('resize', this._onResize); - setTimeout(this.adjustBackground, 10); + setTimeout(this.adjustBackground, 300); }, componentWillUnmount: function() { @@ -957,13 +820,13 @@ var Grommet = /***/ }, -/* 15 */ +/* 12 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); - var CheckBox = __webpack_require__(4); + var React = __webpack_require__(43); + var CheckBox = __webpack_require__(2); var CLASS_ROOT = "login-form"; @@ -1062,17 +925,17 @@ var Grommet = /***/ }, -/* 16 */ +/* 13 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); - var ReactLayeredComponent = __webpack_require__(42); - var KeyboardAccelerators = __webpack_require__(41); - var Overlay = __webpack_require__(51); - var MoreIcon = __webpack_require__(34); - var DropCaretIcon = __webpack_require__(52); + var React = __webpack_require__(43); + var ReactLayeredComponent = __webpack_require__(39); + var KeyboardAccelerators = __webpack_require__(38); + var Overlay = __webpack_require__(45); + var MoreIcon = __webpack_require__(31); + var DropCaretIcon = __webpack_require__(46); var Menu = React.createClass({displayName: "Menu", @@ -1305,12 +1168,12 @@ var Grommet = /***/ }, -/* 17 */ +/* 14 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var BASE_WIDTH = 192; var BASE_HEIGHT = 24; @@ -1376,11 +1239,11 @@ var Grommet = /***/ }, -/* 18 */ +/* 15 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Panel = React.createClass({displayName: "Panel", @@ -1416,12 +1279,12 @@ var Grommet = /***/ }, -/* 19 */ +/* 16 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var RadioButton = React.createClass({displayName: "RadioButton", @@ -1450,16 +1313,16 @@ var Grommet = /***/ }, -/* 20 */ +/* 17 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); - var ReactLayeredComponent = __webpack_require__(42); - var KeyboardAccelerators = __webpack_require__(41); - var Overlay = __webpack_require__(51); - var SearchIcon = __webpack_require__(37); + var React = __webpack_require__(43); + var ReactLayeredComponent = __webpack_require__(39); + var KeyboardAccelerators = __webpack_require__(38); + var Overlay = __webpack_require__(45); + var SearchIcon = __webpack_require__(34); var CLASS_ROOT = "search"; @@ -1729,12 +1592,12 @@ var Grommet = /***/ }, -/* 21 */ +/* 18 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var CLASS_ROOT = 'search-combo'; @@ -1755,12 +1618,12 @@ var Grommet = /***/ }, -/* 22 */ +/* 19 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Section = React.createClass({displayName: "Section", @@ -1820,12 +1683,12 @@ var Grommet = /***/ }, -/* 23 */ +/* 20 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Table = React.createClass({displayName: "Table", @@ -1894,22 +1757,34 @@ var Grommet = /***/ }, -/* 24 */ +/* 21 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Tiles = React.createClass({displayName: "Tiles", propTypes: { + fill: React.PropTypes.bool, + flush: React.PropTypes.bool, small: React.PropTypes.bool }, + getDefaultProps: function () { + return {flush: true, fill: false, small: false}; + }, + // children should be an array of Tile render: function () { var classes = ["tiles"]; + if (this.props.fill) { + classes.push("tiles--fill"); + } + if (this.props.flush) { + classes.push("tiles--flush"); + } if (this.props.small) { classes.push("tiles--small"); } @@ -1929,17 +1804,18 @@ var Grommet = /***/ }, -/* 25 */ +/* 22 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Tile = React.createClass({displayName: "Tile", propTypes: { - status: React.PropTypes.string + status: React.PropTypes.string, + wide: React.PropTypes.bool }, render: function() { @@ -1947,6 +1823,9 @@ var Grommet = if (this.props.status) { classes.push("tile--status-" + this.props.status.toLowerCase()); } + if (this.props.wide) { + classes.push("tile--wide"); + } if (this.props.className) { classes.push(this.props.className); } @@ -1964,13 +1843,13 @@ var Grommet = /***/ }, -/* 26 */ +/* 23 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); - var DropCaret = __webpack_require__(52); + var React = __webpack_require__(43); + var DropCaret = __webpack_require__(46); var Title = React.createClass({displayName: "Title", @@ -2003,13 +1882,13 @@ var Grommet = /***/ }, -/* 27 */ +/* 24 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var _ = __webpack_require__(79); - var React = __webpack_require__(48); + var _ = __webpack_require__(54); + var React = __webpack_require__(43); function renderObject (obj) { var attrs = []; @@ -2069,12 +1948,12 @@ var Grommet = /***/ }, -/* 28 */ +/* 25 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var TBD = React.createClass({displayName: "TBD", @@ -2092,12 +1971,12 @@ var Grommet = /***/ }, -/* 29 */ +/* 26 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Clear = React.createClass({displayName: "Clear", @@ -2122,12 +2001,12 @@ var Grommet = /***/ }, -/* 30 */ +/* 27 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var DragHandle = React.createClass({displayName: "DragHandle", @@ -2158,12 +2037,12 @@ var Grommet = /***/ }, -/* 31 */ +/* 28 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Edit = React.createClass({displayName: "Edit", @@ -2197,12 +2076,12 @@ var Grommet = /***/ }, -/* 32 */ +/* 29 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Filter = React.createClass({displayName: "Filter", @@ -2226,12 +2105,12 @@ var Grommet = /***/ }, -/* 33 */ +/* 30 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Help = React.createClass({displayName: "Help", @@ -2257,12 +2136,12 @@ var Grommet = /***/ }, -/* 34 */ +/* 31 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var More = React.createClass({displayName: "More", @@ -2289,12 +2168,12 @@ var Grommet = /***/ }, -/* 35 */ +/* 32 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Next = React.createClass({displayName: "Next", @@ -2319,12 +2198,12 @@ var Grommet = /***/ }, -/* 36 */ +/* 33 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Previous = React.createClass({displayName: "Previous", @@ -2349,12 +2228,12 @@ var Grommet = /***/ }, -/* 37 */ +/* 34 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Search = React.createClass({displayName: "Search", @@ -2379,12 +2258,12 @@ var Grommet = /***/ }, -/* 38 */ +/* 35 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var SearchPlus = React.createClass({displayName: "SearchPlus", @@ -2411,12 +2290,12 @@ var Grommet = /***/ }, -/* 39 */ +/* 36 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var CLASS_ROOT = "icon-spinning"; @@ -2444,18 +2323,18 @@ var Grommet = /***/ }, -/* 40 */ +/* 37 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); - var OK = __webpack_require__(54); - var ErrorStatus = __webpack_require__(55); - var Warning = __webpack_require__(56); - var Disabled = __webpack_require__(57); - var Unknown = __webpack_require__(58); - var Label = __webpack_require__(59); + var React = __webpack_require__(43); + var OK = __webpack_require__(48); + var ErrorStatus = __webpack_require__(49); + var Warning = __webpack_require__(50); + var Disabled = __webpack_require__(51); + var Unknown = __webpack_require__(52); + var Label = __webpack_require__(53); var CLASS_ROOT = "status-icon"; @@ -2511,7 +2390,7 @@ var Grommet = /***/ }, -/* 41 */ +/* 38 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014 Hewlett-Packard Development Company, L.P. @@ -2611,14 +2490,14 @@ var Grommet = /***/ }, -/* 42 */ +/* 39 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. // http://jsfiddle.net/LBAr8/ - var React = __webpack_require__(48); + var React = __webpack_require__(43); var ReactLayeredComponent = { @@ -2652,381 +2531,199 @@ var Grommet = /***/ }, -/* 43 */ +/* 40 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var mirrorkey = __webpack_require__(83); + var Reflux = __webpack_require__(55); + var Rest = __webpack_require__(42); - module.exports = { + var Actions = Reflux.createActions({ + // Session + 'login': {asyncResult: true}, + 'logout': {} + }); - CHANGE_EVENT: 'change', + Actions.login.listen(function(username, password) { + var thisAction = this; + Rest.post('/rest/login-sessions', + {authLoginDomain: 'LOCAL', userName: username, password: password, loginMsgAck: true}) + .end(function(err, res) { + if (err) { + return thisAction.failed(err, res.body); + } + if (!res.ok) { + return thisAction.failed(err, res.body); + } + thisAction.completed(username, res.body.sessionID); + }); + }); - ActionTypes: mirrorkey({ - // remove? - NAV_SETUP: null, - NAV_SEARCH: null, - NAV_SEARCH_SUGGESTIONS_RESULT: null, - NAV_CHANGE: null, - ROUTE_CHANGE: null, + module.exports = Actions; - SESSION_SETUP: null, - SESSION_LOGOUT: null, - SESSION_LOGIN: null - }), - ActionSources: mirrorkey({ - SERVER_ACTION: null, - VIEW_ACTION: null - }), +/***/ }, +/* 41 */ +/***/ function(module, exports, __webpack_require__) { - Request: mirrorkey({ - SUCCESS: null, - TIMEOUT: null, - ERROR: null - }) + // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - }; + var Reflux = __webpack_require__(55); + var Actions = __webpack_require__(40); + var Cookies = __webpack_require__(47); + var TOKEN = "token"; + var USER = "user"; + var LOGIN_TIME = "loginTime"; + var EMAIL = "email"; -/***/ }, -/* 44 */ -/***/ function(module, exports, __webpack_require__) { + var SessionStore = Reflux.createStore({ - // (C) Copyright 2014 Hewlett-Packard Development Company, L.P. + _data: { + id: null, + name: null, + created: null, + email: null, + loginError: null // {message: , resolution: } + }, - var _ = __webpack_require__(79); - var Dispatcher = __webpack_require__(80).Dispatcher; - var Constants = __webpack_require__(43); + init: function () { + this._data.id = Cookies.get(TOKEN); + this._data.name = Cookies.get(USER); + this._data.created = Cookies.get(LOGIN_TIME); + this._data.email = Cookies.get(EMAIL); - var AppDispatcher = _.extend(new Dispatcher(), { + this.listenTo(Actions.login.completed, this._onLoginCompleted); + this.listenTo(Actions.login.failed, this._onLoginFailed); + this.listenTo(Actions.logout, this._onLogout); + }, - handleServerAction: function(action) { - var payload = { - source: Constants.ActionSources.SERVER_ACTION, - action: action - }; - this.dispatch(payload); + _onLoginCompleted: function (username, id) { + this._data.id = id; + this._data.name = username; + this._data.created = new Date(); + this._data.loginError = null; + if (username.indexOf('@') !== -1) { + this._data.email = username; + } + Cookies.set(TOKEN, this._data.id); + Cookies.set(USER, this._data.name); + Cookies.set(LOGIN_TIME, this._data.created); + Cookies.set(EMAIL, this._data.email); + this.trigger(this._data); }, - handleViewAction: function(action) { - var payload = { - source: Constants.ActionSources.VIEW_ACTION, - action: action + _onLoginFailed: function (error, response) { + this._data.loginError = { + message: response.message, + resolution: response.resolution }; - this.dispatch(payload); - } + this.trigger(this._data); + }, - }); - - module.exports = AppDispatcher; - - -/***/ }, -/* 45 */ -/***/ function(module, exports, __webpack_require__) { - - // (C) Copyright 2014 Hewlett-Packard Development Company, L.P. - - var _ = __webpack_require__(79); - var AppDispatcher = __webpack_require__(44); - var EventEmitter = __webpack_require__(81).EventEmitter; - var Constants = __webpack_require__(43); - var Cookies = __webpack_require__(53); - - var TOKEN = "token"; - var USER = "user"; - var LOGIN_TIME = "loginTime"; - var EMAIL = "email"; - - var _data = { - id: null, - name: null, - created: null, - email: null, - loginError: null // {message: , resolution: } - }; - - function setup () { - _data.id = Cookies.get(TOKEN); - _data.name = Cookies.get(USER); - _data.created = Cookies.get(LOGIN_TIME); - _data.email = Cookies.get(EMAIL); - } - - function login(username, id) { - _data.id = id; - _data.name = username; - _data.created = new Date(); - _data.loginError = null; - if (username.indexOf('@') !== -1) { - _data.email = username; - } - Cookies.set(TOKEN, _data.id); - Cookies.set(USER, _data.name); - Cookies.set(LOGIN_TIME, _data.created); - Cookies.set(EMAIL, _data.email); - } - - function setLoginError(message, resolution) { - _data.loginError = { - message: message, - resolution: resolution - }; - } - - function logout() { - _data.id = null; - _data.name = null; - _data.created = null; - Cookies.remove(TOKEN); - Cookies.remove(USER); - Cookies.remove(LOGIN_TIME); - } - - var SessionStore = _.extend({}, EventEmitter.prototype, { - - // public methods used by Controller-View to operate on data - getAll: function() { - return _data; - }, - - // Allow Controller-View to register itself with store - addChangeListener: function(callback) { - this.on(Constants.CHANGE_EVENT, callback); - }, - removeChangeListener: function(callback) { - this.removeListener(Constants.CHANGE_EVENT, callback); + _onLogout: function () { + this._data.id = null; + this._data.name = null; + this._data.created = null; + this._data.email = null; + Cookies.remove(TOKEN); + Cookies.remove(USER); + Cookies.remove(LOGIN_TIME); + Cookies.remove(EMAIL); + this.trigger(this._data); }, - // triggers change listener above, firing controller-view callback - emitChange: function() { - this.emit(Constants.CHANGE_EVENT); - }, - - // register store with dispatcher, allowing actions to flow through - dispatcherIndex: AppDispatcher.register(function(payload) { - var action = payload.action; - - switch(action.type) { - - case Constants.ActionTypes.SESSION_SETUP: - setup(); - SessionStore.emitChange(); - break; - - case Constants.ActionTypes.SESSION_LOGOUT: - logout(); - SessionStore.emitChange(); - break; - - case Constants.ActionTypes.SESSION_LOGIN: - if (Constants.Request.SUCCESS === action.result) { - login(action.context.username, action.response.sessionID); - } else if (Constants.Request.ERROR === action.result) { - setLoginError(action.response.message, action.response.recommendedActions); - } - SessionStore.emitChange(); - break; - - } - }) + getInitialState: function () { + return this._data; + } }); module.exports = SessionStore; /***/ }, -/* 46 */ +/* 42 */ /***/ function(module, exports, __webpack_require__) { - // (C) Copyright 2014 Hewlett-Packard Development Company, L.P. - - // portions leveraged from examples at - // http://www.code-experience.com/async-requests-with-react-js-and-flux-revisited/ - - var _ = __webpack_require__(79); - var AppDispatcher = __webpack_require__(44); - var Constants = __webpack_require__(43); - var SessionStore = __webpack_require__(45); - var request = __webpack_require__(95); - - var VERSION = 200; - var TIMEOUT = 10000; - var PREFIX = ''; - - function token() { - return SessionStore.getAll().id; - } + // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - function dispatch(key, result, response, params, context) { - var payload = {type: key, result: result, response: response}; - if (params) { - payload.queryParams = params; - } - if (context) { - payload.context = context; - } - AppDispatcher.handleServerAction(payload); - } + var request = __webpack_require__(56); - // return successful response, else return request Constants - function responseHandler(key, params, context) { - return function (err, res) { - if (err && err.timeout === TIMEOUT) { - dispatch(key, Constants.Request.TIMEOUT, null, params, context); - } else if (res.status === 400 && - Constants.ActionTypes.LOGOUT !== key && - Constants.ActionTypes.LOGIN !== key) { - dispatch(Constants.ActionTypes.LOGOUT, null, null, params, context); - } else if (!res.ok) { - dispatch(key, Constants.Request.ERROR, res.body, params, context); - } else { - dispatch(key, Constants.Request.SUCCESS, res.body, params, context); - } - }; - } + var _headers = {}; - function deliver(req, key, params, context) { - req.timeout(TIMEOUT); - if (token()) { - req.set('auth', token()); - } - req.set('Accept', 'application/json'); - req.set('X-API-Version', VERSION); - req.end(responseHandler(key, params, context)); - } + var _timeout = 10000; // 10s // convert params to string, to deal with array values function buildQueryParams(params) { var result = []; - _.forOwn(params, function (value, name) { - if (Array.isArray(value)) { - for (var i=0; i 0) { - Api.get(Constants.ActionTypes.NAV_SEARCH_SUGGESTIONS_RESULT, - '/rest/index/resources', - {start: 0, count: 5, userQuery: text}); - } - }, - - routeChange: function (routerState) { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.ROUTE_CHANGE, - routerState: routerState - }); - } - - }; - + module.exports = React; /***/ }, -/* 50 */ +/* 44 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Top = React.createClass({displayName: "Top", @@ -3053,7 +2750,7 @@ var Grommet = /***/ }, -/* 51 */ +/* 45 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014 Hewlett-Packard Development Company, L.P. @@ -3159,12 +2856,12 @@ var Grommet = /***/ }, -/* 52 */ +/* 46 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var DropCaret = React.createClass({displayName: "DropCaret", @@ -3189,7 +2886,7 @@ var Grommet = /***/ }, -/* 53 */ +/* 47 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2015 Hewlett-Packard Development Company, L.P. @@ -3246,7 +2943,7 @@ var Grommet = return true; }, remove: function (sKey, sPath, sDomain) { - if (!this.hasItem(sKey)) { return false; } + if (!this.has(sKey)) { return false; } document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : ""); return true; }, @@ -3265,12 +2962,12 @@ var Grommet = /***/ }, -/* 54 */ +/* 48 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var OK = React.createClass({displayName: "OK", @@ -3297,12 +2994,12 @@ var Grommet = /***/ }, -/* 55 */ +/* 49 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var ErrorStatus = React.createClass({displayName: "ErrorStatus", @@ -3329,12 +3026,12 @@ var Grommet = /***/ }, -/* 56 */ +/* 50 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Warning = React.createClass({displayName: "Warning", @@ -3361,12 +3058,12 @@ var Grommet = /***/ }, -/* 57 */ +/* 51 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Disabled = React.createClass({displayName: "Disabled", @@ -3393,12 +3090,12 @@ var Grommet = /***/ }, -/* 58 */ +/* 52 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Unknown = React.createClass({displayName: "Unknown", @@ -3425,12 +3122,12 @@ var Grommet = /***/ }, -/* 59 */ +/* 53 */ /***/ function(module, exports, __webpack_require__) { // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - var React = __webpack_require__(48); + var React = __webpack_require__(43); var Label = React.createClass({displayName: "Label", @@ -3454,9534 +3151,9638 @@ var Grommet = /***/ }, -/* 60 */ +/* 54 */ /***/ function(module, exports, __webpack_require__) { - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/** + * @license + * lodash 3.8.0 (Custom Build) + * Build: `lodash modern -d -o ./index.js` + * Copyright 2012-2015 The Dojo Foundation + * Based on Underscore.js 1.8.3 + * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + * Available under MIT license + */ + ;(function() { - var Router = __webpack_require__(2); + /** Used as a safe reference for `undefined` in pre-ES5 environments. */ + var undefined; - var _config; + /** Used as the semantic version number. */ + var VERSION = '3.8.0'; - function configForCategory(category) { - var result; - if (Array.isArray(category)) { - category.some(function (singleCategory) { - if (_config[singleCategory]) { - result = _config[singleCategory]; - return true; - } - }); - } else { - result = _config[category]; - } - return result; - } + /** Used to compose bitmasks for wrapper metadata. */ + var BIND_FLAG = 1, + BIND_KEY_FLAG = 2, + CURRY_BOUND_FLAG = 4, + CURRY_FLAG = 8, + CURRY_RIGHT_FLAG = 16, + PARTIAL_FLAG = 32, + PARTIAL_RIGHT_FLAG = 64, + ARY_FLAG = 128, + REARG_FLAG = 256; - module.exports = { + /** Used as default options for `_.trunc`. */ + var DEFAULT_TRUNC_LENGTH = 30, + DEFAULT_TRUNC_OMISSION = '...'; - init: function (config) { - _config = config; - }, + /** Used to detect when a function becomes hot. */ + var HOT_COUNT = 150, + HOT_SPAN = 16; - resourceHref: function (category, uri, query) { - var config = configForCategory(category); - return (config ? Router.makeHref(config.resourceRoute, {splat: uri}, query) : ''); - }, + /** Used to indicate the type of lazy iteratees. */ + var LAZY_DROP_WHILE_FLAG = 0, + LAZY_FILTER_FLAG = 1, + LAZY_MAP_FLAG = 2; - categoryHref: function (category, query) { - var config = configForCategory(category); - return (config ? Router.makeHref(config.route, {}, query) : ''); - }, + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; - categoryRoute: function (category) { - var config = configForCategory(category); - return (config ? config.route : ''); - }, + /** Used as the internal argument placeholder. */ + var PLACEHOLDER = '__lodash_placeholder__'; - resourceRoute: function (category) { - var config = configForCategory(category); - return (config ? config.resourceRoute : ''); - }, + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + arrayTag = '[object Array]', + boolTag = '[object Boolean]', + dateTag = '[object Date]', + errorTag = '[object Error]', + funcTag = '[object Function]', + mapTag = '[object Map]', + numberTag = '[object Number]', + objectTag = '[object Object]', + regexpTag = '[object RegExp]', + setTag = '[object Set]', + stringTag = '[object String]', + weakMapTag = '[object WeakMap]'; - categoryLabel: function (category) { - var config = configForCategory(category); - return (config ? config.label : ''); - } - }; + var arrayBufferTag = '[object ArrayBuffer]', + 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; -/***/ }, -/* 61 */ -/***/ function(module, exports, __webpack_require__) { + /** Used to match HTML entities and HTML characters. */ + var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, + reUnescapedHtml = /[&<>"'`]/g, + reHasEscapedHtml = RegExp(reEscapedHtml.source), + reHasUnescapedHtml = RegExp(reUnescapedHtml.source); - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + /** Used to match template delimiters. */ + var reEscape = /<%-([\s\S]+?)%>/g, + reEvaluate = /<%([\s\S]+?)%>/g, + reInterpolate = /<%=([\s\S]+?)%>/g; - var React = __webpack_require__(48); - var Index = __webpack_require__(69); - var IndexRouter = __webpack_require__(60); - var Link = __webpack_require__(13); + /** Used to match property names within property paths. */ + var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/, + reIsPlainProp = /^\w*$/, + rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; - var Activity = React.createClass({displayName: "Activity", + /** + * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special). + * In addition to special characters the forward slash is escaped to allow for + * easier `eval` use and `Function` compilation. + */ + var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, + reHasRegExpChars = RegExp(reRegExpChars.source); - render: function() { - return ( - React.createElement(Index, {category: ['alerts', 'tasks'], - sort: "created:desc", - hideAttributes: ['associatedResourceUri', 'associatedResourceCategory'], - attributes: [ - {name: 'status', label: 'Status', filter: true}, - {name: 'name', label: 'Name'}, - { - name: 'associatedResourceName', - label: 'Resource', - hasLink: true, - render: function (item) { - var href = IndexRouter.resourceHref( - item.attributes.associatedResourceCategory, - item.attributes.associatedResourceUri); - var content; - if (href) { - content = ( - React.createElement(Link, {href: href}, - item.attributes.associatedResourceName - ) - ); - } else { - content = ( - React.createElement("a", null, item.attributes.associatedResourceName) - ); - } - return content; - } - }, - {name: 'created', label: 'Time'}, - {name: 'state', label: 'State', filter: true} - ]} - ) - ); - } + /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ + var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; - }); + /** Used to match backslashes in property paths. */ + var reEscapeChar = /\\(\\)?/g; - module.exports = Activity; + /** Used to match [ES template delimiters](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components). */ + var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + /** Used to match `RegExp` flags from their coerced string values. */ + var reFlags = /\w*$/; -/***/ }, -/* 62 */ -/***/ function(module, exports, __webpack_require__) { + /** Used to detect hexadecimal string values. */ + var reHasHexPrefix = /^0[xX]/; - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - - var React = __webpack_require__(48); - var Resource = __webpack_require__(71); - - var ActivityResource = React.createClass({displayName: "ActivityResource", + /** Used to detect host constructors (Safari > 5). */ + var reIsHostCtor = /^\[object .+?Constructor\]$/; - render: function() { - return ( - React.createElement(Resource, {category: ['alerts', 'tasks']}) - ); - } + /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ + var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; - }); + /** Used to ensure capturing order of template delimiters. */ + var reNoMatch = /($^)/; - module.exports = ActivityResource; + /** Used to match unescaped characters in compiled string literals. */ + var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + /** Used to match words to create compound words. */ + var reWords = (function() { + var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', + lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; -/***/ }, -/* 63 */ -/***/ function(module, exports, __webpack_require__) { + return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); + }()); - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + /** Used to detect and test for whitespace. */ + var whitespace = ( + // Basic whitespace characters. + ' \t\x0b\f\xa0\ufeff' + - var React = __webpack_require__(48); - var DashboardStore = __webpack_require__(76); - var DashboardActions = __webpack_require__(73); - var IndexActions = __webpack_require__(74); - var IndexAggregate = __webpack_require__(84); - var IndexRouter = __webpack_require__(60); - var Router = __webpack_require__(2); - var EditIcon = __webpack_require__(31); - var Link = __webpack_require__(13); + // Line terminators. + '\n\r\u2028\u2029' + - var Dashboard = React.createClass({displayName: "Dashboard", + // Unicode category "Zs" space separators. + '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' + ); - _onChange: function () { - this.setState(DashboardStore.getAll()); - }, + /** Used to assign default `context` object properties. */ + var contextProps = [ + 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', + 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', + 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', + 'isFinite', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', + 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', + 'window' + ]; - _onSearch: function (searchText, category) { - var route = IndexRouter.categoryRoute(category); - Router.transitionTo(route, {}, {'search': searchText}); - }, + /** Used to make template sourceURLs easier to identify. */ + var templateCounter = -1; - getInitialState: function () { - return DashboardStore.getAll(); - }, + /** 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[dateTag] = typedArrayTags[errorTag] = + typedArrayTags[funcTag] = typedArrayTags[mapTag] = + typedArrayTags[numberTag] = typedArrayTags[objectTag] = + typedArrayTags[regexpTag] = typedArrayTags[setTag] = + typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; - componentWillMount: function () { - DashboardActions.setup(this.props.configuration); - }, + /** Used to identify `toStringTag` values supported by `_.clone`. */ + var cloneableTags = {}; + cloneableTags[argsTag] = cloneableTags[arrayTag] = + cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = + cloneableTags[dateTag] = cloneableTags[float32Tag] = + cloneableTags[float64Tag] = cloneableTags[int8Tag] = + cloneableTags[int16Tag] = cloneableTags[int32Tag] = + cloneableTags[numberTag] = cloneableTags[objectTag] = + cloneableTags[regexpTag] = cloneableTags[stringTag] = + cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = + cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; + cloneableTags[errorTag] = cloneableTags[funcTag] = + cloneableTags[mapTag] = cloneableTags[setTag] = + cloneableTags[weakMapTag] = false; - componentDidMount: function () { - this.state.panels.forEach(function (panel) { - IndexActions.getAggregates(panel.params, [panel.attribute.name], panel.name); - }); - DashboardStore.addChangeListener(this._onChange); - }, + /** Used as an internal `_.debounce` options object by `_.throttle`. */ + var debounceOptions = { + 'leading': false, + 'maxWait': 0, + 'trailing': false + }; - componentWillUnmount: function () { - DashboardStore.removeChangeListener(this._onChange); - }, + /** Used to map latin-1 supplementary letters to basic latin letters. */ + var deburredLetters = { + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss' + }; - render: function () { - var panels = this.state.panels.map(function (panel) { - var href = IndexRouter.categoryHref(panel.params.category); - var title = ( - React.createElement(Link, {href: href}, panel.name) - ); + /** Used to map characters to HTML entities. */ + var htmlEscapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; - return ( - React.createElement("div", {key: panel.name, className: "dashboard__panel"}, - React.createElement(IndexAggregate, {title: title, - category: panel.params.category, - attribute: panel.attribute, - search: panel.params.search, - aggregateResult: panel.aggregateResult, - onSearch: this._onSearch}) - ) - ); - }, this); + /** Used to map HTML entities to characters. */ + var htmlUnescapes = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + ''': "'", + '`': '`' + }; - return ( - React.createElement("div", {className: "dashboard"}, - React.createElement("div", {className: "dashboard__panels"}, - panels - ), - React.createElement("div", {className: "dashboard__edit"}, - React.createElement(Link, {href: Router.makeHref("dashboard-edit")}, - React.createElement(EditIcon, {className: 'dashboard__edit-icon'}) - ) - ) - ) - ); - } + /** Used to determine if values are of the language type `Object`. */ + var objectTypes = { + 'function': true, + 'object': true + }; - }); + /** Used to escape characters for inclusion in compiled string literals. */ + var stringEscapes = { + '\\': '\\', + "'": "'", + '\n': 'n', + '\r': 'r', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; - module.exports = Dashboard; + /** Detect free variable `exports`. */ + var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + /** Detect free variable `module`. */ + var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; -/***/ }, -/* 64 */ -/***/ function(module, exports, __webpack_require__) { + /** Detect free variable `global` from Node.js. */ + var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + /** Detect free variable `self`. */ + var freeSelf = objectTypes[typeof self] && self && self.Object && self; - var React = __webpack_require__(48); - var RouteHandler = __webpack_require__(82).RouteHandler; - var DashboardStore = __webpack_require__(76); - var DashboardActions = __webpack_require__(73); - var Router = __webpack_require__(2); - var Form = __webpack_require__(9); - var IndexAggregate = __webpack_require__(84); - var EditIcon = __webpack_require__(31); - var RemoveIcon = __webpack_require__(29); - var Link = __webpack_require__(13); - - var DashboardEdit = React.createClass({displayName: "DashboardEdit", - - _onChange: function() { - this.setState(DashboardStore.getAll()); - }, + /** Detect free variable `window`. */ + var freeWindow = objectTypes[typeof window] && window && window.Object && window; - _onOk: function (event) { - event.preventDefault(); - DashboardActions.commitChanges(); - Router.transitionTo('dashboard'); - }, + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - _onCancel: function (event) { - event.preventDefault(); - DashboardActions.abandonChanges(); - Router.transitionTo('dashboard'); - }, + /** + * Used as a reference to the global object. + * + * The `this` value is used if it is the global object to avoid Greasemonkey's + * restricted `window` object, otherwise the `window` object is used. + */ + var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; - _onRemove: function (panel) { - DashboardActions.removePanel(panel); - }, + /** + * The base implementation of `compareAscending` which compares values and + * sorts them in ascending order without guaranteeing a stable sort. + * + * @private + * @param {*} value The value to compare to `other`. + * @param {*} other The value to compare to `value`. + * @returns {number} Returns the sort order indicator for `value`. + */ + function baseCompareAscending(value, other) { + if (value !== other) { + var valIsReflexive = value === value, + othIsReflexive = other === other; - _onDragStart: function(event) { - this._dragged = event.currentTarget; - event.dataTransfer.effectAllowed = 'move'; - // Firefox requires calling dataTransfer.setData - // for the drag to properly work - event.dataTransfer.setData("text/html", event.currentTarget); - var rect = this._dragged.getBoundingClientRect(); - this._placeholder = document.createElement("li"); - this._placeholder.className = - "dashboard-edit__panel dashboard-edit__panel--placeholder list-item box"; - this._placeholder.style.width = '' + (rect.right - rect.left) + 'px'; - this._placeholder.style.height = '' + (rect.bottom - rect.top) + 'px'; - }, + if (value > other || !valIsReflexive || (value === undefined && othIsReflexive)) { + return 1; + } + if (value < other || !othIsReflexive || (other === undefined && valIsReflexive)) { + return -1; + } + } + return 0; + } - _onDragEnd: function() { - this._dragged.style.display = "inline-block"; - this._dragged.parentNode.removeChild(this._placeholder); - this._placeholder = null; + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to search. + * @param {Function} predicate The function invoked per iteration. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromRight) { + var length = array.length, + index = fromRight ? length : -1; - // Update state - var pendingPanels = this.state.pendingPanels.slice(0); - var from = Number(this._dragged.dataset.index); - var to = Number(this._over.dataset.index); - if (from < to) { - to -= 1; + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } } - pendingPanels.splice(to, 0, pendingPanels.splice(from, 1)[0]); - DashboardActions.orderPanels(pendingPanels); - }, + return -1; + } - _onDragOver: function(event) { - event.preventDefault(); - this._dragged.style.display = "none"; - if (event.target.className === - "dashboard-edit__panel dashboard-edit__panel--placeholder list-item box") { - return; + /** + * The base implementation of `_.indexOf` without support for binary searches. + * + * @private + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + if (value !== value) { + return indexOfNaN(array, fromIndex); } - this._over = event.target; - event.target.parentNode.insertBefore(this._placeholder, event.target); - }, - - getInitialState: function() { - return DashboardStore.getAll(); - }, + var index = fromIndex - 1, + length = array.length; - componentDidMount: function() { - DashboardActions.startChanging(); + while (++index < length) { + if (array[index] === value) { + return index; + } + } + return -1; + } - DashboardStore.addChangeListener(this._onChange); - }, - - componentWillUnmount: function() { - DashboardStore.removeChangeListener(this._onChange); - }, - - render: function() { - var removeHandler = this._onRemove; - var onDragStart = this._onDragStart; - var onDragEnd = this._onDragEnd; + /** + * The base implementation of `_.isFunction` without support for environments + * with incorrect `typeof` results. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + */ + function baseIsFunction(value) { + // Avoid a Chakra JIT bug in compatibility modes of IE 11. + // See https://github.com/jashkenas/underscore/issues/1621 for more details. + return typeof value == 'function' || false; + } - var panels = []; - if (this.state.pendingPanels) { - panels = this.state.pendingPanels.map(function (panel, index) { - return ( - React.createElement("li", {key: panel.name, "data-index": index, - className: "dashboard-edit__panel list-item box", - draggable: "true", onDragEnd: onDragEnd, onDragStart: onDragStart}, - React.createElement("div", {className: "dashboard-edit__panel-controls"}, - React.createElement(Link, {href: Router.makeHref('dashboard-panel-edit', {index: index}), - className: "dashboard-edit__panel-edit"}, - React.createElement(EditIcon, {className: 'dashboard-edit__panel-edit-icon'}) - ), - React.createElement("div", {className: "dashboard-edit__panel-remove", - onClick: removeHandler.bind(null, panel)}, - React.createElement(RemoveIcon, {className: 'dashboard-edit__panel-remove-icon'}) - ) - ), - React.createElement(IndexAggregate, {title: panel.name, params: panel.params, - attribute: panel.attribute, aggregateResult: panel.aggregateResult}) - ) - ); - }); + /** + * Converts `value` to a string if it is not one. An empty string is returned + * for `null` or `undefined` values. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + if (typeof value == 'string') { + return value; } - - var buttons = ( - React.createElement("div", null, - React.createElement("button", {onClick: this._onOk, className: 'primary'}, "OK"), - React.createElement("button", {onClick: this._onCancel}, "Cancel") - ) - ); - - return ( - React.createElement(Form, {action: 'Edit', resource: 'Dashboard', buttons: buttons}, - React.createElement("div", {className: "dashboard-edit"}, - React.createElement(Link, {href: Router.makeHref('dashboard-panel-add'), - className: "dashboard-edit__add-panel"}, "+ Add panel"), - React.createElement("ol", {className: "dashboard-edit__panels list-inline", - onDragOver: this._onDragOver}, - panels - ), - React.createElement(RouteHandler, null) - ) - ) - ); + return value == null ? '' : (value + ''); } - }); - - module.exports = DashboardEdit; - - -/***/ }, -/* 65 */ -/***/ function(module, exports, __webpack_require__) { + /** + * Used by `_.max` and `_.min` as the default callback for string values. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the code unit of the first character of the string. + */ + function charAtCallback(string) { + return string.charCodeAt(0); + } - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the first character not found in `chars`. + */ + function charsLeftIndex(string, chars) { + var index = -1, + length = string.length; - var React = __webpack_require__(48); - var DashboardStore = __webpack_require__(76); - var DashboardActions = __webpack_require__(73); - var Router = __webpack_require__(2); - var Form = __webpack_require__(9); - var IndexAggregate = __webpack_require__(84); + while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } - var DashboardPanelAdd = React.createClass({displayName: "DashboardPanelAdd", + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last character + * of `string` that is not found in `chars`. + * + * @private + * @param {string} string The string to inspect. + * @param {string} chars The characters to find. + * @returns {number} Returns the index of the last character not found in `chars`. + */ + function charsRightIndex(string, chars) { + var index = string.length; - _onChange: function() { - this.setState({dashboard: DashboardStore.getAll()}); - }, + while (index-- && chars.indexOf(string.charAt(index)) > -1) {} + return index; + } - _onClick: function (index) { - this.setState({selectedIndex: index}); - }, + /** + * Used by `_.sortBy` to compare transformed elements of a collection and stable + * sort them in ascending order. + * + * @private + * @param {Object} object The object to compare to `other`. + * @param {Object} other The object to compare to `object`. + * @returns {number} Returns the sort order indicator for `object`. + */ + function compareAscending(object, other) { + return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); + } - _onAdd: function (event) { - event.preventDefault(); - DashboardActions.addPanel( - this.state.dashboard.availablePanels[this.state.selectedIndex]); - Router.transitionTo('dashboard-edit'); - }, + /** + * Used by `_.sortByOrder` to compare multiple properties of each element + * in a collection and stable sort them in the following order: + * + * If `orders` is unspecified, sort in ascending order for all properties. + * Otherwise, for each property, sort in ascending order if its corresponding value in + * orders is true, and descending order if false. + * + * @private + * @param {Object} object The object to compare to `other`. + * @param {Object} other The object to compare to `object`. + * @param {boolean[]} 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; - _onAddPlus: function (event) { - event.preventDefault(); - DashboardActions.addPanel( - this.state.dashboard.availablePanels[this.state.selectedIndex]); - }, + while (++index < length) { + var result = baseCompareAscending(objCriteria[index], othCriteria[index]); + if (result) { + if (index >= ordersLength) { + return result; + } + return result * (orders[index] ? 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://code.google.com/p/v8/issues/detail?id=90 for more details. + return object.index - other.index; + } - _onCancel: function (event) { - event.preventDefault(); - Router.transitionTo('dashboard-edit'); - }, + /** + * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. + * + * @private + * @param {string} letter The matched letter to deburr. + * @returns {string} Returns the deburred letter. + */ + function deburrLetter(letter) { + return deburredLetters[letter]; + } - getInitialState: function() { - return {selectedIndex: 0, dashboard: DashboardStore.getAll()}; - }, + /** + * Used by `_.escape` to convert characters to HTML entities. + * + * @private + * @param {string} chr The matched character to escape. + * @returns {string} Returns the escaped character. + */ + function escapeHtmlChar(chr) { + return htmlEscapes[chr]; + } - componentDidMount: function() { - DashboardStore.addChangeListener(this._onChange); - }, + /** + * 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]; + } - componentWillUnmount: function() { - DashboardStore.removeChangeListener(this._onChange); - }, + /** + * Gets the index at which the first occurrence of `NaN` is found in `array`. + * + * @private + * @param {Array} array The array to search. + * @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 `NaN`, else `-1`. + */ + function indexOfNaN(array, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 0 : -1); - render: function() { - var clickHandler = this._onClick; - var selectedIndex = this.state.selectedIndex; - var panels = this.state.dashboard.availablePanels.map(function (panel, index) { - var classes = ["dashboard-panel-add__panel", "list-item", "box"]; - if (index === selectedIndex) { - classes.push("dashboard-panel-add__panel--selected"); + while ((fromRight ? index-- : ++index < length)) { + var other = array[index]; + if (other !== other) { + return index; } - return ( - React.createElement("li", {key: panel.name, className: classes.join(' '), - onClick: clickHandler.bind(null, index)}, - React.createElement(IndexAggregate, {title: panel.name, params: panel.params, - attribute: panel.attribute, aggregateResult: panel.aggregateResult}) - ) - ); - }); - - var buttons = ( - React.createElement("div", null, - React.createElement("button", {onClick: this._onAdd, className: 'primary'}, "Add"), - React.createElement("button", {onClick: this._onAddPlus}, "Add +"), - React.createElement("button", {onClick: this._onCancel}, "Cancel") - ) - ); - - return ( - React.createElement(Form, {action: 'Add Panel', resource: 'Dashboard', onSubmit: this._onSubmit, - buttons: buttons}, - React.createElement("div", {className: "dashboard-panel-add"}, - React.createElement("ol", {className: "dashboard-panel-add__panels list-inline"}, - panels - ) - ) - ) - ); + } + return -1; } - }); + /** + * Checks if `value` is object-like. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } - module.exports = DashboardPanelAdd; + /** + * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a + * character code is whitespace. + * + * @private + * @param {number} charCode The character code to inspect. + * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. + */ + function isSpace(charCode) { + return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || + (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); + } + /** + * 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 = -1, + result = []; -/***/ }, -/* 66 */ -/***/ function(module, exports, __webpack_require__) { + while (++index < length) { + if (array[index] === placeholder) { + array[index] = PLACEHOLDER; + result[++resIndex] = index; + } + } + return result; + } - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + /** + * An implementation of `_.uniq` optimized for sorted arrays without support + * for callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function sortedUniq(array, iteratee) { + var seen, + index = -1, + length = array.length, + resIndex = -1, + result = []; - var React = __webpack_require__(48); - var DashboardStore = __webpack_require__(76); - var DashboardActions = __webpack_require__(73); - var State = __webpack_require__(82).State; - var Router = __webpack_require__(2); - var Form = __webpack_require__(9); - var DashboardPanelEditGuided = __webpack_require__(67); - var DashboardPanelEditRaw = __webpack_require__(68); - var IndexAggregate = __webpack_require__(84); + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; - var DashboardPanelEdit = React.createClass({displayName: "DashboardPanelEdit", + if (!index || seen !== computed) { + seen = computed; + result[++resIndex] = value; + } + } + return result; + } - mixins: [State], + /** + * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the first non-whitespace character. + */ + function trimmedLeftIndex(string) { + var index = -1, + length = string.length; - _onChange: function() { - var data = DashboardStore.getAll(); - this.setState({pendingPanel: data.pendingPanel}); - }, + while (++index < length && isSpace(string.charCodeAt(index))) {} + return index; + } - _onOk: function (event) { - event.preventDefault(); - var index = this.getParams().index; - DashboardActions.updatePanel(index); - Router.transitionTo('dashboard-edit'); - }, + /** + * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace + * character of `string`. + * + * @private + * @param {string} string The string to inspect. + * @returns {number} Returns the index of the last non-whitespace character. + */ + function trimmedRightIndex(string) { + var index = string.length; - _onCancel: function (event) { - event.preventDefault(); - Router.transitionTo('dashboard-edit'); - }, + while (index-- && isSpace(string.charCodeAt(index))) {} + return index; + } - _onChangeMode: function() { - var mode = this.refs.mode.getDOMNode().value; - this.setState({mode: mode}); - }, + /** + * Used by `_.unescape` to convert HTML entities to characters. + * + * @private + * @param {string} chr The matched character to unescape. + * @returns {string} Returns the unescaped character. + */ + function unescapeHtmlChar(chr) { + return htmlUnescapes[chr]; + } - getInitialState: function() { - var data = DashboardStore.getAll(); - var index = this.getParams().index; - return { - mode: 'guided', - panel: data.pendingPanels[index] || {}, - pendingPanel: null - }; - }, + /** + * Create a new pristine `lodash` function using the given `context` object. + * + * @static + * @memberOf _ + * @category Utility + * @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 + * + * // using `context` to mock `Date#getTime` use in `_.now` + * var mock = _.runInContext({ + * 'Date': function() { + * return { 'getTime': getTimeMock }; + * } + * }); + * + * // or creating a suped-up `defer` in Node.js + * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; + */ + function runInContext(context) { + // Avoid issues with some ES3 environments that attempt to use values, named + // after built-in constructors like `Object`, for the creation of literals. + // ES5 clears this up by stating that literals must use built-in constructors. + // See https://es5.github.io/#x11.1.5 for more details. + context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; - componentDidMount: function() { - DashboardStore.addChangeListener(this._onChange); - DashboardActions.editPanel(this.state.panel); - }, + /** Native constructor references. */ + var Array = context.Array, + Date = context.Date, + Error = context.Error, + Function = context.Function, + Math = context.Math, + Number = context.Number, + Object = context.Object, + RegExp = context.RegExp, + String = context.String, + TypeError = context.TypeError; - componentWillUnmount: function() { - DashboardStore.removeChangeListener(this._onChange); - }, + /** Used for native method references. */ + var arrayProto = Array.prototype, + objectProto = Object.prototype, + stringProto = String.prototype; - render: function() { - var config = {params: {}}; - if (this.state.pendingPanel) { - config = this.state.pendingPanel.config; - } + /** Used to detect DOM support. */ + var document = (document = context.window) && document.document; - var display = ''; - if (config.name) { - display = ( - React.createElement(IndexAggregate, {title: config.name, params: config.params, - attribute: config.attribute, aggregateResult: config.aggregateResult}) - ); - } + /** Used to resolve the decompiled source of functions. */ + var fnToString = Function.prototype.toString; - var buttons = ( - React.createElement("div", null, - React.createElement("button", {onClick: this._onOk, className: 'primary'}, "OK"), - React.createElement("button", {onClick: this._onCancel}, "Cancel") - ) - ); + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; - var mode = this.state.mode; - var guidedClasses = ["dashboard-panel-edit__guided"]; - var rawClasses = ["dashboard-panel-edit__raw"]; - if ('guided' === mode) { - guidedClasses.push("dashboard-panel-edit__guided--active"); - } else { - rawClasses.push("dashboard-panel-edit__raw--active"); - } + /** Used to generate unique IDs. */ + var idCounter = 0; - return ( - React.createElement(Form, {action: 'Edit', resource: config.name, buttons: buttons}, - React.createElement("div", {className: "dashboard-panel-edit"}, - React.createElement("div", {className: "dashboard-panel-edit__config"}, - React.createElement("select", {ref: "mode", className: "dashboard-panel-edit__mode-selector", - onChange: this._onChangeMode, value: mode}, - React.createElement("option", null, "guided"), - React.createElement("option", null, "raw") - ), + /** + * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) + * of values. + */ + var objToString = objectProto.toString; - React.createElement("div", {className: guidedClasses.join(' ')}, - React.createElement(DashboardPanelEditGuided, {pendingPanel: this.state.pendingPanel}) - ), - React.createElement("div", {className: rawClasses.join(' ')}, - React.createElement(DashboardPanelEditRaw, {pendingPanel: this.state.pendingPanel}) - ) + /** Used to restore the original `_` reference in `_.noConflict`. */ + var oldDash = context._; - ), - React.createElement("div", {className: "dashboard-panel-edit__display"}, - display - ) - ) - ) + /** Used to detect if a method is native. */ + var reIsNative = RegExp('^' + + escapeRegExp(objToString) + .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' ); - } - }); + /** Native method references. */ + var ArrayBuffer = isNative(ArrayBuffer = context.ArrayBuffer) && ArrayBuffer, + bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice, + ceil = Math.ceil, + clearTimeout = context.clearTimeout, + floor = Math.floor, + getOwnPropertySymbols = isNative(getOwnPropertySymbols = Object.getOwnPropertySymbols) && getOwnPropertySymbols, + getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, + push = arrayProto.push, + preventExtensions = isNative(preventExtensions = Object.preventExtensions) && preventExtensions, + propertyIsEnumerable = objectProto.propertyIsEnumerable, + Set = isNative(Set = context.Set) && Set, + setTimeout = context.setTimeout, + splice = arrayProto.splice, + Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array, + WeakMap = isNative(WeakMap = context.WeakMap) && WeakMap; - module.exports = DashboardPanelEdit; + /** Used to clone array buffers. */ + var Float64Array = (function() { + // Safari 5 errors when using an array buffer to initialize a typed array + // where the array buffer's `byteLength` is not a multiple of the typed + // array's `BYTES_PER_ELEMENT`. + try { + var func = isNative(func = context.Float64Array) && func, + result = new func(new ArrayBuffer(10), 0, 1) && func; + } catch(e) {} + return result; + }()); + /** Used as `baseAssign`. */ + var nativeAssign = (function() { + // Avoid `Object.assign` in Firefox 34-37 which have an early implementation + // with a now defunct try/catch behavior. See https://bugzilla.mozilla.org/show_bug.cgi?id=1103344 + // for more details. + // + // Use `Object.preventExtensions` on a plain object instead of simply using + // `Object('x')` because Chrome and IE fail to throw an error when attempting + // to assign values to readonly indexes of strings. + var func = preventExtensions && isNative(func = Object.assign) && func; + try { + if (func) { + var object = preventExtensions({ '1': 0 }); + object[0] = 1; + } + } catch(e) { + // Only attempt in strict mode. + try { func(object, 'xo'); } catch(e) {} + return !object[1] && func; + } + return false; + }()); -/***/ }, -/* 67 */ -/***/ function(module, exports, __webpack_require__) { + /* Native method references for those with the same name as other `lodash` methods. */ + var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, + nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, + nativeIsFinite = context.isFinite, + nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, + nativeMax = Math.max, + nativeMin = Math.min, + nativeNow = isNative(nativeNow = Date.now) && nativeNow, + nativeNumIsFinite = isNative(nativeNumIsFinite = Number.isFinite) && nativeNumIsFinite, + nativeParseInt = context.parseInt, + nativeRandom = Math.random; - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + /** Used as references for `-Infinity` and `Infinity`. */ + var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, + POSITIVE_INFINITY = Number.POSITIVE_INFINITY; - var React = __webpack_require__(48); - var DashboardStore = __webpack_require__(76); - var DashboardActions = __webpack_require__(73); + /** Used as references for the maximum length and index of an array. */ + var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, + MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, + HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; - var DashboardPanelEditGuided = React.createClass({displayName: "DashboardPanelEditGuided", + /** Used as the size, in bytes, of each `Float64Array` element. */ + var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; - _onChange: function () { - var panel = { - name: this.refs.name.getDOMNode().value, - params: { - category: this.refs.category.getDOMNode().value, - search: this.refs.search.getDOMNode().value - }, - attribute: this.refs.attribute.getDOMNode().value, - }; - DashboardActions.editPanel(panel); - }, + /** + * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) + * of an array-like value. + */ + var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; - getInitialState: function() { - var data = DashboardStore.getAll(); - return({categories: data.categories}); - }, + /** Used to store function metadata. */ + var metaMap = WeakMap && new WeakMap; - render: function() { - var config = {params: {}}; - if (this.props.pendingPanel) { - config = this.props.pendingPanel.config; - } - - var options = this.state.categories.map(function (category) { - return ( - React.createElement("option", null, category) - ); - }); + /** Used to lookup unminified function names. */ + var realNames = {}; - var search = ''; - if (config.params.search) { - search = config.params.search.fullText; + /** + * Creates a `lodash` object which wraps `value` to enable implicit chaining. + * Methods that operate on and return arrays, collections, and functions can + * be chained together. Methods that return a boolean or single value will + * automatically end the chain returning the unwrapped value. Explicit chaining + * may be enabled using `_.chain`. The execution of chained methods is lazy, + * that is, execution is deferred until `_#value` is implicitly or explicitly + * called. + * + * Lazy evaluation allows several methods to support shortcut fusion. Shortcut + * fusion is an optimization that merges iteratees to avoid creating intermediate + * arrays and reduce the number of iteratee executions. + * + * 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`, `reverse`, `shift`, `slice`, `sort`, + * `splice`, and `unshift` + * + * The wrapper `String` methods are: + * `replace` and `split` + * + * The wrapper methods that support shortcut fusion are: + * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, + * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, + * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, + * and `where` + * + * The chainable wrapper methods are: + * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, + * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, + * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, + * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, + * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, + * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, + * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, + * `keysIn`, `map`, `mapValues`, `matches`, `matchesProperty`, `memoize`, + * `merge`, `mixin`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, + * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, + * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `reverse`, + * `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, + * `spread`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, + * `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, `transform`, + * `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, `where`, + * `without`, `wrap`, `xor`, `zip`, and `zipObject` + * + * The wrapper methods that are **not** chainable by default are: + * `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, + * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, + * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, + * `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, `isArray`, + * `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite` + * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, + * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, + * `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`, `noConflict`, + * `noop`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, + * `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, `shift`, `size`, + * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, `startsWith`, + * `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, `unescape`, + * `uniqueId`, `value`, and `words` + * + * The wrapper method `sample` will return a wrapped value when `n` is provided, + * otherwise an unwrapped value is returned. + * + * @name _ + * @constructor + * @category Chain + * @param {*} value The value to wrap in a `lodash` instance. + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var wrapped = _([1, 2, 3]); + * + * // returns an unwrapped value + * wrapped.reduce(function(total, n) { + * return total + n; + * }); + * // => 6 + * + * // returns a wrapped value + * var squares = wrapped.map(function(n) { + * return n * n; + * }); + * + * _.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, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { + return wrapperClone(value); + } + } + return new LodashWrapper(value); } - return ( - React.createElement("fieldset", {className: 'dashboard-panel-edit-guided form__fields'}, - React.createElement("div", {className: 'form__field'}, - React.createElement("label", {htmlFor: 'name'}, "Name"), - React.createElement("input", {ref: 'name', id: 'name', value: config.name, - onChange: this._onChange}) - ), - React.createElement("div", {className: 'form__field'}, - React.createElement("label", {htmlFor: 'category'}, "Category"), - React.createElement("select", {ref: 'category', id: 'category', - value: config.params.category, - onChange: this._onChange}, - options - ) - ), - React.createElement("div", {className: 'form__field'}, - React.createElement("label", {htmlFor: 'search'}, "Filter"), - React.createElement("textarea", {ref: 'search', id: 'search', value: search, - onChange: this._onChange}) - ), - React.createElement("div", {className: 'form__field'}, - React.createElement("label", {htmlFor: 'attribute'}, "Attribute"), - React.createElement("select", {ref: 'attribute', id: 'attribute', - onChange: this._onChange}, - React.createElement("option", null, config.attribute) - ) - ) - ) - ); - } - - }); - - module.exports = DashboardPanelEditGuided; + /** + * The function whose prototype all chaining 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 chaining for all wrapper methods. + * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. + */ + function LodashWrapper(value, chainAll, actions) { + this.__wrapped__ = value; + this.__actions__ = actions || []; + this.__chain__ = !!chainAll; + } -/***/ }, -/* 68 */ -/***/ function(module, exports, __webpack_require__) { + /** + * An object environment feature flags. + * + * @static + * @memberOf _ + * @type Object + */ + var support = lodash.support = {}; - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + (function(x) { + var Ctor = function() { this.x = x; }, + args = arguments, + object = { '0': x, 'length': x }, + props = []; - var React = __webpack_require__(48); - var DashboardActions = __webpack_require__(73); + Ctor.prototype = { 'valueOf': x, 'y': x }; + for (var key in new Ctor) { props.push(key); } - var DashboardPanelEditRaw = React.createClass({displayName: "DashboardPanelEditRaw", + /** + * Detect if functions can be decompiled by `Function#toString` + * (all but Firefox OS certified apps, older Opera mobile browsers, and + * the PlayStation 3; forced `false` for Windows 8 apps). + * + * @memberOf _.support + * @type boolean + */ + support.funcDecomp = /\bthis\b/.test(function() { return this; }); - _onChange: function (event) { - var text = event.target.value; - DashboardActions.editPanel(text); - }, + /** + * Detect if `Function#name` is supported (all but IE). + * + * @memberOf _.support + * @type boolean + */ + support.funcNames = typeof Function.name == 'string'; - render: function() { - var text = ''; - var error = ''; - if (this.props.pendingPanel) { - text = this.props.pendingPanel.text; - error = this.props.pendingPanel.error; - } - return ( - React.createElement("div", {className: "dashboard-panel-edit-raw"}, - React.createElement("textarea", {onChange: this._onChange, - value: text}), - React.createElement("div", {className: "dashboard-panel-edit-raw__error"}, - error - ) - ) - ); - } + /** + * Detect if the DOM is supported. + * + * @memberOf _.support + * @type boolean + */ + try { + support.dom = document.createDocumentFragment().nodeType === 11; + } catch(e) { + support.dom = false; + } - }); + /** + * Detect if `arguments` object indexes are non-enumerable. + * + * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object + * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat + * `arguments` object indexes as non-enumerable and fail `hasOwnProperty` + * checks for indexes that exceed the number of function parameters and + * whose associated argument values are `0`. + * + * @memberOf _.support + * @type boolean + */ + try { + support.nonEnumArgs = !propertyIsEnumerable.call(args, 1); + } catch(e) { + support.nonEnumArgs = true; + } + }(1, 0)); - module.exports = DashboardPanelEditRaw; + /** + * By default, the template delimiters used by lodash are like those in + * embedded Ruby (ERB). Change the following template settings to use + * alternative delimiters. + * + * @static + * @memberOf _ + * @type Object + */ + lodash.templateSettings = { + /** + * Used to detect `data` property values to be HTML-escaped. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'escape': reEscape, -/***/ }, -/* 69 */ -/***/ function(module, exports, __webpack_require__) { + /** + * Used to detect code to be evaluated. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'evaluate': reEvaluate, - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + /** + * Used to detect `data` property values to inject. + * + * @memberOf _.templateSettings + * @type RegExp + */ + 'interpolate': reInterpolate, - var React = __webpack_require__(48); - var NavStore = __webpack_require__(85); - var Router = __webpack_require__(2); - var IndexRouter = __webpack_require__(60); - var IndexStore = __webpack_require__(77); - var IndexActions = __webpack_require__(74); - var IndexHeader = __webpack_require__(86); - var IndexResults = __webpack_require__(87); - var IndexFilter = __webpack_require__(88); - var IndexResource = __webpack_require__(89); - var Search = __webpack_require__(90); + /** + * Used to reference the data object in the template text. + * + * @memberOf _.templateSettings + * @type string + */ + 'variable': '', - var CLASS_ROOT = 'index'; - - var Index = React.createClass({displayName: "Index", + /** + * Used to import variables into the compiled template. + * + * @memberOf _.templateSettings + * @type Object + */ + 'imports': { - contextTypes: { - router: React.PropTypes.func.isRequired - }, + /** + * A reference to the `lodash` function. + * + * @memberOf _.templateSettings.imports + * @type Function + */ + '_': lodash + } + }; - _mobileScroll: function () { - // if we are narrow, scroll down to hide app header above - var indexElement = this.refs.index.getDOMNode(); - var rect = indexElement.getBoundingClientRect(); - if (window.innerWidth < 720 && rect.top > 0) { - setTimeout(function () { - window.scrollTo(0, rect.top); - }, 100); + /** + * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * + * @private + * @param {*} value The value to wrap. + */ + function LazyWrapper(value) { + this.__wrapped__ = value; + this.__actions__ = null; + this.__dir__ = 1; + this.__dropCount__ = 0; + this.__filtered__ = false; + this.__iteratees__ = null; + this.__takeCount__ = POSITIVE_INFINITY; + this.__views__ = null; } - }, - - _search: function (searchText, resourceUri) { - var index = IndexStore.getAll(); - IndexActions.search(Search.create(searchText || ''), resourceUri, index); - }, - _onIndexChange: function () { - var index = IndexStore.getAll(); - this.setState({index: index}); - }, + /** + * Creates a clone of the lazy wrapper object. + * + * @private + * @name clone + * @memberOf LazyWrapper + * @returns {Object} Returns the cloned `LazyWrapper` object. + */ + function lazyClone() { + var actions = this.__actions__, + iteratees = this.__iteratees__, + views = this.__views__, + result = new LazyWrapper(this.__wrapped__); - _onNavChange: function () { - // TODO: Does Index know too much about route configuration here? - var resourceActive = Router.isActive(this.state.resourceRoute); - var resourceUri = null; - if (resourceActive) { - resourceUri = Router.param('splat'); - this.setState({ - resourceActive: resourceActive, - resourceUri: resourceUri, - filterActive: false}); - } else { - this.setState({resourceActive: false, resourceUri: null}); + result.__actions__ = actions ? arrayCopy(actions) : null; + result.__dir__ = this.__dir__; + result.__filtered__ = this.__filtered__; + result.__iteratees__ = iteratees ? arrayCopy(iteratees) : null; + result.__takeCount__ = this.__takeCount__; + result.__views__ = views ? arrayCopy(views) : null; + return result; } - // delay to avoid nested dispatches - clearTimeout(this._navTimer); - var searchText = Router.queryParam('search') || ''; - if (searchText !== this.state.index.params.search.fullText) { - this._navTimer = setTimeout(this._search. - bind(null, searchText, resourceUri), 10); + /** + * 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; } - this._mobileScroll(); - }, - - _onSearch: function (searchText) { - Router.replaceQueryParam('search', searchText); - // causes: _onNavChange -> _search -> _onIndexChange - }, - - _onOpenFilter: function () { - this.setState({filterActive: true, resourceActive: false}); - }, - - _onCloseFilter: function () { - this.setState({filterActive: false}); - }, - - _onCloseResource: function () { - var categoryRoute = IndexRouter.categoryRoute(this.props.category); - Router.transitionTo(categoryRoute, {}, Router.queryParams()); - }, - - getInitialState: function () { - this._navTimer = null; - var resourceRoute = IndexRouter.resourceRoute(this.props.category); + /** + * 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(); + if (!isArray(array)) { + return baseWrapperValue(array, this.__actions__); + } + var dir = this.__dir__, + isRight = dir < 0, + view = getView(0, array.length, this.__views__), + start = view.start, + end = view.end, + length = end - start, + index = isRight ? end : (start - 1), + takeCount = nativeMin(length, this.__takeCount__), + iteratees = this.__iteratees__, + iterLength = iteratees ? iteratees.length : 0, + resIndex = 0, + result = []; - return { - filterActive: false, - resourceRoute: resourceRoute, - resourceActive: Router.isActive(resourceRoute), - resourceUri: Router.param('splat'), - index: IndexStore.getAll() - }; - }, + outer: + while (length-- && resIndex < takeCount) { + index += dir; - componentWillMount: function () { - IndexActions.setContext({ - category: this.props.category, - view: this.props.view, - searchMode: this.props.searchMode || 'filters', - attributes: this.props.attributes - }); - }, + var iterIndex = -1, + value = array[index]; - componentDidMount: function () { - // get data - this._search(Router.queryParam('search'), this.state.resourceUri); + while (++iterIndex < iterLength) { + var data = iteratees[iterIndex], + iteratee = data.iteratee, + type = data.type; - IndexStore.addChangeListener(this._onIndexChange); - NavStore.addChangeListener(this._onNavChange); + if (type == LAZY_DROP_WHILE_FLAG) { + if (data.done && (isRight ? (index > data.index) : (index < data.index))) { + data.count = 0; + data.done = false; + } + data.index = index; + if (!data.done) { + var limit = data.limit; + if (!(data.done = limit > -1 ? (data.count++ >= limit) : !iteratee(value))) { + continue outer; + } + } + } else { + var 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; + } - this._mobileScroll(); - }, + /** + * Creates a cache object to store key/value pairs. + * + * @private + * @static + * @name Cache + * @memberOf _.memoize + */ + function MapCache() { + this.__data__ = {}; + } - componentWillUnmount: function () { - clearTimeout(this._navTimer); - IndexStore.removeChangeListener(this._onIndexChange); - NavStore.removeChangeListener(this._onNavChange); - }, + /** + * Removes `key` and its value from the cache. + * + * @private + * @name delete + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to remove. + * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + */ + function mapDelete(key) { + return this.has(key) && delete this.__data__[key]; + } - render: function () { - var classes = [CLASS_ROOT]; - var filterClasses = [CLASS_ROOT + "__filter"]; - var resourceClasses = [CLASS_ROOT + "__resource"]; + /** + * Gets the cached value for `key`. + * + * @private + * @name get + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to get. + * @returns {*} Returns the cached value. + */ + function mapGet(key) { + return key == '__proto__' ? undefined : this.__data__[key]; + } - if (this.state.filterActive) { - classes.push(CLASS_ROOT + "--shared"); - filterClasses.push(CLASS_ROOT + "__filter--active"); + /** + * Checks if a cached value for `key` exists. + * + * @private + * @name has + * @memberOf _.memoize.Cache + * @param {string} key The key of the entry to check. + * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + */ + function mapHas(key) { + return key != '__proto__' && hasOwnProperty.call(this.__data__, key); } - if (this.state.resourceActive) { - classes.push(CLASS_ROOT + "--shared"); - resourceClasses.push(CLASS_ROOT + "__resource--active"); + /** + * Sets `value` to `key` of the cache. + * + * @private + * @name set + * @memberOf _.memoize.Cache + * @param {string} key The key of the value to cache. + * @param {*} value The value to cache. + * @returns {Object} Returns the cache object. + */ + function mapSet(key, value) { + if (key != '__proto__') { + this.__data__[key] = value; + } + return this; } - return ( - React.createElement("div", {ref: "index", className: classes.join(' ')}, - React.createElement(IndexFilter, {className: filterClasses.join(' '), - category: this.props.category, - search: this.state.index.params.search, - attributes: this.state.index.attributes, - active: this.state.filterActive, - onSearch: this._onSearch, - onClose: this._onCloseFilter}), - - React.createElement("div", {className: CLASS_ROOT + "__content"}, - React.createElement(IndexHeader, {className: CLASS_ROOT + "__header", - category: this.props.category, - index: this.state.index, - title: IndexRouter.categoryLabel(this.props.category), - onSearch: this._onSearch, - onOpenFilter: this._onOpenFilter, - filterActive: this.state.filterActive, - addRoute: this.props.addRoute}), - React.createElement(IndexResults, {className: CLASS_ROOT + "__results", - category: this.props.category, - index: this.state.index, - resourceActive: this.state.resourceActive, - onSearch: this._onSearch}) - ), + /** + * + * Creates a cache object to store unique values. + * + * @private + * @param {Array} [values] The values to cache. + */ + function SetCache(values) { + var length = values ? values.length : 0; - React.createElement(IndexResource, {className: resourceClasses.join(' '), - category: this.props.category, - index: this.state.index, - uri: this.state.resourceUri, - onClose: this._onCloseResource}) - ) - ); - } + this.data = { 'hash': nativeCreate(null), 'set': new Set }; + while (length--) { + this.push(values[length]); + } + } - }); + /** + * Checks if `value` is in `cache` mimicking the return signature of + * `_.indexOf` by returning `0` if the value is found, else `-1`. + * + * @private + * @param {Object} cache The cache to search. + * @param {*} value The value to search for. + * @returns {number} Returns `0` if `value` is found, else `-1`. + */ + function cacheIndexOf(cache, value) { + var data = cache.data, + result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; - module.exports = Index; + return result ? 0 : -1; + } + /** + * Adds `value` to the cache. + * + * @private + * @name push + * @memberOf SetCache + * @param {*} value The value to cache. + */ + function cachePush(value) { + var data = this.data; + if (typeof value == 'string' || isObject(value)) { + data.set.add(value); + } else { + data.hash[value] = true; + } + } -/***/ }, -/* 70 */ -/***/ function(module, exports, __webpack_require__) { + /** + * 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 arrayCopy(source, array) { + var index = -1, + length = source.length; - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + array || (array = Array(length)); + while (++index < length) { + array[index] = source[index]; + } + return array; + } - var React = __webpack_require__(48); - var IndexStore = __webpack_require__(77); - var IndexActions = __webpack_require__(74); - var State = __webpack_require__(82).State; - var Router = __webpack_require__(2); - var IndexRouter = __webpack_require__(60); - var Form = __webpack_require__(9); + /** + * A specialized version of `_.forEach` for arrays without support for callback + * shorthands and `this` binding. + * + * @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.length; - var CLASS_ROOT = 'index-edit'; + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } + } + return array; + } - var IndexEdit = React.createClass({displayName: "IndexEdit", + /** + * A specialized version of `_.forEachRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @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.length; - mixins: [State], + while (length--) { + if (iteratee(array[length], length, array) === false) { + break; + } + } + return array; + } - _onChange: function() { - this.setState(IndexStore.getAll()); - }, + /** + * A specialized version of `_.every` for arrays without support for callback + * shorthands and `this` binding. + * + * @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.length; - _done: function () { - var queryArgs = {}; - var searchText = this.state.params.search.fullText; - if (searchText) { - queryArgs.search = searchText; + while (++index < length) { + if (!predicate(array[index], index, array)) { + return false; + } + } + return true; } - Router.transitionTo(IndexRouter.categoryRoute(this.getParams().category), - {}, queryArgs); - }, - _onOk: function (event) { - event.preventDefault(); - IndexActions.commitChanges(); - this._done(); - }, + /** + * A specialized version of `_.filter` for arrays without support for callback + * shorthands and `this` binding. + * + * @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.length, + resIndex = -1, + result = []; - _onCancel: function (event) { - event.preventDefault(); - IndexActions.abandonChanges(); - this._done(); - }, + while (++index < length) { + var value = array[index]; + if (predicate(value, index, array)) { + result[++resIndex] = value; + } + } + return result; + } - _onChangeView: function (view) { - IndexActions.setView(view); - }, + /** + * A specialized version of `_.map` for arrays without support for callback + * shorthands and `this` binding. + * + * @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.length, + result = Array(length); - _onChangeSearch: function (searchMode) { - IndexActions.setSearchMode(searchMode); - }, + while (++index < length) { + result[index] = iteratee(array[index], index, array); + } + return result; + } - _onAttributeToggleVisible: function (attribute) { - attribute.visible = ! attribute.visible; - IndexActions.updateAttribute(attribute); - }, + /** + * A specialized version of `_.max` for arrays without support for iteratees. + * + * @private + * @param {Array} array The array to iterate over. + * @returns {*} Returns the maximum value. + */ + function arrayMax(array) { + var index = -1, + length = array.length, + result = NEGATIVE_INFINITY; - _onAttributeToggleAggregate: function (attribute) { - attribute.aggregate = ! attribute.aggregate; - IndexActions.updateAttribute(attribute); - }, + while (++index < length) { + var value = array[index]; + if (value > result) { + result = value; + } + } + return result; + } - _onAttributeToggleFilter: function (attribute) { - attribute.filter = ! attribute.filter; - IndexActions.updateAttribute(attribute); - }, + /** + * A specialized version of `_.min` for arrays without support for iteratees. + * + * @private + * @param {Array} array The array to iterate over. + * @returns {*} Returns the minimum value. + */ + function arrayMin(array) { + var index = -1, + length = array.length, + result = POSITIVE_INFINITY; - _onDragStart: function(event) { - this._dragged = event.currentTarget; - event.dataTransfer.effectAllowed = 'move'; - // Firefox requires calling dataTransfer.setData - // for the drag to properly work - event.dataTransfer.setData("text/html", event.currentTarget); - var rect = this._dragged.getBoundingClientRect(); - this._placeholder = document.createElement("li"); - this._placeholder.className = - CLASS_ROOT + "__attribute " + CLASS_ROOT + "__attribute--placeholder list-item"; - this._placeholder.style.width = '' + (rect.right - rect.left) + 'px'; - this._placeholder.style.height = '' + (rect.bottom - rect.top) + 'px'; - }, + while (++index < length) { + var value = array[index]; + if (value < result) { + result = value; + } + } + return result; + } - _onDragEnd: function() { - this._dragged.style.display = "block"; - this._dragged.parentNode.removeChild(this._placeholder); - this._placeholder = null; + /** + * A specialized version of `_.reduce` for arrays without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the first element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduce(array, iteratee, accumulator, initFromArray) { + var index = -1, + length = array.length; - var from = Number(this._dragged.dataset.index); - var to = Number(this._over.dataset.index); - if (from < to) { - to -= 1; + if (initFromArray && length) { + accumulator = array[++index]; + } + while (++index < length) { + accumulator = iteratee(accumulator, array[index], index, array); + } + return accumulator; } - IndexActions.moveAttribute(from, to); - }, - _onDragOver: function(event) { - event.preventDefault(); - this._dragged.style.display = "none"; - if (event.target.className === - CLASS_ROOT + "__attribute " + CLASS_ROOT + "__attribute--placeholder list-item") { - return; + /** + * A specialized version of `_.reduceRight` for arrays without support for + * callback shorthands and `this` binding. + * + * @private + * @param {Array} array The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {boolean} [initFromArray] Specify using the last element of `array` + * as the initial value. + * @returns {*} Returns the accumulated value. + */ + function arrayReduceRight(array, iteratee, accumulator, initFromArray) { + var length = array.length; + if (initFromArray && length) { + accumulator = array[--length]; + } + while (length--) { + accumulator = iteratee(accumulator, array[length], length, array); + } + return accumulator; } - this._over = event.target; - event.target.parentNode.insertBefore(this._placeholder, event.target); - }, - - getInitialState: function() { - return IndexStore.getAll(); - }, - /*componentWillMount: function () { - IndexActions.setContext({ - category: this.getParams().category - }); - },*/ + /** + * A specialized version of `_.some` for arrays without support for callback + * shorthands and `this` binding. + * + * @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.length; - componentDidMount: function() { - IndexStore.addChangeListener(this._onChange); - IndexActions.startChanging(); - }, + while (++index < length) { + if (predicate(array[index], index, array)) { + return true; + } + } + return false; + } - componentWillUnmount: function() { - IndexStore.removeChangeListener(this._onChange); - }, - - render: function() { - - var buttons = ( - React.createElement("div", null, - React.createElement("button", {onClick: this._onOk, className: 'primary'}, "OK"), - React.createElement("button", {onClick: this._onCancel}, "Cancel") - ) - ); + /** + * A specialized version of `_.sum` for arrays without support for iteratees. + * + * @private + * @param {Array} array The array to iterate over. + * @returns {number} Returns the sum. + */ + function arraySum(array) { + var length = array.length, + result = 0; - var view = ''; - var searchMode = ''; - var attributes = []; - if (this.state.pendingChanges) { - view = this.state.pendingChanges.view; - searchMode = this.state.pendingChanges.searchMode; - attributes = this.state.pendingChanges.attributes; + while (length--) { + result += +array[length] || 0; + } + return result; } - /**var attributes = attributes.map(function (attribute, index) { - var id = 'a-' + index; - return ( -
  • - - - {attribute.label} - - - - -
  • - ); - }, this);**/ - - return ( - React.createElement(Form, {action: 'Edit', - resource: IndexRouter.categoryLabel(this.getParams().category), - buttons: buttons}, - React.createElement("div", {className: CLASS_ROOT}, - React.createElement("fieldset", {className: 'form__fields'}, - React.createElement("div", {className: 'form__field'}, - React.createElement("label", null, "View"), - React.createElement("label", {className: 'radiobutton', htmlFor: 'view__table'}, - React.createElement("input", {id: "view__table", type: "radio", name: "view", value: "table", - checked: 'table' === view, - onChange: this._onChangeView.bind(null, 'table')}), - "table" - ), - React.createElement("label", {className: 'radiobutton', htmlFor: 'view__tiles'}, - React.createElement("input", {id: "view__tiles", type: "radio", name: "view", value: "tiles", - checked: 'tiles' === view, - onChange: this._onChangeView.bind(null, 'tiles')}), - "tiles" - ) - ), - React.createElement("div", {className: 'form__field'}, - React.createElement("label", null, "Search"), - React.createElement("label", {className: 'radiobutton', htmlFor: 'search__filters'}, - React.createElement("input", {id: "search__filters", type: "radio", name: "searchMode", value: "filters", - checked: 'filters' === searchMode, - onChange: this._onChangeSearch.bind(null, 'filters')}), - "filters" - ), - React.createElement("label", {className: 'radiobutton', htmlFor: 'search__facets'}, - React.createElement("input", {id: "search__facets", type: "radio", name: "searchMode", value: "facets", - checked: 'facets' === searchMode, - onChange: this._onChangeSearch.bind(null, 'facets')}), - "facets" - ) - ), - React.createElement("div", {className: 'form__field'}, - React.createElement("label", null, "Attributes"), - React.createElement("ol", {className: CLASS_ROOT + "__attributes list-block list-block--small", - onDragOver: this._onDragOver}, - attributes - ) - ) - ) - ) - ) - ); - } - - }); - - module.exports = IndexEdit; + /** + * Used by `_.defaults` to customize its `_.assign` use. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignDefaults(objectValue, sourceValue) { + return objectValue === undefined ? sourceValue : objectValue; + } + /** + * Used by `_.template` to customize its `_.assign` use. + * + * **Note:** This function is like `assignDefaults` except that it ignores + * inherited property values when checking if a property is `undefined`. + * + * @private + * @param {*} objectValue The destination object property value. + * @param {*} sourceValue The source object property value. + * @param {string} key The key associated with the object and source values. + * @param {Object} object The destination object. + * @returns {*} Returns the value to assign to the destination object. + */ + function assignOwnDefaults(objectValue, sourceValue, key, object) { + return (objectValue === undefined || !hasOwnProperty.call(object, key)) + ? sourceValue + : objectValue; + } -/***/ }, -/* 71 */ -/***/ function(module, exports, __webpack_require__) { + /** + * A specialized version of `_.assign` for customizing assigned values without + * support for argument juggling, multiple sources, and `this` binding `customizer` + * functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @param {Function} customizer The function to customize assigned values. + * @returns {Object} Returns `object`. + */ + function assignWith(object, source, customizer) { + var props = keys(source); + push.apply(props, getSymbols(source)); - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. + var index = -1, + length = props.length; - var React = __webpack_require__(48); - var ResourceStore = __webpack_require__(78); - var NavStore = __webpack_require__(85); - var Router = __webpack_require__(2); - var ResourceActions = __webpack_require__(75); - var ResourceHeader = __webpack_require__(91); - var ResourceActivity = __webpack_require__(92); - var ResourceMap = __webpack_require__(93); + while (++index < length) { + var key = props[index], + value = object[key], + result = customizer(value, source[key], key, object, source); - var CLASS_ROOT = 'resource'; + if ((result === result ? (result !== value) : (value === value)) || + (value === undefined && !(key in object))) { + object[key] = result; + } + } + return object; + } - var Resource = React.createClass({displayName: "Resource", + /** + * The base implementation of `_.assign` without support for argument juggling, + * multiple sources, and `customizer` functions. + * + * @private + * @param {Object} object The destination object. + * @param {Object} source The source object. + * @returns {Object} Returns `object`. + */ + var baseAssign = nativeAssign || function(object, source) { + return source == null + ? object + : baseCopy(source, getSymbols(source), baseCopy(source, keys(source), object)); + }; - _onChange: function() { - this.setState(ResourceStore.getAll()); - }, + /** + * The base implementation of `_.at` without support for string collections + * and individual key arguments. + * + * @private + * @param {Array|Object} collection The collection to iterate over. + * @param {number[]|string[]} props The property names or indexes of elements to pick. + * @returns {Array} Returns the new array of picked elements. + */ + function baseAt(collection, props) { + var index = -1, + isNil = collection == null, + isArr = !isNil && isArrayLike(collection), + length = isArr && collection.length, + propsLength = props.length, + result = Array(propsLength); - _onNavChange: function() { - var uri = Router.param('splat'); - if (uri && uri !== this.state.uri) { - // delay to avoid nested dispatches - var category = this.props.category; - clearTimeout(this._navTimer); - this._navTimer = setTimeout(function () { - ResourceActions.get(uri, category); - }, 10); + while(++index < propsLength) { + var key = props[index]; + if (isArr) { + result[index] = isIndex(key, length) ? collection[key] : undefined; + } else { + result[index] = isNil ? undefined : collection[key]; + } + } + return result; } - }, - getInitialState: function() { - return ResourceStore.getAll(); - }, + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property names to copy. + * @param {Object} [object={}] The object to copy properties to. + * @returns {Object} Returns `object`. + */ + function baseCopy(source, props, object) { + object || (object = {}); - componentDidMount: function() { - ResourceStore.addChangeListener(this._onChange); - NavStore.addChangeListener(this._onNavChange); - // get data - var uri = Router.param('splat'); - ResourceActions.get(uri, this.props.category); - }, + var index = -1, + length = props.length; - componentWillUnmount: function() { - ResourceStore.removeChangeListener(this._onChange); - NavStore.removeChangeListener(this._onNavChange); - clearTimeout(this._navTimer); - }, + while (++index < length) { + var key = props[index]; + object[key] = source[key]; + } + return object; + } - render: function() { - var classes = [CLASS_ROOT]; - var response = this.state.response; - if (! response) { - classes.push(CLASS_ROOT + "--loading"); + /** + * The base implementation of `_.callback` which supports specifying the + * number of arguments to provide to `func`. + * + * @private + * @param {*} [func=_.identity] The value to convert to a callback. + * @param {*} [thisArg] The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function baseCallback(func, thisArg, argCount) { + var type = typeof func; + if (type == 'function') { + return thisArg === undefined + ? func + : bindCallback(func, thisArg, argCount); + } + if (func == null) { + return identity; + } + if (type == 'object') { + return baseMatches(func); + } + return thisArg === undefined + ? property(func) + : baseMatchesProperty(func, thisArg); } - return ( - React.createElement("div", {key: this.state.uri, className: classes.join(' ')}, - React.createElement(ResourceHeader, {className: CLASS_ROOT + "__header", - resource: this.state.response, - actions: this.props.actions}), - React.createElement("div", {className: CLASS_ROOT + "__content"}, - React.createElement(ResourceActivity, {category: this.props.category, uri: this.state.uri}), - React.createElement("div", {className: CLASS_ROOT + "__attributes"}, - React.createElement(Object, {data: this.state.response}) - ), - React.createElement("h3", null, "Map"), - React.createElement(ResourceMap, {uri: this.state.uri}) - ) - ) - ); - } + /** + * The base implementation of `_.clone` without support for argument juggling + * and `this` binding `customizer` functions. + * + * @private + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {string} [key] The key of `value`. + * @param {Object} [object] The object `value` belongs to. + * @param {Array} [stackA=[]] Tracks traversed source objects. + * @param {Array} [stackB=[]] Associates clones with source counterparts. + * @returns {*} Returns the cloned value. + */ + function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { + var result; + if (customizer) { + result = object ? customizer(value, key, object) : customizer(value); + } + if (result !== undefined) { + return result; + } + if (!isObject(value)) { + return value; + } + var isArr = isArray(value); + if (isArr) { + result = initCloneArray(value); + if (!isDeep) { + return arrayCopy(value, result); + } + } else { + var tag = objToString.call(value), + isFunc = tag == funcTag; - }); + if (tag == objectTag || tag == argsTag || (isFunc && !object)) { + result = initCloneObject(isFunc ? {} : value); + if (!isDeep) { + return baseAssign(result, value); + } + } else { + return cloneableTags[tag] + ? initCloneByTag(value, tag, isDeep) + : (object ? value : {}); + } + } + // Check for circular references and return corresponding clone. + stackA || (stackA = []); + stackB || (stackB = []); - module.exports = Resource; + var length = stackA.length; + while (length--) { + if (stackA[length] == value) { + return stackB[length]; + } + } + // Add the source value to the stack of traversed objects and associate it with its clone. + stackA.push(value); + stackB.push(result); + // Recursively populate clone (susceptible to call stack limits). + (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { + result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); + }); + return result; + } -/***/ }, -/* 72 */ -/***/ function(module, exports, __webpack_require__) { - - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - - var mirrorkey = __webpack_require__(83); - - module.exports = { - - ActionTypes: mirrorkey({ - INDEX_SET_CONTEXT: null, - INDEX_SET_PARAMS: null, - INDEX_RESULT: null, - INDEX_SEARCH_ATTRIBUTE: null, - INDEX_START_CHANGING: null, - INDEX_COMMIT_CHANGES: null, - INDEX_ABANDON_CHANGES: null, - INDEX_SET_VIEW: null, - INDEX_SET_SEARCH_MODE: null, - INDEX_UPDATE_ATTRIBUTE: null, - INDEX_MOVE_ATTRIBUTE: null, - INDEX_RESOURCE_ACTIVITY_RESULT: null, - INDEX_AGGREGATE_RESULT: null, - INDEX_TREES_AGGREGATED_RESULT: null, - - RESOURCE_SETUP: null, - RESOURCE_RESULT: null, - RESOURCE_ACTION: null, - - DASHBOARD_SETUP: null, - DASHBOARD_START_CHANGING: null, - DASHBOARD_COMMIT_CHANGES: null, - DASHBOARD_ABANDON_CHANGES: null, - DASHBOARD_ADD_PANEL: null, - DASHBOARD_REMOVE_PANEL: null, - DASHBOARD_EDIT_PANEL: null, - DASHBOARD_UPDATE_PANEL: null, - DASHBOARD_ORDER_PANELS: null - }) - - }; - - -/***/ }, -/* 73 */ -/***/ function(module, exports, __webpack_require__) { - - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - - var AppDispatcher = __webpack_require__(44); - var Constants = __webpack_require__(72); - - module.exports = { - - setup: function (config) { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.DASHBOARD_SETUP, - config: config - }); - }, - - startChanging: function () { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.DASHBOARD_START_CHANGING - }); - }, - - commitChanges: function () { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.DASHBOARD_COMMIT_CHANGES - }); - }, - - abandonChanges: function () { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.DASHBOARD_ABANDON_CHANGES - }); - }, - - addPanel: function (panel) { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.DASHBOARD_ADD_PANEL, - panel: panel - }); - }, - - removePanel: function (panel) { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.DASHBOARD_REMOVE_PANEL, - panel: panel - }); - }, - - editPanel: function (panel) { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.DASHBOARD_EDIT_PANEL, - panel: panel - }); - }, - - updatePanel: function (index) { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.DASHBOARD_UPDATE_PANEL, - index: index - }); - }, - - orderPanels: function (panels) { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.DASHBOARD_ORDER_PANELS, - panels: panels - }); - } - - }; - - -/***/ }, -/* 74 */ -/***/ function(module, exports, __webpack_require__) { - - // (C) Copyright 2014-2015 Hewlett-Packard Development Company, L.P. - - var _ = __webpack_require__(79); - var AppDispatcher = __webpack_require__(44); - var Constants = __webpack_require__(72); - var Api = __webpack_require__(46); - - // translate the params used in the UI to the structure used by the REST API - function translateToApiParams (params) { - var apiParams = _.extend({}, params); - // split search into query and userQuery - if (apiParams.search) { - - // split out query terms for api call, attribute:value terms - apiParams.query = apiParams.search.tokens.filter(function (token) { - return token.hasOwnProperty('attribute'); - }).map(function (token) { - return token.attribute + ":'" + token.value + "'"; - }).join(' '); - if (apiParams.query.length === 0) { - delete apiParams.query; - } + /** + * The base implementation of `_.create` without support for assigning + * properties to the created object. + * + * @private + * @param {Object} prototype The object to inherit from. + * @returns {Object} Returns the new object. + */ + var baseCreate = (function() { + function Object() {} + return function(prototype) { + if (isObject(prototype)) { + Object.prototype = prototype; + var result = new Object; + Object.prototype = null; + } + return result || context.Object(); + }; + }()); - apiParams.userQuery = apiParams.search.text; - if (apiParams.userQuery.length === 0) { - delete apiParams.userQuery; + /** + * The base implementation of `_.delay` and `_.defer` which accepts an index + * of where to slice the arguments to provide to `func`. + * + * @private + * @param {Function} func The function to delay. + * @param {number} wait The number of milliseconds to delay invocation. + * @param {Object} args The arguments provide to `func`. + * @returns {number} Returns the timer id. + */ + function baseDelay(func, wait, args) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return setTimeout(function() { func.apply(undefined, args); }, wait); } - delete apiParams.search; - } - - return apiParams; - } - - // We throttle loading resource activity to avoid flooding the network and slowing down the UI. - var pendingTimer = null; - var pendingGets = []; - var pendingActivityUris = {}; - var THROTTLE_DELAY = 100; // milliseconds - - function getSome () { - if (pendingGets.length > 0) { - var getArgs = pendingGets.shift(); - Api.get(getArgs.action, getArgs.restUri, getArgs.apiParams, getArgs.resourceUri); - clearTimeout(pendingTimer); - pendingTimer = setTimeout(getSome, THROTTLE_DELAY); - } - } - - function queueActivity (category, uri) { - if ('tasks' !== category && - 'alerts' !== category && - (! Array.isArray(category) || category.indexOf('alerts') === -1) && - ! pendingActivityUris[uri]) { - - var params = { - category: ['alerts', 'tasks'], - query: "associatedResourceUri:'" + uri + "' AND " + - "(state:'Active' OR state:'Running') AND " + - "parentTaskUri:'null' AND " + - "NOT taskType:'Background' AND " + - //"(NOT state:'New' OR NOT state:'Starting') AND " + - "NOT stateReason:'ValidationError'", - sort: 'created:desc', - start: 0, - count: 5 - }; - var apiParams = translateToApiParams(params); - var getArgs = { - action: Constants.ActionTypes.INDEX_RESOURCE_ACTIVITY_RESULT, - restUri: '/rest/index/resources', - apiParams: apiParams, - resourceUri: uri - }; - - pendingGets.push(getArgs); - pendingActivityUris[uri] = true; - } - } - - var attributeAggregateTimer = null; - - function getAttributeAggregates(getter, index) { - var attributes; - - if (index.params.search.fullText.length > 0) { - // get aggregated attributes - attributes = index.attributes.filter(function (attribute) { - return attribute.aggregate; - }).map(function (attribute) { - return attribute.name; - }); + /** + * The base implementation of `_.difference` which accepts a single array + * of values to exclude. + * + * @private + * @param {Array} array The array to inspect. + * @param {Array} values The values to exclude. + * @returns {Array} Returns the new array of filtered values. + */ + function baseDifference(array, values) { + var length = array ? array.length : 0, + result = []; - if (attributes.length > 0) { - getter(index.params, attributes); - } + if (!length) { + return result; + } + var index = -1, + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, + cache = (isCommon && values.length >= 200) ? createCache(values) : null, + valuesLength = values.length; - // if we don't have filter values yet, get them, without any search filter - attributes = index.attributes.filter(function (attribute) { - return attribute.filter; - }).map(function (attribute) { - return attribute.name; - }); + if (cache) { + indexOf = cacheIndexOf; + isCommon = false; + values = cache; + } + outer: + while (++index < length) { + var value = array[index]; - if (attributes.length > 0) { - var filterParams = _.extend({}, index.params, - {search: {fullText: '', tokens: [], text: ''}}); - getter(filterParams, attributes); - } - } else { - attributes = index.attributes.filter(function (attribute) { - return attribute.aggregate || attribute.filter; - }).map(function (attribute) { - return attribute.name; - }); - - if (attributes.length > 0) { - getter(index.params, attributes); + if (isCommon && value === value) { + var valuesIndex = valuesLength; + while (valuesIndex--) { + if (values[valuesIndex] === value) { + continue outer; + } + } + result.push(value); + } + else if (indexOf(values, value, 0) < 0) { + result.push(value); + } + } + return result; } - } - } - - module.exports = { - - setContext: function (args) { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.INDEX_SET_CONTEXT, - args: args - }); - }, - // index is optional, if provided, aggregates will be loaded as well - getResult: function (params, index) { - AppDispatcher.handleViewAction({ - type: Constants.ActionTypes.INDEX_SET_PARAMS, - params: params - }); + /** + * The base implementation of `_.forEach` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEach = createBaseEach(baseForOwn); - var apiParams = translateToApiParams(params); - pendingActivityUris = {}; - Api.get(Constants.ActionTypes.INDEX_RESULT, - '/rest/index/resources', apiParams, {params: params}); + /** + * The base implementation of `_.forEachRight` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array|Object|string} Returns `collection`. + */ + var baseEachRight = createBaseEach(baseForOwnRight, true); - if (index) { - clearTimeout(attributeAggregateTimer); - var getter = this.getAggregates; - attributeAggregateTimer = setTimeout(function () { - getAttributeAggregates(getter, index); - }, THROTTLE_DELAY); + /** + * The base implementation of `_.every` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Array|Object|string} 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; } - }, - search: function (search, referenceUri, index) { - var params = _.extend({}, index.params, {search: search, referenceUri: referenceUri}); - this.getResult(params, index); - }, + /** + * 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; - loadMore: function (index) { - var params = _.extend({}, index.params); - params.count += index.pageSize; - this.getResult(params); - }, + start = start == null ? 0 : (+start || 0); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : (end >>> 0); + start >>>= 0; - getIndexActivity: function (members) { - for (var i=0; i {view: , searchMode: , sort: , attributes: } - - var _data = { - - pageSize: 20, //100, - - // defaults will be subsumed by persistent state - defaults: { - view: 'table', - searchMode: 'filters', - sort: 'name:asc', - attributes: [{name: 'name', label: 'Name'}] // {name: ,label: } - }, - - view: 'table', // which view to show, 'table' or 'tiles' - searchMode: 'filters', // which style of search to use - sort: 'name:asc', - // each array contains attribute objects containing: - // {name: , label: , visible: , aggregate: , filter: } - // aggregate have {filteredAggregateResult: [{value: ,count:}]} - // filter have {unfilteredAggregateResult: [{value: ,count:}]} - attributes: [], - includeActivity: false, - - params: { - category: null, - start: 0, - count: 0, - // search: {tokens: [{attribute: , value: , text: } or {text: }], fullText: , text: } - search: Search.create(''), - sort: 'name:asc' - }, - - // what we receive - result: { - members: [], - start: 0, - count: 0, - total: 0, - unfilteredTotal: 0 - }, - - uriIndexes: {}, // hash of uri -> index in result.members[] - - facetedSearchText: '', // different than params.search.fullText because we strip the trailing ':' - facetedSearchSuggestions: [] - }; - - function findAttribute(attributes, attributeName) { - return attributes.filter(function (attribute) { - return attribute.name === attributeName; - })[0]; - } - - function clearResults() { - _data.result = { - params: {}, - members: [], - start: 0, - count: 0, - total: 0, - unfilteredTotal: 0 - }; - _data.uriIndexes = {}; - _data.attributes.forEach(function (attribute) { - delete attribute.filteredAggregateResult; - }); - } - - // construct the key to use for _persistentState - function categoryKey(category) { - if (typeof category === 'string') { - return category; - } else if (Array.isArray(category)) { - return category.join(','); - } - } - - // Provides a default context and initializes the state - function setContext(args) { + /** + * The base implementation of `_.isMatch` without support for callback + * shorthands and `this` binding. + * + * @private + * @param {Object} object The object to inspect. + * @param {Array} props The source property names to match. + * @param {Array} values The source values to match. + * @param {Array} strictCompareFlags Strict comparison flags for source values. + * @param {Function} [customizer] The function to customize comparing objects. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. + */ + function baseIsMatch(object, props, values, strictCompareFlags, customizer) { + var index = -1, + length = props.length, + noCustomizer = !customizer; - // normalize attributes - if (args.attributes) { - // normalize attributes - args.attributes = args.attributes.map(function (attribute, index) { - if (typeof attribute === 'string') { - attribute = {name: attribute}; - } - if (! attribute.hasOwnProperty('label')) { - if ('_activity' === attribute.name) { - attribute.label = 'Activity'; - } else { - attribute.label = String.toSentenceCase(attribute.name); + while (++index < length) { + if ((noCustomizer && strictCompareFlags[index]) + ? values[index] !== object[props[index]] + : !(props[index] in object) + ) { + return false; } } - if (! attribute.hasOwnProperty('visible')) { - attribute.visible = true; - } - attribute.index = index; - return attribute; - }); - } - - // set defaults - _data.defaults.view = args.view || 'table'; - _data.defaults.searchMode = args.searchMode || 'filters'; - _data.defaults.sort = args.sort || 'name:asc'; - _data.defaults.attributes = args.attributes || []; - - _persistentState = JSON.parse(localStorage.getItem('IndexStore__state') || '{}'); - var key = categoryKey(args.category); - // initialize persistent state if we haven't yet - if (! _persistentState.hasOwnProperty(key)) { - _persistentState[key] = { - view: _data.defaults.view, - searchMode: _data.defaults.searchMode, - sort: _data.defaults.sort, - attributes: _data.defaults.attributes - }; - } - - // set current state - var persistent = _persistentState[key]; - _data.view = persistent.view; - _data.searchMode = persistent.searchMode; - _data.sort = persistent.sort; - _data.attributes = persistent.attributes; - - // add any default attributes that weren't persisted - _data.defaults.attributes.forEach(function (attribute) { - if (! findAttribute(_data.attributes, attribute.name)) { - attribute.visible = false; - _data.attributes.push(attribute); - } - }); + index = -1; + while (++index < length) { + var key = props[index], + objValue = object[key], + srcValue = values[index]; - _data.includeActivity = false; - _data.attributes.forEach(function (attribute) { - // preserve render() function - _data.defaults.attributes.some(function (defaultAttribute) { - if (defaultAttribute.name === attribute.name) { - if (defaultAttribute.hasOwnProperty('render')) { - attribute.render = defaultAttribute.render; + if (noCustomizer && strictCompareFlags[index]) { + var result = objValue !== undefined || (key in object); + } else { + result = customizer ? customizer(objValue, srcValue, key) : undefined; + if (result === undefined) { + result = baseIsEqual(srcValue, objValue, customizer, true); + } } - if (defaultAttribute.hasLink) { - attribute.hasLink = defaultAttribute.hasLink; + if (!result) { + return false; } - return true; - } - }); - if (attribute.visible && attribute.name === '_activity') { - _data.includeActivity = true; - } - delete attribute.unfilteredAggregateResult; - }); - - _data.params = { - category: args.category, - start: 0, - count: _data.pageSize, - search: Search.create(''), - sort: _data.sort - }; - - clearResults(); - } - - // attributes we don't allow the user to see when searching - var BLACKLIST = {'category': true, 'type': true, 'uri': true, 'eTag': true}; - - // add additional attributes found in an index result to the list of available attributes - function addAttributesFromResult(obj) { - _.forOwn(obj, function (value, name) { - var attribute = findAttribute(_data.attributes, name); - if (! attribute && ! BLACKLIST[name]) { - - if (typeof obj[name] !== 'object') { - attribute = { - name: name, - label: String.toSentenceCase(name), - visible: false - }; - _data.attributes.push(attribute); - } else if ('attributes' === name) { - addAttributesFromResult(value); } + return true; } - }); - } - - // context is _data for basic usage and _data.pendingChanges while editing - function sortAttributes(context) { - // sort, first by show order, then by name - context.attributes.sort(function (a1, a2) { - if (a1.visible && a2.visible) { - return (a1.index < a2.index ? -1 : +1); - } else if (! a1.visible && ! a2.visible) { - return AlphaNum.compare(a1.name, a2.name); - } else { - return a1.visible ? -1 : +1; - } - }); - } - // indicate which attribute values are currently being filtered for - function markActiveFilters() { - _data.attributes.forEach(function (attribute) { - if (attribute.unfilteredAggregateResult) { - attribute.unfilteredAggregateResult.counts.forEach(function (value) { - value.filterActive = _data.params.search.tokens.some(function (token) { - return token.attribute === attribute.name && token.value === value.value; - }); - }); - } - }); - } + /** + * The base implementation of `_.map` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} 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) : []; - // construct the appropriate faceted search suggestions based on the last search text term - function buildFacetedSearchSuggestions() { - _data.facetedSearchSuggestions = []; - var text = _data.facetedSearchText; - - // match only last term and only if there isn't a trailing space - var lastChar = text[text.length - 1]; - var matches = text.match(/\S+/g); - var term = ''; - if (' ' !== lastChar && matches && matches.length > 0) { - term = matches[matches.length-1].toLowerCase(); - } - var parts = term.split(':'); - var exp; - if (parts.length > 1) { - - // attribute:value - exp = new RegExp(parts[1] + '[^$]', 'i'); - var attribute = findAttribute(_data.attributes, parts[0]); - if (attribute.unfilteredAggregateResult) { - attribute.unfilteredAggregateResult.counts.forEach(function (count) { - if (exp.test(count.value)) { - _data.facetedSearchSuggestions.push({term: count.value, count: count.count}); - } + baseEach(collection, function(value, key, collection) { + result[++index] = iteratee(value, key, collection); }); + return result; } - } else { + /** + * The base implementation of `_.matches` which does not clone `source`. + * + * @private + * @param {Object} source The object of property values to match. + * @returns {Function} Returns the new function. + */ + function baseMatches(source) { + var props = keys(source), + length = props.length; - // attribute - exp = new RegExp(parts[0] + '[^$]', 'i'); - _data.attributes.forEach(function (attribute) { - if (exp.test(attribute.name) && '_activity' !== attribute.name) { - _data.facetedSearchSuggestions.push({term: attribute.name + ':'}); + if (!length) { + return constant(true); } - }); - } - - // sort - _data.facetedSearchSuggestions.sort(function (s1, s2) { - return AlphaNum.compare(s1.term, s2.term); - }); - } - - // set the parameters that will be used for subsequent results - function setParams(params) { - _data.params = params; - _data.facetedSearchText = params.search.fullText; - markActiveFilters(); - - // clear out result so we don't use old results after we've asked for new ones - clearResults(); - } - - // record a result from the index service - function setResult(result) { - _data.result = result; - - // save uri -> index to speed up lookups by uri - _data.uriIndexes = {}; - _data.result.members.forEach(function (member, index) { - _data.uriIndexes[member.uri] = index; - }); - - // save attributes so we can use them as faceted search suggestions - if (_data.result.members.length > 1) { - addAttributesFromResult(_data.result.members[0]); - sortAttributes(_data); - } - - buildFacetedSearchSuggestions(); - } - - // save the activity result for the indicated resource - function setResourceActivityResult(result, uri) { - if (_data.uriIndexes.hasOwnProperty(uri)) { - var member = _data.result.members[_data.uriIndexes[uri]]; - member._activity = result; - } - } + if (length == 1) { + var key = props[0], + value = source[key]; - // save the aggregate results - function setAggregateResult(result, context) { - // ignote results initiated from the Dashboard - if (context.params.search && context.params.search.tokens && - context.params.category === _data.params.category) { - result.forEach(function (attributeResult) { - var attribute = findAttribute(_data.attributes, attributeResult.attribute); - if (attribute) { - if (context.params.search.fullText.length > 0) { - attribute.filteredAggregateResult = attributeResult; - } else { - attribute.unfilteredAggregateResult = attributeResult; + if (isStrictComparable(value)) { + return function(object) { + if (object == null) { + return false; + } + return object[key] === value && (value !== undefined || (key in toObject(object))); + }; } } - }); - markActiveFilters(); - buildFacetedSearchSuggestions(); - } - } + var values = Array(length), + strictCompareFlags = Array(length); - function startChanging() { - _data.pendingChanges = { - view: _data.view, - searchMode: _data.searchMode, - attributes: _data.attributes.slice(0) - }; - } - - function pruneAttributesForPersistence(attributes) { - return attributes.filter(function (attribute) { - return attribute.visible || attribute.aggregate || attribute.filter; - }).map(function (attribute) { - return { - name: attribute.name, - label: attribute.label, - visible: attribute.visible || false, - aggregate: attribute.aggregate || false, - filter: attribute.filter || false - }; - }); - } - - function commitChanges() { - _data.view = _data.pendingChanges.view; - _data.searchMode = _data.pendingChanges.searchMode; - _data.attributes = _data.pendingChanges.attributes; - - var key = categoryKey(_data.params.category); - _persistentState[key].view = _data.view; - _persistentState[key].searchMode = _data.searchMode; - _persistentState[key].attributes = pruneAttributesForPersistence(_data.attributes); - localStorage.setItem('IndexStore__state', JSON.stringify(_persistentState)); - } - - function abandonChanges() { - _data.pendingChanges = null; - } - - function setView(view) { - _data.pendingChanges.view = view; - } - - function setSearchMode(searchMode) { - _data.pendingChanges.searchMode = searchMode; - } - - function updateAttribute(attributeArg) { - var attribute = findAttribute(_data.pendingChanges.attributes, attributeArg.name); - attribute.visible = attributeArg.visible; - attribute.aggregate = attributeArg.aggregate; - attribute.filter = attributeArg.filter; - sortAttributes(_data.pendingChanges); - } - - function moveAttribute(fromIndex, toIndex) { - var attributes = _data.pendingChanges.attributes; - attributes.splice(toIndex, 0, attributes.splice(fromIndex, 1)[0]); - _data.pendingChanges.attributes.forEach(function (attribute, index) { - attribute.index = index; - }); - sortAttributes(_data.pendingChanges); - } - - var IndexStore = _.extend({}, EventEmitter.prototype, { - - // public methods used by Controller-View to operate on data - getAll: function() { - return _data; - }, - - nextUri: function (resourceUri) { - var resultUri = null; - if (_data.uriIndexes.hasOwnProperty(resourceUri)) { - var index = _data.uriIndexes[resourceUri] + 1; - if (index < _data.result.members.length) { - resultUri = _data.result.members[index].uri; + while (length--) { + value = source[props[length]]; + values[length] = value; + strictCompareFlags[length] = isStrictComparable(value); } + return function(object) { + return object != null && baseIsMatch(toObject(object), props, values, strictCompareFlags); + }; } - return resultUri; - }, - previousUri: function (resourceUri) { - var resultUri = null; - if (_data.uriIndexes.hasOwnProperty(resourceUri)) { - var index = _data.uriIndexes[resourceUri] - 1; - if (index >= 0) { - resultUri = _data.result.members[index].uri; - } - } - return resultUri; - }, + /** + * The base implementation of `_.matchesProperty` which does not which does + * not clone `value`. + * + * @private + * @param {string} path The path of the property to get. + * @param {*} value The value to compare. + * @returns {Function} Returns the new function. + */ + function baseMatchesProperty(path, value) { + var isArr = isArray(path), + isCommon = isKey(path) && isStrictComparable(value), + pathKey = (path + ''); - areSameCategories: function (c1, c2) { - if (typeof c1 === 'string' && c1 === c2) { - return true; - } else if (Array.isArray(c1) && Array.isArray(c2)) { - if (c1.length !== c2.length) { - return false; - } - for (var i=0; i length ? 0 : (length + start); + } + end = (end === undefined || end > length) ? length : (+end || 0); + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; - var _ = __webpack_require__(79); - var AppDispatcher = __webpack_require__(44); - var EventEmitter = __webpack_require__(81).EventEmitter; - var Constants = __webpack_require__(72); - - var _data = { - category: null, - uri: null, - response: null, - activity: {}, - treesAggregated: {} - }; + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } - // add private functions to modify data - function setup(uri, category) { - _data.category = category; - _data.uri = uri; - _data.response = null; - } + /** + * The base implementation of `_.some` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} 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; - function setResult(result) { - _data.response = result; - } + baseEach(collection, function(value, index, collection) { + result = predicate(value, index, collection); + return !result; + }); + return !!result; + } - function setActivityResult(uri, result) { - if (uri === _data.uri) { - _data.activity = result; - } - } + /** + * 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; - function setTreesAggregatedResult(uri, result) { - if (uri === _data.uri) { - _data.treesAggregated = result; - } - } + array.sort(comparer); + while (length--) { + array[length] = array[length].value; + } + return array; + } - function setActionResult(result) { - _data.task.uri = result.taskUri; - } + /** + * The base implementation of `_.sortByOrder` without param guards. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @returns {Array} Returns the new sorted array. + */ + function baseSortByOrder(collection, iteratees, orders) { + var callback = getCallback(), + index = -1; - var ResourceStore = _.extend({}, EventEmitter.prototype, { + iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); - // public methods used by Controller-View to operate on data - getAll: function() { - return _data; - }, + var result = baseMap(collection, function(value) { + var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); + return { 'criteria': criteria, 'index': ++index, 'value': value }; + }); - // Allow Controller-View to register itself with store - addChangeListener: function(callback) { - this.on(Constants.CHANGE_EVENT, callback); - }, - removeChangeListener: function(callback) { - this.removeListener(Constants.CHANGE_EVENT, callback); - }, - // triggers change listener above, firing controller-view callback - emitChange: function() { - this.emit(Constants.CHANGE_EVENT); - }, + return baseSortBy(result, function(object, other) { + return compareMultiple(object, other, orders); + }); + } - // register store with dispatcher, allowing actions to flow through - dispatcherIndex: AppDispatcher.register(function(payload) { - var action = payload.action; + /** + * The base implementation of `_.sum` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {number} Returns the sum. + */ + function baseSum(collection, iteratee) { + var result = 0; + baseEach(collection, function(value, index, collection) { + result += +iteratee(value, index, collection) || 0; + }); + return result; + } - switch(action.type) { + /** + * The base implementation of `_.uniq` without support for callback shorthands + * and `this` binding. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} [iteratee] The function invoked per iteration. + * @returns {Array} Returns the new duplicate-value-free array. + */ + function baseUniq(array, iteratee) { + var index = -1, + indexOf = getIndexOf(), + length = array.length, + isCommon = indexOf == baseIndexOf, + isLarge = isCommon && length >= 200, + seen = isLarge ? createCache() : null, + result = []; - case Constants.ActionTypes.RESOURCE_SETUP: - setup(action.uri, action.category); - ResourceStore.emitChange(); - break; + if (seen) { + indexOf = cacheIndexOf; + isCommon = false; + } else { + isLarge = false; + seen = iteratee ? [] : result; + } + outer: + while (++index < length) { + var value = array[index], + computed = iteratee ? iteratee(value, index, array) : value; - case Constants.ActionTypes.RESOURCE_RESULT: - setResult(action.response); - ResourceStore.emitChange(); - break; + if (isCommon && value === value) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed) { + continue outer; + } + } + if (iteratee) { + seen.push(computed); + } + result.push(value); + } + else if (indexOf(seen, computed, 0) < 0) { + if (iteratee || isLarge) { + seen.push(computed); + } + result.push(value); + } + } + return result; + } - case Constants.ActionTypes.INDEX_RESOURCE_ACTIVITY_RESULT: - setActivityResult(action.context, action.response); - ResourceStore.emitChange(); - break; + /** + * 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) { + var index = -1, + length = props.length, + result = Array(length); - case Constants.ActionTypes.INDEX_TREES_AGGREGATED_RESULT: - setTreesAggregatedResult(action.context, action.response); - ResourceStore.emitChange(); - break; + while (++index < length) { + result[index] = object[props[index]]; + } + return result; + } - case Constants.ActionTypes.RESOURCE_ACTION: - setActionResult(action.response); - ResourceStore.emitChange(); - break; + /** + * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, + * and `_.takeWhile` without support for callback shorthands and `this` binding. + * + * @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)); } - }) - - }); - module.exports = ResourceStore; + /** + * 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 peform to resolve the unwrapped value. + * @returns {*} Returns the resolved value. + */ + function baseWrapperValue(value, actions) { + var result = value; + if (result instanceof LazyWrapper) { + result = result.value(); + } + var index = -1, + length = actions.length; + while (++index < length) { + var args = [result], + action = actions[index]; -/***/ }, -/* 79 */ -/***/ function(module, exports, __webpack_require__) { + push.apply(args, action.args); + result = action.func.apply(action.thisArg, args); + } + return result; + } - var __WEBPACK_AMD_DEFINE_RESULT__;/* WEBPACK VAR INJECTION */(function(module, global) {/** - * @license - * lodash 3.7.0 (Custom Build) - * Build: `lodash modern -d -o ./index.js` - * Copyright 2012-2015 The Dojo Foundation - * Based on Underscore.js 1.8.3 - * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors - * Available under MIT license - */ - ;(function() { - - /** Used as a safe reference for `undefined` in pre-ES5 environments. */ - var undefined; + /** + * 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 binaryIndex(array, value, retHighest) { + var low = 0, + high = array ? array.length : low; - /** Used as the semantic version number. */ - var VERSION = '3.7.0'; + if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { + while (low < high) { + var mid = (low + high) >>> 1, + computed = array[mid]; - /** Used to compose bitmasks for wrapper metadata. */ - var BIND_FLAG = 1, - BIND_KEY_FLAG = 2, - CURRY_BOUND_FLAG = 4, - CURRY_FLAG = 8, - CURRY_RIGHT_FLAG = 16, - PARTIAL_FLAG = 32, - PARTIAL_RIGHT_FLAG = 64, - ARY_FLAG = 128, - REARG_FLAG = 256; + if (retHighest ? (computed <= value) : (computed < value)) { + low = mid + 1; + } else { + high = mid; + } + } + return high; + } + return binaryIndexBy(array, value, identity, retHighest); + } - /** Used as default options for `_.trunc`. */ - var DEFAULT_TRUNC_LENGTH = 30, - DEFAULT_TRUNC_OMISSION = '...'; + /** + * This function is like `binaryIndex` except that it 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 function invoked per iteration. + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + */ + function binaryIndexBy(array, value, iteratee, retHighest) { + value = iteratee(value); - /** Used to detect when a function becomes hot. */ - var HOT_COUNT = 150, - HOT_SPAN = 16; + var low = 0, + high = array ? array.length : 0, + valIsNaN = value !== value, + valIsUndef = value === undefined; - /** Used to indicate the type of lazy iteratees. */ - var LAZY_DROP_WHILE_FLAG = 0, - LAZY_FILTER_FLAG = 1, - LAZY_MAP_FLAG = 2; + while (low < high) { + var mid = floor((low + high) / 2), + computed = iteratee(array[mid]), + isReflexive = computed === computed; - /** Used as the `TypeError` message for "Functions" methods. */ - var FUNC_ERROR_TEXT = 'Expected a function'; + if (valIsNaN) { + var setLow = isReflexive || retHighest; + } else if (valIsUndef) { + setLow = isReflexive && (retHighest || computed !== undefined); + } else { + setLow = retHighest ? (computed <= value) : (computed < value); + } + if (setLow) { + low = mid + 1; + } else { + high = mid; + } + } + return nativeMin(high, MAX_ARRAY_INDEX); + } - /** Used as the internal argument placeholder. */ - var PLACEHOLDER = '__lodash_placeholder__'; + /** + * A specialized version of `baseCallback` which only supports `this` binding + * and specifying the number of arguments to provide to `func`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} thisArg The `this` binding of `func`. + * @param {number} [argCount] The number of arguments to provide to `func`. + * @returns {Function} Returns the callback. + */ + function bindCallback(func, thisArg, argCount) { + if (typeof func != 'function') { + return identity; + } + if (thisArg === undefined) { + return func; + } + switch (argCount) { + case 1: return function(value) { + return func.call(thisArg, value); + }; + case 3: return function(value, index, collection) { + return func.call(thisArg, value, index, collection); + }; + case 4: return function(accumulator, value, index, collection) { + return func.call(thisArg, accumulator, value, index, collection); + }; + case 5: return function(value, other, key, object, source) { + return func.call(thisArg, value, other, key, object, source); + }; + } + return function() { + return func.apply(thisArg, arguments); + }; + } - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]', - arrayTag = '[object Array]', - boolTag = '[object Boolean]', - dateTag = '[object Date]', - errorTag = '[object Error]', - funcTag = '[object Function]', - mapTag = '[object Map]', - numberTag = '[object Number]', - objectTag = '[object Object]', - regexpTag = '[object RegExp]', - setTag = '[object Set]', - stringTag = '[object String]', - weakMapTag = '[object WeakMap]'; + /** + * Creates a clone of the given array buffer. + * + * @private + * @param {ArrayBuffer} buffer The array buffer to clone. + * @returns {ArrayBuffer} Returns the cloned array buffer. + */ + function bufferClone(buffer) { + return bufferSlice.call(buffer, 0); + } + if (!bufferSlice) { + // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`. + bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) { + var byteLength = buffer.byteLength, + floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, + offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, + result = new ArrayBuffer(byteLength); - var arrayBufferTag = '[object ArrayBuffer]', - 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]'; + if (floatLength) { + var view = new Float64Array(result, 0, floatLength); + view.set(new Float64Array(buffer, 0, floatLength)); + } + if (byteLength != offset) { + view = new Uint8Array(result, offset); + view.set(new Uint8Array(buffer, offset)); + } + return result; + }; + } - /** 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; + /** + * Creates an array that is the composition of partially applied arguments, + * placeholders, and provided arguments into a single array of arguments. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to prepend to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgs(args, partials, holders) { + var holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + leftIndex = -1, + leftLength = partials.length, + result = Array(argsLength + leftLength); - /** Used to match HTML entities and HTML characters. */ - var reEscapedHtml = /&(?:amp|lt|gt|quot|#39|#96);/g, - reUnescapedHtml = /[&<>"'`]/g, - reHasEscapedHtml = RegExp(reEscapedHtml.source), - reHasUnescapedHtml = RegExp(reUnescapedHtml.source); + while (++leftIndex < leftLength) { + result[leftIndex] = partials[leftIndex]; + } + while (++argsIndex < holdersLength) { + result[holders[argsIndex]] = args[argsIndex]; + } + while (argsLength--) { + result[leftIndex++] = args[argsIndex++]; + } + return result; + } - /** Used to match template delimiters. */ - var reEscape = /<%-([\s\S]+?)%>/g, - reEvaluate = /<%([\s\S]+?)%>/g, - reInterpolate = /<%=([\s\S]+?)%>/g; + /** + * This function is like `composeArgs` except that the arguments composition + * is tailored for `_.partialRight`. + * + * @private + * @param {Array|Object} args The provided arguments. + * @param {Array} partials The arguments to append to those provided. + * @param {Array} holders The `partials` placeholder indexes. + * @returns {Array} Returns the new array of composed arguments. + */ + function composeArgsRight(args, partials, holders) { + var holdersIndex = -1, + holdersLength = holders.length, + argsIndex = -1, + argsLength = nativeMax(args.length - holdersLength, 0), + rightIndex = -1, + rightLength = partials.length, + result = Array(argsLength + rightLength); - /** Used to match property names within property paths. */ - var reIsDeepProp = /\.|\[(?:[^[\]]+|(["'])(?:(?!\1)[^\n\\]|\\.)*?)\1\]/, - reIsPlainProp = /^\w*$/, - rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g; + while (++argsIndex < argsLength) { + result[argsIndex] = args[argsIndex]; + } + var offset = argsIndex; + while (++rightIndex < rightLength) { + result[offset + rightIndex] = partials[rightIndex]; + } + while (++holdersIndex < holdersLength) { + result[offset + holders[holdersIndex]] = args[argsIndex++]; + } + return result; + } - /** - * Used to match `RegExp` [special characters](http://www.regular-expressions.info/characters.html#special). - * In addition to special characters the forward slash is escaped to allow for - * easier `eval` use and `Function` compilation. - */ - var reRegExpChars = /[.*+?^${}()|[\]\/\\]/g, - reHasRegExpChars = RegExp(reRegExpChars.source); + /** + * Creates a function that aggregates a collection, creating an accumulator + * object composed from the results of running each element in the collection + * through an iteratee. + * + * **Note:** This function is used to create `_.countBy`, `_.groupBy`, `_.indexBy`, + * and `_.partition`. + * + * @private + * @param {Function} setter The function to set keys and values of the accumulator object. + * @param {Function} [initializer] The function to initialize the accumulator object. + * @returns {Function} Returns the new aggregator function. + */ + function createAggregator(setter, initializer) { + return function(collection, iteratee, thisArg) { + var result = initializer ? initializer() : {}; + iteratee = getCallback(iteratee, thisArg, 3); - /** Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). */ - var reComboMark = /[\u0300-\u036f\ufe20-\ufe23]/g; + if (isArray(collection)) { + var index = -1, + length = collection.length; - /** Used to match backslashes in property paths. */ - var reEscapeChar = /\\(\\)?/g; + while (++index < length) { + var value = collection[index]; + setter(result, value, iteratee(value, index, collection), collection); + } + } else { + baseEach(collection, function(value, key, collection) { + setter(result, value, iteratee(value, key, collection), collection); + }); + } + return result; + }; + } - /** Used to match [ES template delimiters](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-template-literal-lexical-components). */ - var reEsTemplate = /\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g; + /** + * Creates a function that assigns properties of source object(s) to a given + * destination object. + * + * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return restParam(function(object, sources) { + var index = -1, + length = object == null ? 0 : sources.length, + customizer = length > 2 && sources[length - 2], + guard = length > 2 && sources[2], + thisArg = length > 1 && sources[length - 1]; - /** Used to match `RegExp` flags from their coerced string values. */ - var reFlags = /\w*$/; + if (typeof customizer == 'function') { + customizer = bindCallback(customizer, thisArg, 5); + length -= 2; + } else { + customizer = typeof thisArg == 'function' ? thisArg : null; + length -= (customizer ? 1 : 0); + } + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? null : customizer; + length = 1; + } + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, customizer); + } + } + return object; + }); + } - /** Used to detect hexadecimal string values. */ - var reHasHexPrefix = /^0[xX]/; + /** + * 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) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + return eachFunc(collection, iteratee); + } + var index = fromRight ? length : -1, + iterable = toObject(collection); - /** Used to detect host constructors (Safari > 5). */ - var reIsHostCtor = /^\[object .+?Constructor\]$/; + while ((fromRight ? index-- : ++index < length)) { + if (iteratee(iterable[index], index, iterable) === false) { + break; + } + } + return collection; + }; + } - /** Used to match latin-1 supplementary letters (excluding mathematical operators). */ - var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g; + /** + * Creates a base function for `_.forIn` or `_.forInRight`. + * + * @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 iterable = toObject(object), + props = keysFunc(object), + length = props.length, + index = fromRight ? length : -1; - /** Used to ensure capturing order of template delimiters. */ - var reNoMatch = /($^)/; + while ((fromRight ? index-- : ++index < length)) { + var key = props[index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; + } - /** Used to match unescaped characters in compiled string literals. */ - var reUnescapedString = /['\n\r\u2028\u2029\\]/g; + /** + * Creates a function that wraps `func` and invokes it with the `this` + * binding of `thisArg`. + * + * @private + * @param {Function} func The function to bind. + * @param {*} [thisArg] The `this` binding of `func`. + * @returns {Function} Returns the new bound function. + */ + function createBindWrapper(func, thisArg) { + var Ctor = createCtorWrapper(func); - /** Used to match words to create compound words. */ - var reWords = (function() { - var upper = '[A-Z\\xc0-\\xd6\\xd8-\\xde]', - lower = '[a-z\\xdf-\\xf6\\xf8-\\xff]+'; + function wrapper() { + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(thisArg, arguments); + } + return wrapper; + } - return RegExp(upper + '+(?=' + upper + lower + ')|' + upper + '?' + lower + '|' + upper + '+|[0-9]+', 'g'); - }()); + /** + * Creates a `Set` cache object to optimize linear searches of large arrays. + * + * @private + * @param {Array} [values] The values to cache. + * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. + */ + var createCache = !(nativeCreate && Set) ? constant(null) : function(values) { + return new SetCache(values); + }; - /** Used to detect and test for whitespace. */ - var whitespace = ( - // Basic whitespace characters. - ' \t\x0b\f\xa0\ufeff' + + /** + * Creates a function that produces compound words out of the words in a + * given string. + * + * @private + * @param {Function} callback The function to combine each word. + * @returns {Function} Returns the new compounder function. + */ + function createCompounder(callback) { + return function(string) { + var index = -1, + array = words(deburr(string)), + length = array.length, + result = ''; - // Line terminators. - '\n\r\u2028\u2029' + + while (++index < length) { + result = callback(result, array[index], index); + } + return result; + }; + } - // Unicode category "Zs" space separators. - '\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000' - ); + /** + * 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 createCtorWrapper(Ctor) { + return function() { + var thisBinding = baseCreate(Ctor.prototype), + result = Ctor.apply(thisBinding, arguments); - /** Used to assign default `context` object properties. */ - var contextProps = [ - 'Array', 'ArrayBuffer', 'Date', 'Error', 'Float32Array', 'Float64Array', - 'Function', 'Int8Array', 'Int16Array', 'Int32Array', 'Math', 'Number', - 'Object', 'RegExp', 'Set', 'String', '_', 'clearTimeout', 'document', - 'isFinite', 'parseInt', 'setTimeout', 'TypeError', 'Uint8Array', - 'Uint8ClampedArray', 'Uint16Array', 'Uint32Array', 'WeakMap', - 'window' - ]; + // Mimic the constructor's `return` behavior. + // See https://es5.github.io/#x13.2.2 for more details. + return isObject(result) ? result : thisBinding; + }; + } - /** Used to make template sourceURLs easier to identify. */ - var templateCounter = -1; + /** + * Creates a `_.curry` or `_.curryRight` function. + * + * @private + * @param {boolean} flag The curry bit flag. + * @returns {Function} Returns the new curry function. + */ + function createCurry(flag) { + function curryFunc(func, arity, guard) { + if (guard && isIterateeCall(func, arity, guard)) { + arity = null; + } + var result = createWrapper(func, flag, null, null, null, null, null, arity); + result.placeholder = curryFunc.placeholder; + return result; + } + return curryFunc; + } - /** 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[dateTag] = typedArrayTags[errorTag] = - typedArrayTags[funcTag] = typedArrayTags[mapTag] = - typedArrayTags[numberTag] = typedArrayTags[objectTag] = - typedArrayTags[regexpTag] = typedArrayTags[setTag] = - typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + /** + * Creates a `_.max` or `_.min` function. + * + * @private + * @param {Function} arrayFunc The function to get the extremum value from an array. + * @param {boolean} [isMin] Specify returning the minimum, instead of the maximum, + * extremum value. + * @returns {Function} Returns the new extremum function. + */ + function createExtremum(arrayFunc, isMin) { + return function(collection, iteratee, thisArg) { + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = null; + } + var func = getCallback(), + noIteratee = iteratee == null; - /** Used to identify `toStringTag` values supported by `_.clone`. */ - var cloneableTags = {}; - cloneableTags[argsTag] = cloneableTags[arrayTag] = - cloneableTags[arrayBufferTag] = cloneableTags[boolTag] = - cloneableTags[dateTag] = cloneableTags[float32Tag] = - cloneableTags[float64Tag] = cloneableTags[int8Tag] = - cloneableTags[int16Tag] = cloneableTags[int32Tag] = - cloneableTags[numberTag] = cloneableTags[objectTag] = - cloneableTags[regexpTag] = cloneableTags[stringTag] = - cloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] = - cloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true; - cloneableTags[errorTag] = cloneableTags[funcTag] = - cloneableTags[mapTag] = cloneableTags[setTag] = - cloneableTags[weakMapTag] = false; + if (!(func === baseCallback && noIteratee)) { + noIteratee = false; + iteratee = func(iteratee, thisArg, 3); + } + if (noIteratee) { + var isArr = isArray(collection); + if (!isArr && isString(collection)) { + iteratee = charAtCallback; + } else { + return arrayFunc(isArr ? collection : toIterable(collection)); + } + } + return extremumBy(collection, iteratee, isMin); + }; + } - /** Used as an internal `_.debounce` options object by `_.throttle`. */ - var debounceOptions = { - 'leading': false, - 'maxWait': 0, - 'trailing': false - }; + /** + * Creates a `_.find` or `_.findLast` 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 find function. + */ + function createFind(eachFunc, fromRight) { + return function(collection, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + if (isArray(collection)) { + var index = baseFindIndex(collection, predicate, fromRight); + return index > -1 ? collection[index] : undefined; + } + return baseFind(collection, predicate, eachFunc); + }; + } - /** Used to map latin-1 supplementary letters to basic latin letters. */ - var deburredLetters = { - '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', - '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', - '\xc7': 'C', '\xe7': 'c', - '\xd0': 'D', '\xf0': 'd', - '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', - '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', - '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', - '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', - '\xd1': 'N', '\xf1': 'n', - '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', - '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', - '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', - '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', - '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', - '\xc6': 'Ae', '\xe6': 'ae', - '\xde': 'Th', '\xfe': 'th', - '\xdf': 'ss' - }; + /** + * Creates a `_.findIndex` or `_.findLastIndex` function. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new find function. + */ + function createFindIndex(fromRight) { + return function(array, predicate, thisArg) { + if (!(array && array.length)) { + return -1; + } + predicate = getCallback(predicate, thisArg, 3); + return baseFindIndex(array, predicate, fromRight); + }; + } - /** Used to map characters to HTML entities. */ - var htmlEscapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '`': '`' - }; + /** + * Creates a `_.findKey` or `_.findLastKey` function. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new find function. + */ + function createFindKey(objectFunc) { + return function(object, predicate, thisArg) { + predicate = getCallback(predicate, thisArg, 3); + return baseFind(object, predicate, objectFunc, true); + }; + } - /** Used to map HTML entities to characters. */ - var htmlUnescapes = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - ''': "'", - '`': '`' - }; + /** + * 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 function() { + var length = arguments.length; + if (!length) { + return function() { return arguments[0]; }; + } + var wrapper, + index = fromRight ? length : -1, + leftIndex = 0, + funcs = Array(length); - /** Used to determine if values are of the language type `Object`. */ - var objectTypes = { - 'function': true, - 'object': true - }; + while ((fromRight ? index-- : ++index < length)) { + var func = funcs[leftIndex++] = arguments[index]; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var funcName = wrapper ? '' : getFuncName(func); + wrapper = funcName == 'wrapper' ? new LodashWrapper([]) : wrapper; + } + index = wrapper ? -1 : length; + while (++index < length) { + func = funcs[index]; + funcName = getFuncName(func); - /** Used to escape characters for inclusion in compiled string literals. */ - var stringEscapes = { - '\\': '\\', - "'": "'", - '\n': 'n', - '\r': 'r', - '\u2028': 'u2028', - '\u2029': 'u2029' - }; + var data = funcName == 'wrapper' ? getData(func) : null; + if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { + wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); + } else { + wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); + } + } + return function() { + var args = arguments; + if (wrapper && args.length == 1 && isArray(args[0])) { + return wrapper.plant(args[0]).value(); + } + var index = 0, + result = funcs[index].apply(this, args); - /** Detect free variable `exports`. */ - var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports; + while (++index < length) { + result = funcs[index].call(this, result); + } + return result; + }; + }; + } - /** Detect free variable `module`. */ - var freeModule = objectTypes[typeof module] && module && !module.nodeType && module; + /** + * Creates a function for `_.forEach` or `_.forEachRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createForEach(arrayFunc, eachFunc) { + return function(collection, iteratee, thisArg) { + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee) + : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); + }; + } - /** Detect free variable `global` from Node.js. */ - var freeGlobal = freeExports && freeModule && typeof global == 'object' && global && global.Object && global; + /** + * Creates a function for `_.forIn` or `_.forInRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForIn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee, keysIn); + }; + } - /** Detect free variable `self`. */ - var freeSelf = objectTypes[typeof self] && self && self.Object && self; + /** + * Creates a function for `_.forOwn` or `_.forOwnRight`. + * + * @private + * @param {Function} objectFunc The function to iterate over an object. + * @returns {Function} Returns the new each function. + */ + function createForOwn(objectFunc) { + return function(object, iteratee, thisArg) { + if (typeof iteratee != 'function' || thisArg !== undefined) { + iteratee = bindCallback(iteratee, thisArg, 3); + } + return objectFunc(object, iteratee); + }; + } - /** Detect free variable `window`. */ - var freeWindow = objectTypes[typeof window] && window && window.Object && window; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports && freeExports; - - /** - * Used as a reference to the global object. - * - * The `this` value is used if it is the global object to avoid Greasemonkey's - * restricted `window` object, otherwise the `window` object is used. - */ - var root = freeGlobal || ((freeWindow !== (this && this.window)) && freeWindow) || freeSelf || this; - - /*--------------------------------------------------------------------------*/ - - /** - * The base implementation of `compareAscending` which compares values and - * sorts them in ascending order without guaranteeing a stable sort. - * - * @private - * @param {*} value The value to compare to `other`. - * @param {*} other The value to compare to `value`. - * @returns {number} Returns the sort order indicator for `value`. - */ - function baseCompareAscending(value, other) { - if (value !== other) { - var valIsReflexive = value === value, - othIsReflexive = other === other; + /** + * Creates a function for `_.mapKeys` or `_.mapValues`. + * + * @private + * @param {boolean} [isMapKeys] Specify mapping keys instead of values. + * @returns {Function} Returns the new map function. + */ + function createObjectMapper(isMapKeys) { + return function(object, iteratee, thisArg) { + var result = {}; + iteratee = getCallback(iteratee, thisArg, 3); - if (value > other || !valIsReflexive || (value === undefined && othIsReflexive)) { - return 1; - } - if (value < other || !othIsReflexive || (other === undefined && valIsReflexive)) { - return -1; - } + baseForOwn(object, function(value, key, object) { + var mapped = iteratee(value, key, object); + key = isMapKeys ? mapped : key; + value = isMapKeys ? value : mapped; + result[key] = value; + }); + return result; + }; } - return 0; - } - - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to search. - * @param {Function} predicate The function invoked per iteration. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromRight) { - var length = array.length, - index = fromRight ? length : -1; - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; - } + /** + * Creates a function for `_.padLeft` or `_.padRight`. + * + * @private + * @param {boolean} [fromRight] Specify padding from the right. + * @returns {Function} Returns the new pad function. + */ + function createPadDir(fromRight) { + return function(string, length, chars) { + string = baseToString(string); + return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); + }; } - return -1; - } - /** - * The base implementation of `_.indexOf` without support for binary searches. - * - * @private - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - if (value !== value) { - return indexOfNaN(array, fromIndex); + /** + * Creates a `_.partial` or `_.partialRight` function. + * + * @private + * @param {boolean} flag The partial bit flag. + * @returns {Function} Returns the new partial function. + */ + function createPartial(flag) { + var partialFunc = restParam(function(func, partials) { + var holders = replaceHolders(partials, partialFunc.placeholder); + return createWrapper(func, flag, null, partials, holders); + }); + return partialFunc; } - var index = fromIndex - 1, - length = array.length; - while (++index < length) { - if (array[index] === value) { - return index; - } + /** + * Creates a function for `_.reduce` or `_.reduceRight`. + * + * @private + * @param {Function} arrayFunc The function to iterate over an array. + * @param {Function} eachFunc The function to iterate over a collection. + * @returns {Function} Returns the new each function. + */ + function createReduce(arrayFunc, eachFunc) { + return function(collection, iteratee, accumulator, thisArg) { + var initFromArray = arguments.length < 3; + return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) + ? arrayFunc(collection, iteratee, accumulator, initFromArray) + : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); + }; } - return -1; - } - /** - * The base implementation of `_.isFunction` without support for environments - * with incorrect `typeof` results. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - */ - function baseIsFunction(value) { - // Avoid a Chakra JIT bug in compatibility modes of IE 11. - // See https://github.com/jashkenas/underscore/issues/1621 for more details. - return typeof value == 'function' || false; - } + /** + * Creates a function that wraps `func` and invokes it with optional `this` + * binding of, partial application, and currying. + * + * @private + * @param {Function|string} func The function or method name to reference. + * @param {number} bitmask The bitmask of flags. See `createWrapper` 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 createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { + var isAry = bitmask & ARY_FLAG, + isBind = bitmask & BIND_FLAG, + isBindKey = bitmask & BIND_KEY_FLAG, + isCurry = bitmask & CURRY_FLAG, + isCurryBound = bitmask & CURRY_BOUND_FLAG, + isCurryRight = bitmask & CURRY_RIGHT_FLAG; - /** - * Converts `value` to a string if it is not one. An empty string is returned - * for `null` or `undefined` values. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - if (typeof value == 'string') { - return value; - } - return value == null ? '' : (value + ''); - } + var Ctor = !isBindKey && createCtorWrapper(func), + key = func; - /** - * Used by `_.max` and `_.min` as the default callback for string values. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the code unit of the first character of the string. - */ - function charAtCallback(string) { - return string.charCodeAt(0); - } + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it to other functions. + var length = arguments.length, + index = length, + args = Array(length); - /** - * Used by `_.trim` and `_.trimLeft` to get the index of the first character - * of `string` that is not found in `chars`. - * - * @private - * @param {string} string The string to inspect. - * @param {string} chars The characters to find. - * @returns {number} Returns the index of the first character not found in `chars`. - */ - function charsLeftIndex(string, chars) { - var index = -1, - length = string.length; + while (index--) { + args[index] = arguments[index]; + } + if (partials) { + args = composeArgs(args, partials, holders); + } + if (partialsRight) { + args = composeArgsRight(args, partialsRight, holdersRight); + } + if (isCurry || isCurryRight) { + var placeholder = wrapper.placeholder, + argsHolders = replaceHolders(args, placeholder); - while (++index < length && chars.indexOf(string.charAt(index)) > -1) {} - return index; - } + length -= argsHolders.length; + if (length < arity) { + var newArgPos = argPos ? arrayCopy(argPos) : null, + newArity = nativeMax(arity - length, 0), + newsHolders = isCurry ? argsHolders : null, + newHoldersRight = isCurry ? null : argsHolders, + newPartials = isCurry ? args : null, + newPartialsRight = isCurry ? null : args; - /** - * Used by `_.trim` and `_.trimRight` to get the index of the last character - * of `string` that is not found in `chars`. - * - * @private - * @param {string} string The string to inspect. - * @param {string} chars The characters to find. - * @returns {number} Returns the index of the last character not found in `chars`. - */ - function charsRightIndex(string, chars) { - var index = string.length; + bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); + bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); - while (index-- && chars.indexOf(string.charAt(index)) > -1) {} - return index; - } + if (!isCurryBound) { + bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); + } + var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], + result = createHybridWrapper.apply(undefined, newData); - /** - * Used by `_.sortBy` to compare transformed elements of a collection and stable - * sort them in ascending order. - * - * @private - * @param {Object} object The object to compare to `other`. - * @param {Object} other The object to compare to `object`. - * @returns {number} Returns the sort order indicator for `object`. - */ - function compareAscending(object, other) { - return baseCompareAscending(object.criteria, other.criteria) || (object.index - other.index); - } - - /** - * Used by `_.sortByOrder` to compare multiple properties of each element - * in a collection and stable sort them in the following order: - * - * If `orders` is unspecified, sort in ascending order for all properties. - * Otherwise, for each property, sort in ascending order if its corresponding value in - * orders is true, and descending order if false. - * - * @private - * @param {Object} object The object to compare to `other`. - * @param {Object} other The object to compare to `object`. - * @param {boolean[]} 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 = baseCompareAscending(objCriteria[index], othCriteria[index]); - if (result) { - if (index >= ordersLength) { - return result; + if (isLaziable(func)) { + setData(result, newData); + } + result.placeholder = placeholder; + return result; + } } - return result * (orders[index] ? 1 : -1); + var thisBinding = isBind ? thisArg : this; + if (isBindKey) { + func = thisBinding[key]; + } + if (argPos) { + args = reorder(args, argPos); + } + if (isAry && ary < args.length) { + args.length = ary; + } + var fn = (this && this !== root && this instanceof wrapper) ? (Ctor || createCtorWrapper(func)) : func; + return fn.apply(thisBinding, args); } + return wrapper; } - // 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://code.google.com/p/v8/issues/detail?id=90 for more details. - return object.index - other.index; - } - - /** - * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters. - * - * @private - * @param {string} letter The matched letter to deburr. - * @returns {string} Returns the deburred letter. - */ - function deburrLetter(letter) { - return deburredLetters[letter]; - } - - /** - * Used by `_.escape` to convert characters to HTML entities. - * - * @private - * @param {string} chr The matched character to escape. - * @returns {string} Returns the escaped character. - */ - function escapeHtmlChar(chr) { - return htmlEscapes[chr]; - } - - /** - * 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 index at which the first occurrence of `NaN` is found in `array`. - * - * @private - * @param {Array} array The array to search. - * @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 `NaN`, else `-1`. - */ - function indexOfNaN(array, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 0 : -1); + /** + * Creates the padding required for `string` based on the given `length`. + * The `chars` string is truncated if the number of characters exceeds `length`. + * + * @private + * @param {string} string The string to create padding for. + * @param {number} [length=0] The padding length. + * @param {string} [chars=' '] The string used as padding. + * @returns {string} Returns the pad for `string`. + */ + function createPadding(string, length, chars) { + var strLength = string.length; + length = +length; - while ((fromRight ? index-- : ++index < length)) { - var other = array[index]; - if (other !== other) { - return index; + if (strLength >= length || !nativeIsFinite(length)) { + return ''; } + var padLength = length - strLength; + chars = chars == null ? ' ' : (chars + ''); + return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength); } - return -1; - } - - /** - * Checks if `value` is object-like. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - */ - function isObjectLike(value) { - return !!value && typeof value == 'object'; - } - /** - * Used by `trimmedLeftIndex` and `trimmedRightIndex` to determine if a - * character code is whitespace. - * - * @private - * @param {number} charCode The character code to inspect. - * @returns {boolean} Returns `true` if `charCode` is whitespace, else `false`. - */ - function isSpace(charCode) { - return ((charCode <= 160 && (charCode >= 9 && charCode <= 13) || charCode == 32 || charCode == 160) || charCode == 5760 || charCode == 6158 || - (charCode >= 8192 && (charCode <= 8202 || charCode == 8232 || charCode == 8233 || charCode == 8239 || charCode == 8287 || charCode == 12288 || charCode == 65279))); - } + /** + * Creates a function that wraps `func` and invokes it with the optional `this` + * binding of `thisArg` and the `partials` prepended to those provided to + * the wrapper. + * + * @private + * @param {Function} func The function to partially apply arguments to. + * @param {number} bitmask The bitmask of flags. See `createWrapper` 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 bound function. + */ + function createPartialWrapper(func, bitmask, thisArg, partials) { + var isBind = bitmask & BIND_FLAG, + Ctor = createCtorWrapper(func); - /** - * 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 = -1, - result = []; + function wrapper() { + // Avoid `arguments` object use disqualifying optimizations by + // converting it to an array before providing it `func`. + var argsIndex = -1, + argsLength = arguments.length, + leftIndex = -1, + leftLength = partials.length, + args = Array(argsLength + leftLength); - while (++index < length) { - if (array[index] === placeholder) { - array[index] = PLACEHOLDER; - result[++resIndex] = index; + while (++leftIndex < leftLength) { + args[leftIndex] = partials[leftIndex]; + } + while (argsLength--) { + args[leftIndex++] = arguments[++argsIndex]; + } + var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; + return fn.apply(isBind ? thisArg : this, args); } + return wrapper; } - return result; - } - - /** - * An implementation of `_.uniq` optimized for sorted arrays without support - * for callback shorthands and `this` binding. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. - */ - function sortedUniq(array, iteratee) { - var seen, - index = -1, - length = array.length, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; - if (!index || seen !== computed) { - seen = computed; - result[++resIndex] = value; - } + /** + * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * + * @private + * @param {boolean} [retHighest] Specify returning the highest qualified index. + * @returns {Function} Returns the new index function. + */ + function createSortedIndex(retHighest) { + return function(array, value, iteratee, thisArg) { + var func = getCallback(iteratee); + return (func === baseCallback && iteratee == null) + ? binaryIndex(array, value, retHighest) + : binaryIndexBy(array, value, func(iteratee, thisArg, 1), retHighest); + }; } - return result; - } - /** - * Used by `_.trim` and `_.trimLeft` to get the index of the first non-whitespace - * character of `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the index of the first non-whitespace character. - */ - function trimmedLeftIndex(string) { - var index = -1, - length = string.length; - - while (++index < length && isSpace(string.charCodeAt(index))) {} - return index; - } - - /** - * Used by `_.trim` and `_.trimRight` to get the index of the last non-whitespace - * character of `string`. - * - * @private - * @param {string} string The string to inspect. - * @returns {number} Returns the index of the last non-whitespace character. - */ - function trimmedRightIndex(string) { - var index = string.length; + /** + * 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 reference. + * @param {number} bitmask The bitmask of flags. + * The bitmask may be composed of the following flags: + * 1 - `_.bind` + * 2 - `_.bindKey` + * 4 - `_.curry` or `_.curryRight` of a bound function + * 8 - `_.curry` + * 16 - `_.curryRight` + * 32 - `_.partial` + * 64 - `_.partialRight` + * 128 - `_.rearg` + * 256 - `_.ary` + * @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 createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { + var isBindKey = bitmask & BIND_KEY_FLAG; + if (!isBindKey && typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + var length = partials ? partials.length : 0; + if (!length) { + bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); + partials = holders = null; + } + length -= (holders ? holders.length : 0); + if (bitmask & PARTIAL_RIGHT_FLAG) { + var partialsRight = partials, + holdersRight = holders; - while (index-- && isSpace(string.charCodeAt(index))) {} - return index; - } + partials = holders = null; + } + var data = isBindKey ? null : getData(func), + newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; - /** - * Used by `_.unescape` to convert HTML entities to characters. - * - * @private - * @param {string} chr The matched character to unescape. - * @returns {string} Returns the unescaped character. - */ - function unescapeHtmlChar(chr) { - return htmlUnescapes[chr]; - } + if (data) { + mergeData(newData, data); + bitmask = newData[1]; + arity = newData[9]; + } + newData[9] = arity == null + ? (isBindKey ? 0 : func.length) + : (nativeMax(arity - length, 0) || 0); - /*--------------------------------------------------------------------------*/ + if (bitmask == BIND_FLAG) { + var result = createBindWrapper(newData[0], newData[2]); + } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { + result = createPartialWrapper.apply(undefined, newData); + } else { + result = createHybridWrapper.apply(undefined, newData); + } + var setter = data ? baseSetData : setData; + return setter(result, newData); + } - /** - * Create a new pristine `lodash` function using the given `context` object. - * - * @static - * @memberOf _ - * @category Utility - * @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 - * - * // using `context` to mock `Date#getTime` use in `_.now` - * var mock = _.runInContext({ - * 'Date': function() { - * return { 'getTime': getTimeMock }; - * } - * }); - * - * // or creating a suped-up `defer` in Node.js - * var defer = _.runInContext({ 'setTimeout': setImmediate }).defer; - */ - function runInContext(context) { - // Avoid issues with some ES3 environments that attempt to use values, named - // after built-in constructors like `Object`, for the creation of literals. - // ES5 clears this up by stating that literals must use built-in constructors. - // See https://es5.github.io/#x11.1.5 for more details. - context = context ? _.defaults(root.Object(), context, _.pick(root, contextProps)) : root; + /** + * A specialized version of `baseIsEqualDeep` for arrays with support for + * partial deep comparisons. + * + * @private + * @param {Array} array The array to compare. + * @param {Array} other The other array to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing arrays. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + */ + function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { + var index = -1, + arrLength = array.length, + othLength = other.length, + result = true; - /** Native constructor references. */ - var Array = context.Array, - Date = context.Date, - Error = context.Error, - Function = context.Function, - Math = context.Math, - Number = context.Number, - Object = context.Object, - RegExp = context.RegExp, - String = context.String, - TypeError = context.TypeError; + if (arrLength != othLength && !(isLoose && othLength > arrLength)) { + return false; + } + // Deep compare the contents, ignoring non-numeric properties. + while (result && ++index < arrLength) { + var arrValue = array[index], + othValue = other[index]; - /** Used for native method references. */ - var arrayProto = Array.prototype, - objectProto = Object.prototype, - stringProto = String.prototype; + result = undefined; + if (customizer) { + result = isLoose + ? customizer(othValue, arrValue, index) + : customizer(arrValue, othValue, index); + } + if (result === undefined) { + // Recursively compare arrays (susceptible to call stack limits). + if (isLoose) { + var othIndex = othLength; + while (othIndex--) { + othValue = other[othIndex]; + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + if (result) { + break; + } + } + } else { + result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); + } + } + } + return !!result; + } - /** Used to detect DOM support. */ - var document = (document = context.window) && document.document; + /** + * 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} value The object to compare. + * @param {Object} other The other object to compare. + * @param {string} tag The `toStringTag` of the objects to compare. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + */ + function equalByTag(object, other, tag) { + switch (tag) { + case boolTag: + case dateTag: + // Coerce dates and booleans to numbers, dates to milliseconds and booleans + // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. + return +object == +other; - /** Used to resolve the decompiled source of functions. */ - var fnToString = Function.prototype.toString; + case errorTag: + return object.name == other.name && object.message == other.message; - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; + case numberTag: + // Treat `NaN` vs. `NaN` as equal. + return (object != +object) + ? other != +other + : object == +other; - /** Used to generate unique IDs. */ - var idCounter = 0; + case regexpTag: + case stringTag: + // Coerce regexes to strings and treat strings primitives and string + // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. + return object == (other + ''); + } + return false; + } /** - * Used to resolve the [`toStringTag`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.prototype.tostring) - * of values. + * A specialized version of `baseIsEqualDeep` for objects with support for + * partial deep comparisons. + * + * @private + * @param {Object} object The object to compare. + * @param {Object} other The other object to compare. + * @param {Function} equalFunc The function to determine equivalents of values. + * @param {Function} [customizer] The function to customize comparing values. + * @param {boolean} [isLoose] Specify performing partial comparisons. + * @param {Array} [stackA] Tracks traversed `value` objects. + * @param {Array} [stackB] Tracks traversed `other` objects. + * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. */ - var objToString = objectProto.toString; - - /** Used to restore the original `_` reference in `_.noConflict`. */ - var oldDash = context._; - - /** Used to detect if a method is native. */ - var reIsNative = RegExp('^' + - escapeRegExp(objToString) - .replace(/toString|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$' - ); - - /** Native method references. */ - var ArrayBuffer = isNative(ArrayBuffer = context.ArrayBuffer) && ArrayBuffer, - bufferSlice = isNative(bufferSlice = ArrayBuffer && new ArrayBuffer(0).slice) && bufferSlice, - ceil = Math.ceil, - clearTimeout = context.clearTimeout, - floor = Math.floor, - getOwnPropertySymbols = isNative(getOwnPropertySymbols = Object.getOwnPropertySymbols) && getOwnPropertySymbols, - getPrototypeOf = isNative(getPrototypeOf = Object.getPrototypeOf) && getPrototypeOf, - push = arrayProto.push, - preventExtensions = isNative(Object.preventExtensions = Object.preventExtensions) && preventExtensions, - propertyIsEnumerable = objectProto.propertyIsEnumerable, - Set = isNative(Set = context.Set) && Set, - setTimeout = context.setTimeout, - splice = arrayProto.splice, - Uint8Array = isNative(Uint8Array = context.Uint8Array) && Uint8Array, - WeakMap = isNative(WeakMap = context.WeakMap) && WeakMap; - - /** Used to clone array buffers. */ - var Float64Array = (function() { - // Safari 5 errors when using an array buffer to initialize a typed array - // where the array buffer's `byteLength` is not a multiple of the typed - // array's `BYTES_PER_ELEMENT`. - try { - var func = isNative(func = context.Float64Array) && func, - result = new func(new ArrayBuffer(10), 0, 1) && func; - } catch(e) {} - return result; - }()); - - /** Used as `baseAssign`. */ - var nativeAssign = (function() { - // Avoid `Object.assign` in Firefox 34-37 which have an early implementation - // with a now defunct try/catch behavior. See https://bugzilla.mozilla.org/show_bug.cgi?id=1103344 - // for more details. - // - // Use `Object.preventExtensions` on a plain object instead of simply using - // `Object('x')` because Chrome and IE fail to throw an error when attempting - // to assign values to readonly indexes of strings in strict mode. - var object = { '1': 0 }, - func = preventExtensions && isNative(func = Object.assign) && func; - - try { func(preventExtensions(object), 'xo'); } catch(e) {} - return !object[1] && func; - }()); - - /* Native method references for those with the same name as other `lodash` methods. */ - var nativeIsArray = isNative(nativeIsArray = Array.isArray) && nativeIsArray, - nativeCreate = isNative(nativeCreate = Object.create) && nativeCreate, - nativeIsFinite = context.isFinite, - nativeKeys = isNative(nativeKeys = Object.keys) && nativeKeys, - nativeMax = Math.max, - nativeMin = Math.min, - nativeNow = isNative(nativeNow = Date.now) && nativeNow, - nativeNumIsFinite = isNative(nativeNumIsFinite = Number.isFinite) && nativeNumIsFinite, - nativeParseInt = context.parseInt, - nativeRandom = Math.random; - - /** Used as references for `-Infinity` and `Infinity`. */ - var NEGATIVE_INFINITY = Number.NEGATIVE_INFINITY, - POSITIVE_INFINITY = Number.POSITIVE_INFINITY; - - /** Used as references for the maximum length and index of an array. */ - var MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1, - MAX_ARRAY_INDEX = MAX_ARRAY_LENGTH - 1, - HALF_MAX_ARRAY_LENGTH = MAX_ARRAY_LENGTH >>> 1; + function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { + var objProps = keys(object), + objLength = objProps.length, + othProps = keys(other), + othLength = othProps.length; - /** Used as the size, in bytes, of each `Float64Array` element. */ - var FLOAT64_BYTES_PER_ELEMENT = Float64Array ? Float64Array.BYTES_PER_ELEMENT : 0; + if (objLength != othLength && !isLoose) { + return false; + } + var skipCtor = isLoose, + index = -1; - /** - * Used as the [maximum length](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer) - * of an array-like value. - */ - var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1; + while (++index < objLength) { + var key = objProps[index], + result = isLoose ? key in other : hasOwnProperty.call(other, key); - /** Used to store function metadata. */ - var metaMap = WeakMap && new WeakMap; + if (result) { + var objValue = object[key], + othValue = other[key]; - /** Used to lookup unminified function names. */ - var realNames = {}; + result = undefined; + if (customizer) { + result = isLoose + ? customizer(othValue, objValue, key) + : customizer(objValue, othValue, key); + } + if (result === undefined) { + // Recursively compare objects (susceptible to call stack limits). + result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB); + } + } + if (!result) { + return false; + } + skipCtor || (skipCtor = key == 'constructor'); + } + if (!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)) { + return false; + } + } + return true; + } /** - * Creates a `lodash` object which wraps `value` to enable implicit chaining. - * Methods that operate on and return arrays, collections, and functions can - * be chained together. Methods that return a boolean or single value will - * automatically end the chain returning the unwrapped value. Explicit chaining - * may be enabled using `_.chain`. The execution of chained methods is lazy, - * that is, execution is deferred until `_#value` is implicitly or explicitly - * called. - * - * Lazy evaluation allows several methods to support shortcut fusion. Shortcut - * fusion is an optimization that merges iteratees to avoid creating intermediate - * arrays and reduce the number of iteratee executions. - * - * 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`, `reverse`, `shift`, `slice`, `sort`, - * `splice`, and `unshift` - * - * The wrapper `String` methods are: - * `replace` and `split` - * - * The wrapper methods that support shortcut fusion are: - * `compact`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `filter`, - * `first`, `initial`, `last`, `map`, `pluck`, `reject`, `rest`, `reverse`, - * `slice`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `toArray`, - * and `where` - * - * The chainable wrapper methods are: - * `after`, `ary`, `assign`, `at`, `before`, `bind`, `bindAll`, `bindKey`, - * `callback`, `chain`, `chunk`, `commit`, `compact`, `concat`, `constant`, - * `countBy`, `create`, `curry`, `debounce`, `defaults`, `defer`, `delay`, - * `difference`, `drop`, `dropRight`, `dropRightWhile`, `dropWhile`, `fill`, - * `filter`, `flatten`, `flattenDeep`, `flow`, `flowRight`, `forEach`, - * `forEachRight`, `forIn`, `forInRight`, `forOwn`, `forOwnRight`, `functions`, - * `groupBy`, `indexBy`, `initial`, `intersection`, `invert`, `invoke`, `keys`, - * `keysIn`, `map`, `mapValues`, `matches`, `matchesProperty`, `memoize`, - * `merge`, `mixin`, `negate`, `omit`, `once`, `pairs`, `partial`, `partialRight`, - * `partition`, `pick`, `plant`, `pluck`, `property`, `propertyOf`, `pull`, - * `pullAt`, `push`, `range`, `rearg`, `reject`, `remove`, `rest`, `reverse`, - * `shuffle`, `slice`, `sort`, `sortBy`, `sortByAll`, `sortByOrder`, `splice`, - * `spread`, `take`, `takeRight`, `takeRightWhile`, `takeWhile`, `tap`, - * `throttle`, `thru`, `times`, `toArray`, `toPlainObject`, `transform`, - * `union`, `uniq`, `unshift`, `unzip`, `values`, `valuesIn`, `where`, - * `without`, `wrap`, `xor`, `zip`, and `zipObject` - * - * The wrapper methods that are **not** chainable by default are: - * `add`, `attempt`, `camelCase`, `capitalize`, `clone`, `cloneDeep`, `deburr`, - * `endsWith`, `escape`, `escapeRegExp`, `every`, `find`, `findIndex`, `findKey`, - * `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`, - * `identity`, `includes`, `indexOf`, `inRange`, `isArguments`, `isArray`, - * `isBoolean`, `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite` - * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`, `isObject`, - * `isPlainObject`, `isRegExp`, `isString`, `isUndefined`, `isTypedArray`, - * `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`, `noConflict`, - * `noop`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`, `random`, - * `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`, `shift`, `size`, - * `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`, `startCase`, `startsWith`, - * `sum`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`, `unescape`, - * `uniqueId`, `value`, and `words` - * - * The wrapper method `sample` will return a wrapped value when `n` is provided, - * otherwise an unwrapped value is returned. - * - * @name _ - * @constructor - * @category Chain - * @param {*} value The value to wrap in a `lodash` instance. - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example - * - * var wrapped = _([1, 2, 3]); - * - * // returns an unwrapped value - * wrapped.reduce(function(total, n) { - * return total + n; - * }); - * // => 6 - * - * // returns a wrapped value - * var squares = wrapped.map(function(n) { - * return n * n; - * }); - * - * _.isArray(squares); - * // => false + * Gets the extremum value of `collection` invoking `iteratee` for each value + * in `collection` to generate the criterion by which the value is ranked. + * The `iteratee` is invoked with three arguments: (value, index, collection). * - * _.isArray(squares.value()); - * // => true + * @private + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {boolean} [isMin] Specify returning the minimum, instead of the + * maximum, extremum value. + * @returns {*} Returns the extremum value. */ - function lodash(value) { - if (isObjectLike(value) && !isArray(value) && !(value instanceof LazyWrapper)) { - if (value instanceof LodashWrapper) { - return value; - } - if (hasOwnProperty.call(value, '__chain__') && hasOwnProperty.call(value, '__wrapped__')) { - return wrapperClone(value); + function extremumBy(collection, iteratee, isMin) { + var exValue = isMin ? POSITIVE_INFINITY : NEGATIVE_INFINITY, + computed = exValue, + result = computed; + + baseEach(collection, function(value, index, collection) { + var current = iteratee(value, index, collection); + if ((isMin ? (current < computed) : (current > computed)) || + (current === exValue && current === result)) { + computed = current; + result = value; } - } - return new LodashWrapper(value); + }); + return result; } /** - * The function whose prototype all chaining wrappers inherit from. + * Gets the appropriate "callback" function. If the `_.callback` method is + * customized this function returns the custom method, otherwise it returns + * the `baseCallback` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. * * @private + * @returns {Function} Returns the chosen function or its result. */ - function baseLodash() { - // No operation performed. + function getCallback(func, thisArg, argCount) { + var result = lodash.callback || callback; + result = result === callback ? baseCallback : result; + return argCount ? result(func, thisArg, argCount) : result; } /** - * The base constructor for creating `lodash` wrapper objects. + * Gets metadata for `func`. * * @private - * @param {*} value The value to wrap. - * @param {boolean} [chainAll] Enable chaining for all wrapper methods. - * @param {Array} [actions=[]] Actions to peform to resolve the unwrapped value. + * @param {Function} func The function to query. + * @returns {*} Returns the metadata for `func`. */ - function LodashWrapper(value, chainAll, actions) { - this.__wrapped__ = value; - this.__actions__ = actions || []; - this.__chain__ = !!chainAll; - } + var getData = !metaMap ? noop : function(func) { + return metaMap.get(func); + }; /** - * An object environment feature flags. + * Gets the name of `func`. * - * @static - * @memberOf _ - * @type Object + * @private + * @param {Function} func The function to query. + * @returns {string} Returns the function name. */ - var support = lodash.support = {}; - - (function(x) { - var Ctor = function() { this.x = x; }, - object = { '0': x, 'length': x }, - props = []; - - Ctor.prototype = { 'valueOf': x, 'y': x }; - for (var key in new Ctor) { props.push(key); } - - /** - * Detect if functions can be decompiled by `Function#toString` - * (all but Firefox OS certified apps, older Opera mobile browsers, and - * the PlayStation 3; forced `false` for Windows 8 apps). - * - * @memberOf _.support - * @type boolean - */ - support.funcDecomp = /\bthis\b/.test(function() { return this; }); - - /** - * Detect if `Function#name` is supported (all but IE). - * - * @memberOf _.support - * @type boolean - */ - support.funcNames = typeof Function.name == 'string'; - - /** - * Detect if the DOM is supported. - * - * @memberOf _.support - * @type boolean - */ - try { - support.dom = document.createDocumentFragment().nodeType === 11; - } catch(e) { - support.dom = false; + var getFuncName = (function() { + if (!support.funcNames) { + return constant(''); } - - /** - * Detect if `arguments` object indexes are non-enumerable. - * - * In Firefox < 4, IE < 9, PhantomJS, and Safari < 5.1 `arguments` object - * indexes are non-enumerable. Chrome < 25 and Node.js < 0.11.0 treat - * `arguments` object indexes as non-enumerable and fail `hasOwnProperty` - * checks for indexes that exceed the number of function parameters and - * whose associated argument values are `0`. - * - * @memberOf _.support - * @type boolean - */ - try { - support.nonEnumArgs = !propertyIsEnumerable.call(arguments, 1); - } catch(e) { - support.nonEnumArgs = true; + if (constant.name == 'constant') { + return baseProperty('name'); } - }(1, 0)); + return function(func) { + var result = func.name, + array = realNames[result], + length = array ? array.length : 0; + + while (length--) { + var data = array[length], + otherFunc = data.func; + + if (otherFunc == null || otherFunc == func) { + return data.name; + } + } + return result; + }; + }()); /** - * By default, the template delimiters used by lodash are like those in - * embedded Ruby (ERB). Change the following template settings to use - * alternative delimiters. + * Gets the appropriate "indexOf" function. If the `_.indexOf` method is + * customized this function returns the custom method, otherwise it returns + * the `baseIndexOf` function. If arguments are provided the chosen function + * is invoked with them and its result is returned. * - * @static - * @memberOf _ - * @type Object + * @private + * @returns {Function|number} Returns the chosen function or its result. */ - 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 - } - }; + function getIndexOf(collection, target, fromIndex) { + var result = lodash.indexOf || indexOf; + result = result === indexOf ? baseIndexOf : result; + return collection ? result(collection, target, fromIndex) : result; + } - /*------------------------------------------------------------------------*/ + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) + * that affects Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); /** - * Creates a lazy wrapper object which wraps `value` to enable lazy evaluation. + * Creates an array of the own symbols of `object`. * * @private - * @param {*} value The value to wrap. + * @param {Object} object The object to query. + * @returns {Array} Returns the array of symbols. */ - function LazyWrapper(value) { - this.__wrapped__ = value; - this.__actions__ = null; - this.__dir__ = 1; - this.__dropCount__ = 0; - this.__filtered__ = false; - this.__iteratees__ = null; - this.__takeCount__ = POSITIVE_INFINITY; - this.__views__ = null; - } + var getSymbols = !getOwnPropertySymbols ? constant([]) : function(object) { + return getOwnPropertySymbols(toObject(object)); + }; /** - * Creates a clone of the lazy wrapper object. + * Gets the view, applying any `transforms` to the `start` and `end` positions. * * @private - * @name clone - * @memberOf LazyWrapper - * @returns {Object} Returns the cloned `LazyWrapper` object. + * @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 lazyClone() { - var actions = this.__actions__, - iteratees = this.__iteratees__, - views = this.__views__, - result = new LazyWrapper(this.__wrapped__); + function getView(start, end, transforms) { + var index = -1, + length = transforms ? transforms.length : 0; - result.__actions__ = actions ? arrayCopy(actions) : null; - result.__dir__ = this.__dir__; - result.__filtered__ = this.__filtered__; - result.__iteratees__ = iteratees ? arrayCopy(iteratees) : null; - result.__takeCount__ = this.__takeCount__; - result.__views__ = views ? arrayCopy(views) : null; - return result; + 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 }; } /** - * Reverses the direction of lazy iteration. + * Initializes an array clone. * * @private - * @name reverse - * @memberOf LazyWrapper - * @returns {Object} Returns the new reversed `LazyWrapper` object. + * @param {Array} array The array to clone. + * @returns {Array} Returns the initialized clone. */ - function lazyReverse() { - if (this.__filtered__) { - var result = new LazyWrapper(this); - result.__dir__ = -1; - result.__filtered__ = true; - } else { - result = this.clone(); - result.__dir__ *= -1; + function initCloneArray(array) { + var length = array.length, + result = new array.constructor(length); + + // Add array 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; } /** - * Extracts the unwrapped value from its lazy wrapper. + * Initializes an object clone. * * @private - * @name value - * @memberOf LazyWrapper - * @returns {*} Returns the unwrapped value. + * @param {Object} object The object to clone. + * @returns {Object} Returns the initialized clone. */ - function lazyValue() { - var array = this.__wrapped__.value(); - if (!isArray(array)) { - return baseWrapperValue(array, this.__actions__); + function initCloneObject(object) { + var Ctor = object.constructor; + if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { + Ctor = Object; } - var dir = this.__dir__, - isRight = dir < 0, - view = getView(0, array.length, this.__views__), - start = view.start, - end = view.end, - length = end - start, - index = isRight ? end : (start - 1), - takeCount = nativeMin(length, this.__takeCount__), - iteratees = this.__iteratees__, - iterLength = iteratees ? iteratees.length : 0, - resIndex = 0, - result = []; + return new Ctor; + } - outer: - while (length-- && resIndex < takeCount) { - index += dir; + /** + * Initializes an object clone based on its `toStringTag`. + * + * **Note:** This function only supports cloning values with tags of + * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * + * @private + * @param {Object} object The object to clone. + * @param {string} tag The `toStringTag` of the object to clone. + * @param {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 bufferClone(object); - var iterIndex = -1, - value = array[index]; + case boolTag: + case dateTag: + return new Ctor(+object); - while (++iterIndex < iterLength) { - var data = iteratees[iterIndex], - iteratee = data.iteratee, - type = data.type; + case float32Tag: case float64Tag: + case int8Tag: case int16Tag: case int32Tag: + case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: + var buffer = object.buffer; + return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); - if (type == LAZY_DROP_WHILE_FLAG) { - if (data.done && (isRight ? (index > data.index) : (index < data.index))) { - data.count = 0; - data.done = false; - } - data.index = index; - if (!data.done) { - var limit = data.limit; - if (!(data.done = limit > -1 ? (data.count++ >= limit) : !iteratee(value))) { - continue outer; - } - } - } else { - var 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; + case numberTag: + case stringTag: + return new Ctor(object); + + case regexpTag: + var result = new Ctor(object.source, reFlags.exec(object)); + result.lastIndex = object.lastIndex; } return result; } - /*------------------------------------------------------------------------*/ - /** - * Creates a cache object to store key/value pairs. + * Invokes the method at `path` on `object`. * * @private - * @static - * @name Cache - * @memberOf _.memoize + * @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 MapCache() { - this.__data__ = {}; + function invokePath(object, path, args) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); + } + var func = object == null ? object : object[path]; + return func == null ? undefined : func.apply(object, args); } /** - * Removes `key` and its value from the cache. + * Checks if `value` is array-like. * * @private - * @name delete - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to remove. - * @returns {boolean} Returns `true` if the entry was removed successfully, else `false`. + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. */ - function mapDelete(key) { - return this.has(key) && delete this.__data__[key]; + function isArrayLike(value) { + return value != null && isLength(getLength(value)); } /** - * Gets the cached value for `key`. + * Checks if `value` is a valid array-like index. * * @private - * @name get - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to get. - * @returns {*} Returns the cached value. + * @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 mapGet(key) { - return key == '__proto__' ? undefined : this.__data__[key]; + function isIndex(value, length) { + value = +value; + length = length == null ? MAX_SAFE_INTEGER : length; + return value > -1 && value % 1 == 0 && value < length; } /** - * Checks if a cached value for `key` exists. + * Checks if the provided arguments are from an iteratee call. * * @private - * @name has - * @memberOf _.memoize.Cache - * @param {string} key The key of the entry to check. - * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`. + * @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 mapHas(key) { - return key != '__proto__' && hasOwnProperty.call(this.__data__, key); + 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)) { + var other = object[index]; + return value === value ? (value === other) : (other !== other); + } + return false; } /** - * Sets `value` to `key` of the cache. + * Checks if `value` is a property name and not a property path. * * @private - * @name set - * @memberOf _.memoize.Cache - * @param {string} key The key of the value to cache. - * @param {*} value The value to cache. - * @returns {Object} Returns the cache object. + * @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 mapSet(key, value) { - if (key != '__proto__') { - this.__data__[key] = value; + function isKey(value, object) { + var type = typeof value; + if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { + return true; } - return this; + if (isArray(value)) { + return false; + } + var result = !reIsDeepProp.test(value); + return result || (object != null && value in toObject(object)); } - /*------------------------------------------------------------------------*/ - /** - * - * Creates a cache object to store unique values. + * Checks if `func` has a lazy counterpart. * * @private - * @param {Array} [values] The values to cache. + * @param {Function} func The function to check. + * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. */ - function SetCache(values) { - var length = values ? values.length : 0; - - this.data = { 'hash': nativeCreate(null), 'set': new Set }; - while (length--) { - this.push(values[length]); - } + function isLaziable(func) { + var funcName = getFuncName(func); + return !!funcName && func === lodash[funcName] && funcName in LazyWrapper.prototype; } /** - * Checks if `value` is in `cache` mimicking the return signature of - * `_.indexOf` by returning `0` if the value is found, else `-1`. + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). * * @private - * @param {Object} cache The cache to search. - * @param {*} value The value to search for. - * @returns {number} Returns `0` if `value` is found, else `-1`. + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. */ - function cacheIndexOf(cache, value) { - var data = cache.data, - result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value]; - - return result ? 0 : -1; + function isLength(value) { + return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } /** - * Adds `value` to the cache. + * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. * * @private - * @name push - * @memberOf SetCache - * @param {*} value The value to cache. + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` if suitable for strict + * equality comparisons, else `false`. */ - function cachePush(value) { - var data = this.data; - if (typeof value == 'string' || isObject(value)) { - data.set.add(value); - } else { - data.hash[value] = true; - } + function isStrictComparable(value) { + return value === value && !isObject(value); } - /*------------------------------------------------------------------------*/ - /** - * Copies the values of `source` to `array`. + * Merges the function metadata of `source` into `data`. + * + * Merging metadata reduces the number of wrappers required 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` + * augment function arguments, making the order in which they are executed important, + * preventing the merging of metadata. However, we make an exception for a safe + * common case where curried functions have `_.ary` and or `_.rearg` applied. * * @private - * @param {Array} source The array to copy values from. - * @param {Array} [array=[]] The array to copy values to. - * @returns {Array} Returns `array`. + * @param {Array} data The destination metadata. + * @param {Array} source The source metadata. + * @returns {Array} Returns `data`. */ - function arrayCopy(source, array) { - var index = -1, - length = source.length; + function mergeData(data, source) { + var bitmask = data[1], + srcBitmask = source[1], + newBitmask = bitmask | srcBitmask, + isCommon = newBitmask < ARY_FLAG; - array || (array = Array(length)); - while (++index < length) { - array[index] = source[index]; + var isCombo = + (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || + (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || + (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); + + // Exit early if metadata can't be merged. + if (!(isCommon || isCombo)) { + return data; } - return array; + // Use source `thisArg` if available. + if (srcBitmask & BIND_FLAG) { + data[2] = source[2]; + // Set when currying a bound function. + newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; + } + // Compose partial arguments. + var value = source[3]; + if (value) { + var partials = data[3]; + data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); + data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); + } + // Compose partial right arguments. + value = source[5]; + if (value) { + partials = data[5]; + data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); + data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); + } + // Use source `argPos` if available. + value = source[7]; + if (value) { + data[7] = arrayCopy(value); + } + // Use source `ary` if it's smaller. + if (srcBitmask & ARY_FLAG) { + data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); + } + // Use source `arity` if one is not provided. + if (data[9] == null) { + data[9] = source[9]; + } + // Use source `func` and merge bitmasks. + data[0] = source[0]; + data[1] = newBitmask; + + return data; } /** - * A specialized version of `_.forEach` for arrays without support for callback - * shorthands and `this` binding. + * A specialized version of `_.pick` which picks `object` properties specified + * by `props`. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. + * @param {Object} object The source object. + * @param {string[]} props The property names to pick. + * @returns {Object} Returns the new object. */ - function arrayEach(array, iteratee) { + function pickByArray(object, props) { + object = toObject(object); + var index = -1, - length = array.length; + length = props.length, + result = {}; while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; + var key = props[index]; + if (key in object) { + result[key] = object[key]; } } - return array; + return result; } /** - * A specialized version of `_.forEachRight` for arrays without support for - * callback shorthands and `this` binding. + * A specialized version of `_.pick` which picks `object` properties `predicate` + * returns truthy for. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. + * @param {Object} object The source object. + * @param {Function} predicate The function invoked per iteration. + * @returns {Object} Returns the new object. */ - function arrayEachRight(array, iteratee) { - var length = array.length; - - while (length--) { - if (iteratee(array[length], length, array) === false) { - break; + function pickByCallback(object, predicate) { + var result = {}; + baseForIn(object, function(value, key, object) { + if (predicate(value, key, object)) { + result[key] = value; } - } - return array; + }); + return result; } /** - * A specialized version of `_.every` for arrays without support for callback - * shorthands and `this` binding. + * 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 iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. + * @param {Array} array The array to reorder. + * @param {Array} indexes The arranged array indexes. + * @returns {Array} Returns `array`. */ - function arrayEvery(array, predicate) { - var index = -1, - length = array.length; + function reorder(array, indexes) { + var arrLength = array.length, + length = nativeMin(indexes.length, arrLength), + oldArray = arrayCopy(array); - while (++index < length) { - if (!predicate(array[index], index, array)) { - return false; - } + while (length--) { + var index = indexes[length]; + array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; } - return true; + return array; } /** - * A specialized version of `_.filter` for arrays without support for callback - * shorthands and `this` binding. + * 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://code.google.com/p/v8/issues/detail?id=2070) + * for more details. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. + * @param {Function} func The function to associate metadata with. + * @param {*} data The metadata. + * @returns {Function} Returns `func`. */ - function arrayFilter(array, predicate) { - var index = -1, - length = array.length, - resIndex = -1, - result = []; + var setData = (function() { + var count = 0, + lastCalled = 0; - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result[++resIndex] = value; + return function(key, value) { + var stamp = now(), + remaining = HOT_SPAN - (stamp - lastCalled); + + lastCalled = stamp; + if (remaining > 0) { + if (++count >= HOT_COUNT) { + return key; + } + } else { + count = 0; } - } - return result; - } + return baseSetData(key, value); + }; + }()); /** - * A specialized version of `_.map` for arrays without support for callback - * shorthands and `this` binding. + * A fallback implementation of `_.isPlainObject` which checks if `value` + * is an object created by the `Object` constructor or has a `[[Prototype]]` + * of `null`. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. */ - function arrayMap(array, iteratee) { - var index = -1, - length = array.length, - result = Array(length); + function shimIsPlainObject(value) { + var Ctor, + support = lodash.support; - while (++index < length) { - result[index] = iteratee(array[index], index, array); + // Exit early for non `Object` objects. + if (!(isObjectLike(value) && objToString.call(value) == objectTag) || + (!hasOwnProperty.call(value, 'constructor') && + (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { + return false; } - return result; + // IE < 9 iterates inherited properties before own properties. If the first + // iterated property is an object's own property then there are no inherited + // enumerable properties. + var result; + // In most environments an object's own properties are iterated before + // its inherited properties. If the last iterated property is an object's + // own property then there are no inherited enumerable properties. + baseForIn(value, function(subValue, key) { + result = key; + }); + return result === undefined || hasOwnProperty.call(value, result); } /** - * A specialized version of `_.max` for arrays without support for iteratees. + * A fallback implementation of `Object.keys` which creates an array of the + * own enumerable property names of `object`. * * @private - * @param {Array} array The array to iterate over. - * @returns {*} Returns the maximum value. + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. */ - function arrayMax(array) { + function shimKeys(object) { + var props = keysIn(object), + propsLength = props.length, + length = propsLength && object.length, + support = lodash.support; + + var allowIndexes = length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))); + var index = -1, - length = array.length, - result = NEGATIVE_INFINITY; + result = []; - while (++index < length) { - var value = array[index]; - if (value > result) { - result = value; + while (++index < propsLength) { + var key = props[index]; + if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { + result.push(key); } } return result; } /** - * A specialized version of `_.min` for arrays without support for iteratees. + * Converts `value` to an array-like object if it is not one. * * @private - * @param {Array} array The array to iterate over. - * @returns {*} Returns the minimum value. + * @param {*} value The value to process. + * @returns {Array|Object} Returns the array-like object. */ - function arrayMin(array) { - var index = -1, - length = array.length, - result = POSITIVE_INFINITY; - - while (++index < length) { - var value = array[index]; - if (value < result) { - result = value; - } + function toIterable(value) { + if (value == null) { + return []; } - return result; + if (!isArrayLike(value)) { + return values(value); + } + return isObject(value) ? value : Object(value); } /** - * A specialized version of `_.reduce` for arrays without support for callback - * shorthands and `this` binding. + * Converts `value` to an object if it is not one. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray] Specify using the first element of `array` - * as the initial value. - * @returns {*} Returns the accumulated value. + * @param {*} value The value to process. + * @returns {Object} Returns the object. */ - function arrayReduce(array, iteratee, accumulator, initFromArray) { - var index = -1, - length = array.length; - - if (initFromArray && length) { - accumulator = array[++index]; - } - while (++index < length) { - accumulator = iteratee(accumulator, array[index], index, array); - } - return accumulator; + function toObject(value) { + return isObject(value) ? value : Object(value); } /** - * A specialized version of `_.reduceRight` for arrays without support for - * callback shorthands and `this` binding. + * Converts `value` to property path array if it is not one. * * @private - * @param {Array} array The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {boolean} [initFromArray] Specify using the last element of `array` - * as the initial value. - * @returns {*} Returns the accumulated value. + * @param {*} value The value to process. + * @returns {Array} Returns the property path array. */ - function arrayReduceRight(array, iteratee, accumulator, initFromArray) { - var length = array.length; - if (initFromArray && length) { - accumulator = array[--length]; - } - while (length--) { - accumulator = iteratee(accumulator, array[length], length, array); + function toPath(value) { + if (isArray(value)) { + return value; } - return accumulator; + var result = []; + baseToString(value).replace(rePropName, function(match, number, quote, string) { + result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); + }); + return result; } /** - * A specialized version of `_.some` for arrays without support for callback - * shorthands and `this` binding. + * Creates a clone of `wrapper`. * * @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`. + * @param {Object} wrapper The wrapper to clone. + * @returns {Object} Returns the cloned wrapper. */ - function arraySome(array, predicate) { - var index = -1, - length = array.length; - - while (++index < length) { - if (predicate(array[index], index, array)) { - return true; - } - } - return false; + function wrapperClone(wrapper) { + return wrapper instanceof LazyWrapper + ? wrapper.clone() + : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); } /** - * A specialized version of `_.sum` for arrays without support for iteratees. + * Creates an array of elements split into groups the length of `size`. + * If `collection` can't be split evenly, the final chunk will be the remaining + * elements. * - * @private - * @param {Array} array The array to iterate over. - * @returns {number} Returns the sum. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to process. + * @param {number} [size=1] The length of each chunk. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new array containing chunks. + * @example + * + * _.chunk(['a', 'b', 'c', 'd'], 2); + * // => [['a', 'b'], ['c', 'd']] + * + * _.chunk(['a', 'b', 'c', 'd'], 3); + * // => [['a', 'b', 'c'], ['d']] */ - function arraySum(array) { - var length = array.length, - result = 0; + function chunk(array, size, guard) { + if (guard ? isIterateeCall(array, size, guard) : size == null) { + size = 1; + } else { + size = nativeMax(+size || 1, 1); + } + var index = 0, + length = array ? array.length : 0, + resIndex = -1, + result = Array(ceil(length / size)); - while (length--) { - result += +array[length] || 0; + while (index < length) { + result[++resIndex] = baseSlice(array, index, (index += size)); } return result; } /** - * Used by `_.defaults` to customize its `_.assign` use. - * - * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @returns {*} Returns the value to assign to the destination object. - */ - function assignDefaults(objectValue, sourceValue) { - return objectValue === undefined ? sourceValue : objectValue; - } - - /** - * Used by `_.template` to customize its `_.assign` use. - * - * **Note:** This function is like `assignDefaults` except that it ignores - * inherited property values when checking if a property is `undefined`. + * Creates an array with all falsey values removed. The values `false`, `null`, + * `0`, `""`, `undefined`, and `NaN` are falsey. * - * @private - * @param {*} objectValue The destination object property value. - * @param {*} sourceValue The source object property value. - * @param {string} key The key associated with the object and source values. - * @param {Object} object The destination object. - * @returns {*} Returns the value to assign to the destination object. - */ - function assignOwnDefaults(objectValue, sourceValue, key, object) { - return (objectValue === undefined || !hasOwnProperty.call(object, key)) - ? sourceValue - : objectValue; - } - - /** - * A specialized version of `_.assign` for customizing assigned values without - * support for argument juggling, multiple sources, and `this` binding `customizer` - * functions. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to compact. + * @returns {Array} Returns the new array of filtered values. + * @example * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} customizer The function to customize assigned values. - * @returns {Object} Returns `object`. + * _.compact([0, 1, false, 2, '', 3]); + * // => [1, 2, 3] */ - function assignWith(object, source, customizer) { - var props = keys(source); - push.apply(props, getSymbols(source)); - + function compact(array) { var index = -1, - length = props.length; + length = array ? array.length : 0, + resIndex = -1, + result = []; while (++index < length) { - var key = props[index], - value = object[key], - result = customizer(value, source[key], key, object, source); - - if ((result === result ? (result !== value) : (value === value)) || - (value === undefined && !(key in object))) { - object[key] = result; + var value = array[index]; + if (value) { + result[++resIndex] = value; } } - return object; + return result; } /** - * The base implementation of `_.assign` without support for argument juggling, - * multiple sources, and `customizer` functions. + * Creates an array excluding all values of the provided arrays using + * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for equality comparisons. * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @returns {Object} Returns `object`. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to inspect. + * @param {...Array} [values] The arrays of values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.difference([1, 2, 3], [4, 2]); + * // => [1, 3] */ - var baseAssign = nativeAssign || function(object, source) { - return source == null - ? object - : baseCopy(source, getSymbols(source), baseCopy(source, keys(source), object)); - }; + var difference = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, baseFlatten(values, false, true)) + : []; + }); /** - * The base implementation of `_.at` without support for string collections - * and individual key arguments. + * Creates a slice of `array` with `n` elements dropped from the beginning. * - * @private - * @param {Array|Object} collection The collection to iterate over. - * @param {number[]|string[]} props The property names or indexes of elements to pick. - * @returns {Array} Returns the new array of picked elements. + * @static + * @memberOf _ + * @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 a callback for functions 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 baseAt(collection, props) { - var index = -1, - length = collection.length, - isArr = isLength(length), - propsLength = props.length, - result = Array(propsLength); - - while(++index < propsLength) { - var key = props[index]; - if (isArr) { - result[index] = isIndex(key, length) ? collection[key] : undefined; - } else { - result[index] = collection[key]; - } + function drop(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; } - return result; + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, n < 0 ? 0 : n); } /** - * Copies properties of `source` to `object`. + * Creates a slice of `array` with `n` elements dropped from the end. * - * @private - * @param {Object} source The object to copy properties from. - * @param {Array} props The property names to copy. - * @param {Object} [object={}] The object to copy properties to. - * @returns {Object} Returns `object`. - */ - function baseCopy(source, props, object) { - object || (object = {}); - - var index = -1, - length = props.length; - - while (++index < length) { - var key = props[index]; - object[key] = source[key]; - } - return object; - } - - /** - * The base implementation of `_.callback` which supports specifying the - * number of arguments to provide to `func`. + * @static + * @memberOf _ + * @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 a callback for functions like `_.map`. + * @returns {Array} Returns the slice of `array`. + * @example * - * @private - * @param {*} [func=_.identity] The value to convert to a callback. - * @param {*} [thisArg] The `this` binding of `func`. - * @param {number} [argCount] The number of arguments to provide to `func`. - * @returns {Function} Returns the callback. + * _.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 baseCallback(func, thisArg, argCount) { - var type = typeof func; - if (type == 'function') { - return thisArg === undefined - ? func - : bindCallback(func, thisArg, argCount); - } - if (func == null) { - return identity; + function dropRight(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; } - if (type == 'object') { - return baseMatches(func); + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; } - return thisArg === undefined - ? property(func) - : baseMatchesProperty(func, thisArg); + n = length - (+n || 0); + return baseSlice(array, 0, n < 0 ? 0 : n); } /** - * The base implementation of `_.clone` without support for argument juggling - * and `this` binding `customizer` functions. + * Creates a slice of `array` excluding elements dropped from the end. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). * - * @private - * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {string} [key] The key of `value`. - * @param {Object} [object] The object `value` belongs to. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates clones with source counterparts. - * @returns {*} Returns the cloned value. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that match the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [1] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); + * // => ['barney'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropRightWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] */ - function baseClone(value, isDeep, customizer, key, object, stackA, stackB) { - var result; - if (customizer) { - result = object ? customizer(value, key, object) : customizer(value); - } - if (result !== undefined) { - return result; - } - if (!isObject(value)) { - return value; - } - var isArr = isArray(value); - if (isArr) { - result = initCloneArray(value); - if (!isDeep) { - return arrayCopy(value, result); - } - } else { - var tag = objToString.call(value), - isFunc = tag == funcTag; - - if (tag == objectTag || tag == argsTag || (isFunc && !object)) { - result = initCloneObject(isFunc ? {} : value); - if (!isDeep) { - return baseAssign(result, value); - } - } else { - return cloneableTags[tag] - ? initCloneByTag(value, tag, isDeep) - : (object ? value : {}); - } - } - // Check for circular references and return corresponding clone. - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == value) { - return stackB[length]; - } - } - // Add the source value to the stack of traversed objects and associate it with its clone. - stackA.push(value); - stackB.push(result); - - // Recursively populate clone (susceptible to call stack limits). - (isArr ? arrayEach : baseForOwn)(value, function(subValue, key) { - result[key] = baseClone(subValue, isDeep, customizer, key, value, stackA, stackB); - }); - return result; + function dropRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) + : []; } /** - * The base implementation of `_.create` without support for assigning - * properties to the created object. + * Creates a slice of `array` excluding elements dropped from the beginning. + * Elements are dropped until `predicate` returns falsey. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, index, array). * - * @private - * @param {Object} prototype The object to inherit from. - * @returns {Object} Returns the new object. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.dropWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [3] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.dropWhile(users, 'active', false), 'user'); + * // => ['pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.dropWhile(users, 'active'), 'user'); + * // => ['barney', 'fred', 'pebbles'] */ - var baseCreate = (function() { - function Object() {} - return function(prototype) { - if (isObject(prototype)) { - Object.prototype = prototype; - var result = new Object; - Object.prototype = null; - } - return result || context.Object(); - }; - }()); + function dropWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), true) + : []; + } /** - * The base implementation of `_.delay` and `_.defer` which accepts an index - * of where to slice the arguments to provide to `func`. + * Fills elements of `array` with `value` from `start` up to, but not + * including, `end`. * - * @private - * @param {Function} func The function to delay. - * @param {number} wait The number of milliseconds to delay invocation. - * @param {Object} args The arguments provide to `func`. - * @returns {number} Returns the timer id. - */ - function baseDelay(func, wait, args) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return setTimeout(function() { func.apply(undefined, args); }, wait); - } - - /** - * The base implementation of `_.difference` which accepts a single array - * of values to exclude. + * **Note:** This method mutates `array`. * - * @private - * @param {Array} array The array to inspect. - * @param {Array} values The values to exclude. - * @returns {Array} Returns the new array of filtered values. + * @static + * @memberOf _ + * @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], '*', 1, 2); + * // => [4, '*', 8] */ - function baseDifference(array, values) { - var length = array ? array.length : 0, - result = []; - + function fill(array, value, start, end) { + var length = array ? array.length : 0; if (!length) { - return result; - } - var index = -1, - indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf, - cache = (isCommon && values.length >= 200) ? createCache(values) : null, - valuesLength = values.length; - - if (cache) { - indexOf = cacheIndexOf; - isCommon = false; - values = cache; + return []; } - outer: - while (++index < length) { - var value = array[index]; - - if (isCommon && value === value) { - var valuesIndex = valuesLength; - while (valuesIndex--) { - if (values[valuesIndex] === value) { - continue outer; - } - } - result.push(value); - } - else if (indexOf(values, value, 0) < 0) { - result.push(value); - } + if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { + start = 0; + end = length; } - return result; + return baseFill(array, value, start, end); } /** - * The base implementation of `_.forEach` without support for callback - * shorthands and `this` binding. + * This method is like `_.find` except that it returns the index of the first + * element `predicate` returns truthy for instead of the element itself. * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object|string} Returns `collection`. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @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(chr) { + * return chr.user == 'barney'; + * }); + * // => 0 + * + * // using the `_.matches` callback shorthand + * _.findIndex(users, { 'user': 'fred', 'active': false }); + * // => 1 + * + * // using the `_.matchesProperty` callback shorthand + * _.findIndex(users, 'active', false); + * // => 0 + * + * // using the `_.property` callback shorthand + * _.findIndex(users, 'active'); + * // => 2 */ - var baseEach = createBaseEach(baseForOwn); + var findIndex = createFindIndex(); /** - * The base implementation of `_.forEachRight` without support for callback - * shorthands and `this` binding. + * This method is like `_.findIndex` except that it iterates over elements + * of `collection` from right to left. * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array|Object|string} Returns `collection`. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @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(chr) { + * return chr.user == 'pebbles'; + * }); + * // => 2 + * + * // using the `_.matches` callback shorthand + * _.findLastIndex(users, { 'user': 'barney', 'active': true }); + * // => 0 + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastIndex(users, 'active', false); + * // => 2 + * + * // using the `_.property` callback shorthand + * _.findLastIndex(users, 'active'); + * // => 0 */ - var baseEachRight = createBaseEach(baseForOwnRight, true); + var findLastIndex = createFindIndex(true); /** - * The base implementation of `_.every` without support for callback - * shorthands and `this` binding. + * Gets the first element of `array`. * - * @private - * @param {Array|Object|string} 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` + * @static + * @memberOf _ + * @alias head + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the first element of `array`. + * @example + * + * _.first([1, 2, 3]); + * // => 1 + * + * _.first([]); + * // => undefined */ - function baseEvery(collection, predicate) { - var result = true; - baseEach(collection, function(value, index, collection) { - result = !!predicate(value, index, collection); - return result; - }); - return result; + function first(array) { + return array ? array[0] : undefined; } /** - * The base implementation of `_.fill` without an iteratee call guard. + * Flattens a nested array. If `isDeep` is `true` the array is recursively + * flattened, otherwise it is only flattened a single level. * - * @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`. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to flatten. + * @param {boolean} [isDeep] Specify a deep flatten. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flatten([1, [2, 3, [4]]]); + * // => [1, 2, 3, [4]] + * + * // using `isDeep` + * _.flatten([1, [2, 3, [4]]], true); + * // => [1, 2, 3, 4] */ - function baseFill(array, value, start, end) { - var length = array.length; - - start = start == null ? 0 : (+start || 0); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : (+end || 0); - if (end < 0) { - end += length; + function flatten(array, isDeep, guard) { + var length = array ? array.length : 0; + if (guard && isIterateeCall(array, isDeep, guard)) { + isDeep = false; } - length = start > end ? 0 : (end >>> 0); - start >>>= 0; + return length ? baseFlatten(array, isDeep) : []; + } - while (start < length) { - array[start++] = value; - } - return array; + /** + * Recursively flattens a nested array. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to recursively flatten. + * @returns {Array} Returns the new flattened array. + * @example + * + * _.flattenDeep([1, [2, 3, [4]]]); + * // => [1, 2, 3, 4] + */ + function flattenDeep(array) { + var length = array ? array.length : 0; + return length ? baseFlatten(array, true) : []; } /** - * The base implementation of `_.filter` without support for callback - * shorthands and `this` binding. + * Gets the index at which the first occurrence of `value` is found in `array` + * using [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` + * performs a faster binary search. * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} predicate The function invoked per iteration. - * @returns {Array} Returns the new filtered array. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=0] The index to search from or `true` + * to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.indexOf([1, 2, 1, 2], 2); + * // => 1 + * + * // using `fromIndex` + * _.indexOf([1, 2, 1, 2], 2, 2); + * // => 3 + * + * // performing a binary search + * _.indexOf([1, 1, 2, 2], 2, true); + * // => 2 */ - function baseFilter(collection, predicate) { - var result = []; - baseEach(collection, function(value, index, collection) { - if (predicate(value, index, collection)) { - result.push(value); + function indexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + if (typeof fromIndex == 'number') { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; + } else if (fromIndex) { + var index = binaryIndex(array, value), + other = array[index]; + + if (value === value ? (value === other) : (other !== other)) { + return index; } - }); - return result; + return -1; + } + return baseIndexOf(array, value, fromIndex || 0); } /** - * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, - * without support for callback shorthands and `this` binding, which iterates - * over `collection` using the provided `eachFunc`. + * Gets all but the last element of `array`. * - * @private - * @param {Array|Object|string} collection The collection to search. - * @param {Function} predicate The function invoked per iteration. - * @param {Function} eachFunc The function to iterate over `collection`. - * @param {boolean} [retKey] Specify returning the key of the found element - * instead of the element itself. - * @returns {*} Returns the found element or its key, else `undefined`. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.initial([1, 2, 3]); + * // => [1, 2] */ - function baseFind(collection, predicate, eachFunc, retKey) { - var result; - eachFunc(collection, function(value, key, collection) { - if (predicate(value, key, collection)) { - result = retKey ? key : value; - return false; - } - }); - return result; + function initial(array) { + return dropRight(array, 1); } /** - * The base implementation of `_.flatten` with added support for restricting - * flattening and specifying the start index. + * Creates an array of unique values in all provided arrays using + * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for equality comparisons. * - * @private - * @param {Array} array The array to flatten. - * @param {boolean} isDeep Specify a deep flatten. - * @param {boolean} isStrict Restrict flattening to arrays and `arguments` objects. - * @returns {Array} Returns the new flattened array. + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of shared values. + * @example + * _.intersection([1, 2], [4, 2], [2, 1]); + * // => [2] */ - function baseFlatten(array, isDeep, isStrict) { - var index = -1, - length = array.length, - resIndex = -1, + function intersection() { + var args = [], + argsIndex = -1, + argsLength = arguments.length, + caches = [], + indexOf = getIndexOf(), + isCommon = indexOf == baseIndexOf, result = []; - while (++index < length) { - var value = array[index]; + while (++argsIndex < argsLength) { + var value = arguments[argsIndex]; + if (isArrayLike(value)) { + args.push(value); + caches.push((isCommon && value.length >= 120) ? createCache(argsIndex && value) : null); + } + } + argsLength = args.length; + if (argsLength < 2) { + return result; + } + var array = args[0], + index = -1, + length = array ? array.length : 0, + seen = caches[0]; - if (isObjectLike(value) && isLength(value.length) && (isArray(value) || isArguments(value))) { - if (isDeep) { - // Recursively flatten arrays (susceptible to call stack limits). - value = baseFlatten(value, isDeep, isStrict); + outer: + while (++index < length) { + value = array[index]; + if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { + argsIndex = argsLength; + while (--argsIndex) { + var cache = caches[argsIndex]; + if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value, 0)) < 0) { + continue outer; + } } - var valIndex = -1, - valLength = value.length; - - result.length += valLength; - while (++valIndex < valLength) { - result[++resIndex] = value[valIndex]; + if (seen) { + seen.push(value); } - } else if (!isStrict) { - result[++resIndex] = value; + result.push(value); } } return result; } /** - * The base implementation of `baseForIn` and `baseForOwn` which iterates - * over `object` properties returned by `keysFunc` invoking `iteratee` for - * each property. Iteratee functions may exit iteration early by explicitly - * returning `false`. + * Gets the last element of `array`. * - * @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. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @returns {*} Returns the last element of `array`. + * @example * - * @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`. + * _.last([1, 2, 3]); + * // => 3 */ - var baseForRight = createBaseFor(true); + function last(array) { + var length = array ? array.length : 0; + return length ? array[length - 1] : undefined; + } /** - * The base implementation of `_.forIn` without support for callback - * shorthands and `this` binding. + * This method is like `_.indexOf` except that it iterates over elements of + * `array` from right to left. * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to search. + * @param {*} value The value to search for. + * @param {boolean|number} [fromIndex=array.length-1] The index to search from + * or `true` to perform a binary search on a sorted array. + * @returns {number} Returns the index of the matched value, else `-1`. + * @example + * + * _.lastIndexOf([1, 2, 1, 2], 2); + * // => 3 + * + * // using `fromIndex` + * _.lastIndexOf([1, 2, 1, 2], 2, 2); + * // => 1 + * + * // performing a binary search + * _.lastIndexOf([1, 1, 2, 2], 2, true); + * // => 3 */ - function baseForIn(object, iteratee) { - return baseFor(object, iteratee, keysIn); + function lastIndexOf(array, value, fromIndex) { + var length = array ? array.length : 0; + if (!length) { + return -1; + } + var index = length; + if (typeof fromIndex == 'number') { + index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; + } else if (fromIndex) { + index = binaryIndex(array, value, true) - 1; + var other = array[index]; + if (value === value ? (value === other) : (other !== other)) { + return index; + } + return -1; + } + if (value !== value) { + return indexOfNaN(array, index, true); + } + while (index--) { + if (array[index] === value) { + return index; + } + } + return -1; } /** - * The base implementation of `_.forOwn` without support for callback - * shorthands and `this` binding. + * Removes all provided values from `array` using + * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for equality comparisons. * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. + * **Note:** Unlike `_.without`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...*} [values] The values to remove. + * @returns {Array} Returns `array`. + * @example + * + * var array = [1, 2, 3, 1, 2, 3]; + * + * _.pull(array, 2, 3); + * console.log(array); + * // => [1, 1] */ - function baseForOwn(object, iteratee) { - return baseFor(object, iteratee, keys); + function pull() { + var args = arguments, + array = args[0]; + + if (!(array && array.length)) { + return array; + } + var index = 0, + indexOf = getIndexOf(), + length = args.length; + + while (++index < length) { + var fromIndex = 0, + value = args[index]; + + while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { + splice.call(array, fromIndex, 1); + } + } + return array; } /** - * The base implementation of `_.forOwnRight` without support for callback - * shorthands and `this` binding. + * Removes elements from `array` corresponding to the given indexes and returns + * an array of the removed elements. Indexes may be specified as an array of + * indexes or as individual arguments. * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. + * **Note:** Unlike `_.at`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * specified as individual indexes or arrays of indexes. + * @returns {Array} Returns the new array of removed elements. + * @example + * + * var array = [5, 10, 15, 20]; + * var evens = _.pullAt(array, 1, 3); + * + * console.log(array); + * // => [5, 15] + * + * console.log(evens); + * // => [10, 20] */ - function baseForOwnRight(object, iteratee) { - return baseForRight(object, iteratee, keys); - } + var pullAt = restParam(function(array, indexes) { + indexes = baseFlatten(indexes); + + var result = baseAt(array, indexes); + basePullAt(array, indexes.sort(baseCompareAscending)); + return result; + }); /** - * The base implementation of `_.functions` which creates an array of - * `object` function property names filtered from those provided. + * Removes all elements from `array` that `predicate` returns truthy for + * and returns an array of the removed elements. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The property names to filter. - * @returns {Array} Returns the new array of filtered property names. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * **Note:** Unlike `_.filter`, this method mutates `array`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to modify. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @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 baseFunctions(object, props) { + function remove(array, predicate, thisArg) { + var result = []; + if (!(array && array.length)) { + return result; + } var index = -1, - length = props.length, - resIndex = -1, - result = []; + indexes = [], + length = array.length; + predicate = getCallback(predicate, thisArg, 3); while (++index < length) { - var key = props[index]; - if (isFunction(object[key])) { - result[++resIndex] = key; + var value = array[index]; + if (predicate(value, index, array)) { + result.push(value); + indexes.push(index); } } + basePullAt(array, indexes); return result; } /** - * The base implementation of `get` without support for string paths - * and default values. + * Gets all but the first element of `array`. * - * @private - * @param {Object} object The object to query. - * @param {Array} path The path of the property to get. - * @param {string} [pathKey] The key representation of path. - * @returns {*} Returns the resolved value. + * @static + * @memberOf _ + * @alias tail + * @category Array + * @param {Array} array The array to query. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.rest([1, 2, 3]); + * // => [2, 3] */ - function baseGet(object, path, pathKey) { - if (object == null) { - return; - } - if (pathKey !== undefined && pathKey in toObject(object)) { - path = [pathKey]; - } - var index = -1, - length = path.length; - - while (object != null && ++index < length) { - var result = object = object[path[index]]; - } - return result; + function rest(array) { + return drop(array, 1); } /** - * The base implementation of `_.isEqual` without support for `this` binding - * `customizer` functions. + * Creates a slice of `array` from `start` up to, but not including, `end`. * - * @private - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * **Note:** This method is used instead of `Array#slice` to support node + * lists in IE < 9 and to ensure dense arrays are returned. + * + * @static + * @memberOf _ + * @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 baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { - // Exit early for identical values. - if (value === other) { - // Treat `+0` vs. `-0` as not equal. - return value !== 0 || (1 / value == 1 / other); + function slice(array, start, end) { + var length = array ? array.length : 0; + if (!length) { + return []; } - var valType = typeof value, - othType = typeof other; - - // Exit early for unlike primitive values. - if ((valType != 'function' && valType != 'object' && othType != 'function' && othType != 'object') || - value == null || other == null) { - // Return `false` unless both values are `NaN`. - return value !== value && other !== other; + if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { + start = 0; + end = length; } - return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); + return baseSlice(array, start, end); } /** - * 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. + * Uses a binary search to determine the lowest index at which `value` should + * be inserted into `array` in order to maintain its sort order. If an iteratee + * function is provided it is invoked for `value` and each element of `array` + * to compute their sort ranking. The iteratee is bound to `thisArg` and + * invoked with one argument; (value). * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing objects. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA=[]] Tracks traversed `value` objects. - * @param {Array} [stackB=[]] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. - */ - function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { - var objIsArr = isArray(object), - othIsArr = isArray(other), - objTag = arrayTag, - othTag = arrayTag; - - if (!objIsArr) { - objTag = objToString.call(object); - if (objTag == argsTag) { - objTag = objectTag; - } else if (objTag != objectTag) { - objIsArr = isTypedArray(object); - } - } - if (!othIsArr) { - othTag = objToString.call(other); - if (othTag == argsTag) { - othTag = objectTag; - } else if (othTag != objectTag) { - othIsArr = isTypedArray(other); - } - } - var objIsObj = objTag == objectTag, - othIsObj = othTag == objectTag, - isSameTag = objTag == othTag; - - if (isSameTag && !(objIsArr || objIsObj)) { - return equalByTag(object, other, objTag); - } - if (!isLoose) { - var valWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), - othWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); - - if (valWrapped || othWrapped) { - return equalFunc(valWrapped ? object.value() : object, othWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); - } - } - if (!isSameTag) { - return false; - } - // Assume cyclic values are equal. - // For more information on detecting circular references see https://es5.github.io/#JO. - stackA || (stackA = []); - stackB || (stackB = []); - - var length = stackA.length; - while (length--) { - if (stackA[length] == object) { - return stackB[length] == other; - } - } - // Add `object` and `other` to the stack of traversed objects. - stackA.push(object); - stackB.push(other); - - var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); - - stackA.pop(); - stackB.pop(); - - return result; - } + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedIndex([30, 50], 40); + * // => 1 + * + * _.sortedIndex([4, 4, 5, 5], 5); + * // => 2 + * + * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * + * // using an iteratee function + * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { + * return this.data[word]; + * }, dict); + * // => 1 + * + * // using the `_.property` callback shorthand + * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); + * // => 1 + */ + var sortedIndex = createSortedIndex(); /** - * The base implementation of `_.isMatch` without support for callback - * shorthands and `this` binding. + * 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. * - * @private - * @param {Object} object The object to inspect. - * @param {Array} props The source property names to match. - * @param {Array} values The source values to match. - * @param {Array} strictCompareFlags Strict comparison flags for source values. - * @param {Function} [customizer] The function to customize comparing objects. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The sorted array to inspect. + * @param {*} value The value to evaluate. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {number} Returns the index at which `value` should be inserted + * into `array`. + * @example + * + * _.sortedLastIndex([4, 4, 5, 5], 5); + * // => 4 */ - function baseIsMatch(object, props, values, strictCompareFlags, customizer) { - var index = -1, - length = props.length, - noCustomizer = !customizer; - - while (++index < length) { - if ((noCustomizer && strictCompareFlags[index]) - ? values[index] !== object[props[index]] - : !(props[index] in object) - ) { - return false; - } - } - index = -1; - while (++index < length) { - var key = props[index], - objValue = object[key], - srcValue = values[index]; - - if (noCustomizer && strictCompareFlags[index]) { - var result = objValue !== undefined || (key in object); - } else { - result = customizer ? customizer(objValue, srcValue, key) : undefined; - if (result === undefined) { - result = baseIsEqual(srcValue, objValue, customizer, true); - } - } - if (!result) { - return false; - } - } - return true; - } + var sortedLastIndex = createSortedIndex(true); /** - * The base implementation of `_.map` without support for callback shorthands - * and `this` binding. + * Creates a slice of `array` with `n` elements taken from the beginning. * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. + * @static + * @memberOf _ + * @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 a callback for functions 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 baseMap(collection, iteratee) { - var index = -1, - length = getLength(collection), - result = isLength(length) ? Array(length) : []; - - baseEach(collection, function(value, key, collection) { - result[++index] = iteratee(value, key, collection); - }); - return result; + function take(array, n, guard) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; + } + return baseSlice(array, 0, n < 0 ? 0 : n); } /** - * The base implementation of `_.matches` which does not clone `source`. + * Creates a slice of `array` with `n` elements taken from the end. * - * @private - * @param {Object} source The object of property values to match. - * @returns {Function} Returns the new function. + * @static + * @memberOf _ + * @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 a callback for functions 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 baseMatches(source) { - var props = keys(source), - length = props.length; - + function takeRight(array, n, guard) { + var length = array ? array.length : 0; if (!length) { - return constant(true); - } - if (length == 1) { - var key = props[0], - value = source[key]; - - if (isStrictComparable(value)) { - return function(object) { - if (object == null) { - return false; - } - return object[key] === value && (value !== undefined || (key in toObject(object))); - }; - } + return []; } - var values = Array(length), - strictCompareFlags = Array(length); - - while (length--) { - value = source[props[length]]; - values[length] = value; - strictCompareFlags[length] = isStrictComparable(value); + if (guard ? isIterateeCall(array, n, guard) : n == null) { + n = 1; } - return function(object) { - return object != null && baseIsMatch(toObject(object), props, values, strictCompareFlags); - }; + n = length - (+n || 0); + return baseSlice(array, n < 0 ? 0 : n); } /** - * The base implementation of `_.matchesProperty` which does not which does - * not clone `value`. + * Creates a slice of `array` with elements taken from the end. Elements are + * taken until `predicate` returns falsey. The predicate is bound to `thisArg` + * and invoked with three arguments: (value, index, array). * - * @private - * @param {string} path The path of the property to get. - * @param {*} value The value to compare. - * @returns {Function} Returns the new function. - */ - function baseMatchesProperty(path, value) { - var isArr = isArray(path), - isCommon = isKey(path) && isStrictComparable(value), - pathKey = (path + ''); - - path = toPath(path); - return function(object) { - if (object == null) { - return false; - } - var key = pathKey; - object = toObject(object); - if ((isArr || !isCommon) && !(key in object)) { - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - if (object == null) { - return false; - } - key = last(path); - object = toObject(object); - } - return object[key] === value - ? (value !== undefined || (key in object)) - : baseIsEqual(value, object[key], null, true); - }; - } - - /** - * The base implementation of `_.merge` without support for argument juggling, - * multiple sources, and `this` binding `customizer` functions. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {Function} [customizer] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - * @returns {Object} Returns `object`. - */ - function baseMerge(object, source, customizer, stackA, stackB) { - if (!isObject(object)) { - return object; - } - var isSrcArr = isLength(source.length) && (isArray(source) || isTypedArray(source)); - if (!isSrcArr) { - var props = keys(source); - push.apply(props, getSymbols(source)); - } - arrayEach(props || source, function(srcValue, key) { - if (props) { - key = srcValue; - srcValue = source[key]; - } - if (isObjectLike(srcValue)) { - stackA || (stackA = []); - stackB || (stackB = []); - baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); - } - else { - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = result === undefined; - - if (isCommon) { - result = srcValue; - } - if ((isSrcArr || result !== undefined) && - (isCommon || (result === result ? (result !== value) : (value === value)))) { - object[key] = result; - } - } - }); - return object; - } - - /** - * 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. + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. * - * @private - * @param {Object} object The destination object. - * @param {Object} source The source object. - * @param {string} key The key of the value to merge. - * @param {Function} mergeFunc The function to merge values. - * @param {Function} [customizer] The function to customize merging properties. - * @param {Array} [stackA=[]] Tracks traversed source objects. - * @param {Array} [stackB=[]] Associates values with source counterparts. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeRightWhile([1, 2, 3], function(n) { + * return n > 1; + * }); + * // => [2, 3] + * + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false }, + * { 'user': 'pebbles', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); + * // => ['pebbles'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); + * // => ['fred', 'pebbles'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeRightWhile(users, 'active'), 'user'); + * // => [] */ - function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { - var length = stackA.length, - srcValue = source[key]; - - while (length--) { - if (stackA[length] == srcValue) { - object[key] = stackB[length]; - return; - } - } - var value = object[key], - result = customizer ? customizer(value, srcValue, key, object, source) : undefined, - isCommon = result === undefined; - - if (isCommon) { - result = srcValue; - if (isLength(srcValue.length) && (isArray(srcValue) || isTypedArray(srcValue))) { - result = isArray(value) - ? value - : (getLength(value) ? arrayCopy(value) : []); - } - else if (isPlainObject(srcValue) || isArguments(srcValue)) { - result = isArguments(value) - ? toPlainObject(value) - : (isPlainObject(value) ? value : {}); - } - else { - isCommon = false; - } - } - // Add the source value to the stack of traversed objects and associate - // it with its merged value. - stackA.push(srcValue); - stackB.push(result); - - if (isCommon) { - // Recursively merge objects and arrays (susceptible to call stack limits). - object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); - } else if (result === result ? (result !== value) : (value === value)) { - object[key] = result; - } + function takeRightWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) + : []; } /** - * The base implementation of `_.property` without support for deep paths. + * Creates a slice of `array` with elements taken from the beginning. Elements + * are taken until `predicate` returns falsey. The predicate is bound to + * `thisArg` and invoked with three arguments: (value, index, array). * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new function. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to query. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the slice of `array`. + * @example + * + * _.takeWhile([1, 2, 3], function(n) { + * return n < 3; + * }); + * // => [1, 2] + * + * var users = [ + * { 'user': 'barney', 'active': false }, + * { 'user': 'fred', 'active': false}, + * { 'user': 'pebbles', 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.takeWhile(users, 'active', false), 'user'); + * // => ['barney', 'fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.takeWhile(users, 'active'), 'user'); + * // => [] */ - function baseProperty(key) { - return function(object) { - return object == null ? undefined : object[key]; - }; + function takeWhile(array, predicate, thisArg) { + return (array && array.length) + ? baseWhile(array, getCallback(predicate, thisArg, 3)) + : []; } /** - * A specialized version of `baseProperty` which supports deep paths. + * Creates an array of unique values, in order, of the provided arrays using + * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for equality comparisons. * - * @private - * @param {Array|string} path The path of the property to get. - * @returns {Function} Returns the new function. + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of combined values. + * @example + * + * _.union([1, 2], [4, 2], [2, 1]); + * // => [1, 2, 4] */ - function basePropertyDeep(path) { - var pathKey = (path + ''); - path = toPath(path); - return function(object) { - return baseGet(object, path, pathKey); - }; - } + var union = restParam(function(arrays) { + return baseUniq(baseFlatten(arrays, false, true)); + }); /** - * The base implementation of `_.pullAt` without support for individual - * index arguments and capturing the removed elements. + * Creates a duplicate-free version of an array, using + * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for equality comparisons, in which only the first occurence of each element + * is kept. Providing `true` for `isSorted` performs a faster search algorithm + * for sorted arrays. If an iteratee function is provided it is invoked for + * each element in the array to generate the criterion by which uniqueness + * is computed. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index, array). * - * @private - * @param {Array} array The array to modify. - * @param {number[]} indexes The indexes of elements to remove. - * @returns {Array} Returns `array`. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias unique + * @category Array + * @param {Array} array The array to inspect. + * @param {boolean} [isSorted] Specify the array is sorted. + * @param {Function|Object|string} [iteratee] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new duplicate-value-free array. + * @example + * + * _.uniq([2, 1, 2]); + * // => [2, 1] + * + * // using `isSorted` + * _.uniq([1, 1, 2], true); + * // => [1, 2] + * + * // using an iteratee function + * _.uniq([1, 2.5, 1.5, 2], function(n) { + * return this.floor(n); + * }, Math); + * // => [1, 2.5] + * + * // using the `_.property` callback shorthand + * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); + * // => [{ 'x': 1 }, { 'x': 2 }] */ - function basePullAt(array, indexes) { - var length = indexes.length; - while (length--) { - var index = parseFloat(indexes[length]); - if (index != previous && isIndex(index)) { - var previous = index; - splice.call(array, index, 1); - } + function uniq(array, isSorted, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; } - return array; + if (isSorted != null && typeof isSorted != 'boolean') { + thisArg = iteratee; + iteratee = isIterateeCall(array, isSorted, thisArg) ? null : isSorted; + isSorted = false; + } + var func = getCallback(); + if (!(func === baseCallback && iteratee == null)) { + iteratee = func(iteratee, thisArg, 3); + } + return (isSorted && getIndexOf() == baseIndexOf) + ? sortedUniq(array, iteratee) + : baseUniq(array, iteratee); } /** - * The base implementation of `_.random` without support for argument juggling - * and returning floating-point numbers. + * 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. * - * @private - * @param {number} min The minimum possible value. - * @param {number} max The maximum possible value. - * @returns {number} Returns the random number. + * @static + * @memberOf _ + * @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(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] + * + * _.unzip(zipped); + * // => [['fred', 'barney'], [30, 40], [true, false]] */ - function baseRandom(min, max) { - return min + floor(nativeRandom() * (max - min + 1)); + function unzip(array) { + if (!(array && array.length)) { + return []; + } + var index = -1, + length = 0; + + array = arrayFilter(array, function(group) { + if (isArrayLike(group)) { + length = nativeMax(group.length, length); + return true; + } + }); + var result = Array(length); + while (++index < length) { + result[index] = arrayMap(array, baseProperty(index)); + } + return result; } /** - * The base implementation of `_.reduce` and `_.reduceRight` without support - * for callback shorthands and `this` binding, which iterates over `collection` - * using the provided `eachFunc`. + * This method is like `_.unzip` except that it accepts an iteratee to specify + * how regrouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {*} accumulator The initial value. - * @param {boolean} initFromCollection 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. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array of grouped elements to process. + * @param {Function} [iteratee] The function to combine regrouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @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 baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { - eachFunc(collection, function(value, index, collection) { - accumulator = initFromCollection - ? (initFromCollection = false, value) - : iteratee(accumulator, value, index, collection); + function unzipWith(array, iteratee, thisArg) { + var length = array ? array.length : 0; + if (!length) { + return []; + } + var result = unzip(array); + if (iteratee == null) { + return result; + } + iteratee = bindCallback(iteratee, thisArg, 4); + return arrayMap(result, function(group) { + return arrayReduce(group, iteratee, undefined, true); }); - return accumulator; } /** - * The base implementation of `setData` without support for hot loop detection. + * Creates an array excluding all provided values using + * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for equality comparisons. * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. + * @static + * @memberOf _ + * @category Array + * @param {Array} array The array to filter. + * @param {...*} [values] The values to exclude. + * @returns {Array} Returns the new array of filtered values. + * @example + * + * _.without([1, 2, 1, 3], 1, 2); + * // => [3] */ - var baseSetData = !metaMap ? identity : function(func, data) { - metaMap.set(func, data); - return func; - }; + var without = restParam(function(array, values) { + return isArrayLike(array) + ? baseDifference(array, values) + : []; + }); /** - * The base implementation of `_.slice` without an iteratee call guard. + * Creates an array that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) + * of the provided arrays. * - * @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`. + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to inspect. + * @returns {Array} Returns the new array of values. + * @example + * + * _.xor([1, 2], [4, 2]); + * // => [1, 4] */ - function baseSlice(array, start, end) { + function xor() { var index = -1, - length = array.length; - - start = start == null ? 0 : (+start || 0); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = (end === undefined || end > length) ? length : (+end || 0); - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; + length = arguments.length; - var result = Array(length); while (++index < length) { - result[index] = array[index + start]; + var array = arguments[index]; + if (isArrayLike(array)) { + var result = result + ? baseDifference(result, array).concat(baseDifference(array, result)) + : array; + } } - return result; + return result ? baseUniq(result) : []; } /** - * The base implementation of `_.some` without support for callback shorthands - * and `this` binding. + * 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. * - * @private - * @param {Array|Object|string} 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 `_.sortBy` which uses `comparer` to define - * the sort order of `array` and replaces criteria objects with their - * corresponding values. + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @returns {Array} Returns the new array of grouped elements. + * @example * - * @private - * @param {Array} array The array to sort. - * @param {Function} comparer The function to define sort order. - * @returns {Array} Returns `array`. + * _.zip(['fred', 'barney'], [30, 40], [true, false]); + * // => [['fred', 30, true], ['barney', 40, false]] */ - function baseSortBy(array, comparer) { - var length = array.length; - - array.sort(comparer); - while (length--) { - array[length] = array[length].value; - } - return array; - } + var zip = restParam(unzip); /** - * The base implementation of `_.sortByOrder` without param guards. + * The inverse of `_.pairs`; this method returns an object composed from arrays + * of property names and values. Provide either a single two dimensional array, + * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names + * and one of corresponding values. * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {boolean[]} orders The sort orders of `iteratees`. - * @returns {Array} Returns the new sorted array. - */ - function baseSortByOrder(collection, iteratees, orders) { - var callback = getCallback(), - index = -1; - - iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); - - var result = baseMap(collection, function(value) { - 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 `_.sum` without support for callback shorthands - * and `this` binding. + * @static + * @memberOf _ + * @alias object + * @category Array + * @param {Array} props The property names. + * @param {Array} [values=[]] The property values. + * @returns {Object} Returns the new object. + * @example * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {number} Returns the sum. - */ - function baseSum(collection, iteratee) { - var result = 0; - baseEach(collection, function(value, index, collection) { - result += +iteratee(value, index, collection) || 0; - }); - return result; - } - - /** - * The base implementation of `_.uniq` without support for callback shorthands - * and `this` binding. + * _.zipObject([['fred', 30], ['barney', 40]]); + * // => { 'fred': 30, 'barney': 40 } * - * @private - * @param {Array} array The array to inspect. - * @param {Function} [iteratee] The function invoked per iteration. - * @returns {Array} Returns the new duplicate-value-free array. + * _.zipObject(['fred', 'barney'], [30, 40]); + * // => { 'fred': 30, 'barney': 40 } */ - function baseUniq(array, iteratee) { + function zipObject(props, values) { var index = -1, - indexOf = getIndexOf(), - length = array.length, - isCommon = indexOf == baseIndexOf, - isLarge = isCommon && length >= 200, - seen = isLarge ? createCache() : null, - result = []; + length = props ? props.length : 0, + result = {}; - if (seen) { - indexOf = cacheIndexOf; - isCommon = false; - } else { - isLarge = false; - seen = iteratee ? [] : result; + if (length && !values && !isArray(props[0])) { + values = []; } - outer: while (++index < length) { - var value = array[index], - computed = iteratee ? iteratee(value, index, array) : value; - - if (isCommon && value === value) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed) { - continue outer; - } - } - if (iteratee) { - seen.push(computed); - } - result.push(value); - } - else if (indexOf(seen, computed, 0) < 0) { - if (iteratee || isLarge) { - seen.push(computed); - } - result.push(value); + var key = props[index]; + if (values) { + result[key] = values[index]; + } else if (key) { + result[key[0]] = key[1]; } } return result; } /** - * The base implementation of `_.values` and `_.valuesIn` which creates an - * array of `object` property values corresponding to the property names - * of `props`. + * This method is like `_.zip` except that it accepts an iteratee to specify + * how grouped values should be combined. The `iteratee` is bound to `thisArg` + * and invoked with four arguments: (accumulator, value, index, group). * - * @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. + * @static + * @memberOf _ + * @category Array + * @param {...Array} [arrays] The arrays to process. + * @param {Function} [iteratee] The function to combine grouped values. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new array of grouped elements. + * @example + * + * _.zipWith([1, 2], [10, 20], [100, 200], _.add); + * // => [111, 222] */ - function baseValues(object, props) { - var index = -1, - length = props.length, - result = Array(length); + var zipWith = restParam(function(arrays) { + var length = arrays.length, + iteratee = arrays[length - 2], + thisArg = arrays[length - 1]; - while (++index < length) { - result[index] = object[props[index]]; + if (length > 2 && typeof iteratee == 'function') { + length -= 2; + } else { + iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; + thisArg = undefined; } - return result; - } + arrays.length = length; + return unzipWith(arrays, iteratee, thisArg); + }); /** - * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, - * and `_.takeWhile` without support for callback shorthands and `this` binding. + * Creates a `lodash` object that wraps `value` with explicit method + * chaining enabled. * - * @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`. + * @static + * @memberOf _ + * @category Chain + * @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(chr) { + * return chr.user + ' is ' + chr.age; + * }) + * .first() + * .value(); + * // => 'pebbles is 1' */ - 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)); + function chain(value) { + var result = lodash(value); + result.__chain__ = true; + return result; } /** - * 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. + * This method invokes `interceptor` and returns `value`. The interceptor is + * bound to `thisArg` and invoked with one argument; (value). The purpose of + * this method is to "tap into" a method chain in order to perform operations + * on intermediate results within the chain. * - * @private - * @param {*} value The unwrapped value. - * @param {Array} actions Actions to peform to resolve the unwrapped value. - * @returns {*} Returns the resolved value. + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns `value`. + * @example + * + * _([1, 2, 3]) + * .tap(function(array) { + * array.pop(); + * }) + * .reverse() + * .value(); + * // => [2, 1] */ - function baseWrapperValue(value, actions) { - var result = value; - if (result instanceof LazyWrapper) { - result = result.value(); - } - var index = -1, - length = actions.length; - - while (++index < length) { - var args = [result], - action = actions[index]; - - push.apply(args, action.args); - result = action.func.apply(action.thisArg, args); - } - return result; + function tap(value, interceptor, thisArg) { + interceptor.call(thisArg, value); + return value; } /** - * 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. + * This method is like `_.tap` except that it returns the result of `interceptor`. * - * @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`. + * @static + * @memberOf _ + * @category Chain + * @param {*} value The value to provide to `interceptor`. + * @param {Function} interceptor The function to invoke. + * @param {*} [thisArg] The `this` binding of `interceptor`. + * @returns {*} Returns the result of `interceptor`. + * @example + * + * _(' abc ') + * .chain() + * .trim() + * .thru(function(value) { + * return [value]; + * }) + * .value(); + * // => ['abc'] */ - function binaryIndex(array, value, retHighest) { - var low = 0, - high = array ? array.length : low; - - if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { - while (low < high) { - var mid = (low + high) >>> 1, - computed = array[mid]; - - if (retHighest ? (computed <= value) : (computed < value)) { - low = mid + 1; - } else { - high = mid; - } - } - return high; - } - return binaryIndexBy(array, value, identity, retHighest); + function thru(value, interceptor, thisArg) { + return interceptor.call(thisArg, value); } /** - * This function is like `binaryIndex` except that it invokes `iteratee` for - * `value` and each element of `array` to compute their sort ranking. The - * iteratee is invoked with one argument; (value). + * Enables explicit method chaining on the wrapper object. * - * @private - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function} iteratee The function invoked per iteration. - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @name chain + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * // without explicit chaining + * _(users).first(); + * // => { 'user': 'barney', 'age': 36 } + * + * // with explicit chaining + * _(users).chain() + * .first() + * .pick('user') + * .value(); + * // => { 'user': 'barney' } */ - function binaryIndexBy(array, value, iteratee, retHighest) { - value = iteratee(value); + function wrapperChain() { + return chain(this); + } - var low = 0, - high = array ? array.length : 0, - valIsNaN = value !== value, - valIsUndef = value === undefined; + /** + * Executes the chained sequence and returns the wrapped result. + * + * @name commit + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapper = _(array).push(3); + * + * console.log(array); + * // => [1, 2] + * + * wrapper = wrapper.commit(); + * console.log(array); + * // => [1, 2, 3] + * + * wrapper.last(); + * // => 3 + * + * console.log(array); + * // => [1, 2, 3] + */ + function wrapperCommit() { + return new LodashWrapper(this.value(), this.__chain__); + } - while (low < high) { - var mid = floor((low + high) / 2), - computed = iteratee(array[mid]), - isReflexive = computed === computed; + /** + * Creates a clone of the chained sequence planting `value` as the wrapped value. + * + * @name plant + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new `lodash` wrapper instance. + * @example + * + * var array = [1, 2]; + * var wrapper = _(array).map(function(value) { + * return Math.pow(value, 2); + * }); + * + * var other = [3, 4]; + * var otherWrapper = wrapper.plant(other); + * + * otherWrapper.value(); + * // => [9, 16] + * + * wrapper.value(); + * // => [1, 4] + */ + function wrapperPlant(value) { + var result, + parent = this; - if (valIsNaN) { - var setLow = isReflexive || retHighest; - } else if (valIsUndef) { - setLow = isReflexive && (retHighest || computed !== undefined); - } else { - setLow = retHighest ? (computed <= value) : (computed < value); - } - if (setLow) { - low = mid + 1; + while (parent instanceof baseLodash) { + var clone = wrapperClone(parent); + if (result) { + previous.__wrapped__ = clone; } else { - high = mid; + result = clone; } + var previous = clone; + parent = parent.__wrapped__; } - return nativeMin(high, MAX_ARRAY_INDEX); + previous.__wrapped__ = value; + return result; } /** - * A specialized version of `baseCallback` which only supports `this` binding - * and specifying the number of arguments to provide to `func`. + * Reverses the wrapped array so the first element becomes the last, the + * second element becomes the second to last, and so on. * - * @private - * @param {Function} func The function to bind. - * @param {*} thisArg The `this` binding of `func`. - * @param {number} [argCount] The number of arguments to provide to `func`. - * @returns {Function} Returns the callback. + * **Note:** This method mutates the wrapped array. + * + * @name reverse + * @memberOf _ + * @category Chain + * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @example + * + * var array = [1, 2, 3]; + * + * _(array).reverse().value() + * // => [3, 2, 1] + * + * console.log(array); + * // => [3, 2, 1] */ - function bindCallback(func, thisArg, argCount) { - if (typeof func != 'function') { - return identity; - } - if (thisArg === undefined) { - return func; - } - switch (argCount) { - case 1: return function(value) { - return func.call(thisArg, value); - }; - case 3: return function(value, index, collection) { - return func.call(thisArg, value, index, collection); - }; - case 4: return function(accumulator, value, index, collection) { - return func.call(thisArg, accumulator, value, index, collection); - }; - case 5: return function(value, other, key, object, source) { - return func.call(thisArg, value, other, key, object, source); - }; + function wrapperReverse() { + var value = this.__wrapped__; + if (value instanceof LazyWrapper) { + if (this.__actions__.length) { + value = new LazyWrapper(this); + } + return new LodashWrapper(value.reverse(), this.__chain__); } - return function() { - return func.apply(thisArg, arguments); - }; + return this.thru(function(value) { + return value.reverse(); + }); } /** - * Creates a clone of the given array buffer. + * Produces the result of coercing the unwrapped value to a string. * - * @private - * @param {ArrayBuffer} buffer The array buffer to clone. - * @returns {ArrayBuffer} Returns the cloned array buffer. + * @name toString + * @memberOf _ + * @category Chain + * @returns {string} Returns the coerced string value. + * @example + * + * _([1, 2, 3]).toString(); + * // => '1,2,3' */ - function bufferClone(buffer) { - return bufferSlice.call(buffer, 0); - } - if (!bufferSlice) { - // PhantomJS has `ArrayBuffer` and `Uint8Array` but not `Float64Array`. - bufferClone = !(ArrayBuffer && Uint8Array) ? constant(null) : function(buffer) { - var byteLength = buffer.byteLength, - floatLength = Float64Array ? floor(byteLength / FLOAT64_BYTES_PER_ELEMENT) : 0, - offset = floatLength * FLOAT64_BYTES_PER_ELEMENT, - result = new ArrayBuffer(byteLength); - - if (floatLength) { - var view = new Float64Array(result, 0, floatLength); - view.set(new Float64Array(buffer, 0, floatLength)); - } - if (byteLength != offset) { - view = new Uint8Array(result, offset); - view.set(new Uint8Array(buffer, offset)); - } - return result; - }; + function wrapperToString() { + return (this.value() + ''); } /** - * Creates an array that is the composition of partially applied arguments, - * placeholders, and provided arguments into a single array of arguments. + * Executes the chained sequence to extract the unwrapped value. * - * @private - * @param {Array|Object} args The provided arguments. - * @param {Array} partials The arguments to prepend to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @returns {Array} Returns the new array of composed arguments. + * @name value + * @memberOf _ + * @alias run, toJSON, valueOf + * @category Chain + * @returns {*} Returns the resolved unwrapped value. + * @example + * + * _([1, 2, 3]).value(); + * // => [1, 2, 3] */ - function composeArgs(args, partials, holders) { - var holdersLength = holders.length, - argsIndex = -1, - argsLength = nativeMax(args.length - holdersLength, 0), - leftIndex = -1, - leftLength = partials.length, - result = Array(argsLength + leftLength); - - while (++leftIndex < leftLength) { - result[leftIndex] = partials[leftIndex]; - } - while (++argsIndex < holdersLength) { - result[holders[argsIndex]] = args[argsIndex]; - } - while (argsLength--) { - result[leftIndex++] = args[argsIndex++]; - } - return result; + function wrapperValue() { + return baseWrapperValue(this.__wrapped__, this.__actions__); } /** - * This function is like `composeArgs` except that the arguments composition - * is tailored for `_.partialRight`. + * Creates an array of elements corresponding to the given keys, or indexes, + * of `collection`. Keys may be specified as individual arguments or as arrays + * of keys. * - * @private - * @param {Array|Object} args The provided arguments. - * @param {Array} partials The arguments to append to those provided. - * @param {Array} holders The `partials` placeholder indexes. - * @returns {Array} Returns the new array of composed arguments. - */ - function composeArgsRight(args, partials, holders) { - var holdersIndex = -1, - holdersLength = holders.length, - argsIndex = -1, - argsLength = nativeMax(args.length - holdersLength, 0), - rightIndex = -1, - rightLength = partials.length, - result = Array(argsLength + rightLength); - - while (++argsIndex < argsLength) { - result[argsIndex] = args[argsIndex]; - } - var pad = argsIndex; - while (++rightIndex < rightLength) { - result[pad + rightIndex] = partials[rightIndex]; - } - while (++holdersIndex < holdersLength) { - result[pad + holders[holdersIndex]] = args[argsIndex++]; - } - return result; - } - - /** - * Creates a function that aggregates a collection, creating an accumulator - * object composed from the results of running each element in the collection - * through an iteratee. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(number|number[]|string|string[])} [props] The property names + * or indexes of elements to pick, specified individually or in arrays. + * @returns {Array} Returns the new array of picked elements. + * @example * - * **Note:** This function is used to create `_.countBy`, `_.groupBy`, `_.indexBy`, - * and `_.partition`. + * _.at(['a', 'b', 'c'], [0, 2]); + * // => ['a', 'c'] * - * @private - * @param {Function} setter The function to set keys and values of the accumulator object. - * @param {Function} [initializer] The function to initialize the accumulator object. - * @returns {Function} Returns the new aggregator function. + * _.at(['barney', 'fred', 'pebbles'], 0, 2); + * // => ['barney', 'pebbles'] */ - function createAggregator(setter, initializer) { - return function(collection, iteratee, thisArg) { - var result = initializer ? initializer() : {}; - iteratee = getCallback(iteratee, thisArg, 3); - - if (isArray(collection)) { - var index = -1, - length = collection.length; - - while (++index < length) { - var value = collection[index]; - setter(result, value, iteratee(value, index, collection), collection); - } - } else { - baseEach(collection, function(value, key, collection) { - setter(result, value, iteratee(value, key, collection), collection); - }); - } - return result; - }; - } + var at = restParam(function(collection, props) { + return baseAt(collection, baseFlatten(props)); + }); /** - * Creates a function that assigns properties of source object(s) to a given - * destination object. + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the number of times the key was returned by `iteratee`. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). * - * **Note:** This function is used to create `_.assign`, `_.defaults`, and `_.merge`. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. * - * @private - * @param {Function} assigner The function to assign values. - * @returns {Function} Returns the new assigner function. - */ - function createAssigner(assigner) { - return restParam(function(object, sources) { - var index = -1, - length = object == null ? 0 : sources.length, - customizer = length > 2 && sources[length - 2], - guard = length > 2 && sources[2], - thisArg = length > 1 && sources[length - 1]; - - if (typeof customizer == 'function') { - customizer = bindCallback(customizer, thisArg, 5); - length -= 2; - } else { - customizer = typeof thisArg == 'function' ? thisArg : null; - length -= (customizer ? 1 : 0); - } - if (guard && isIterateeCall(sources[0], sources[1], guard)) { - customizer = length < 3 ? null : customizer; - length = 1; - } - while (++index < length) { - var source = sources[index]; - if (source) { - assigner(object, source, customizer); - } - } - return object; - }); - } - - /** - * Creates a `baseEach` or `baseEachRight` function. + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. * - * @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) { - var length = collection ? getLength(collection) : 0; - if (!isLength(length)) { - return eachFunc(collection, iteratee); - } - var index = fromRight ? length : -1, - iterable = toObject(collection); - - while ((fromRight ? index-- : ++index < length)) { - if (iteratee(iterable[index], index, iterable) === false) { - break; - } - } - return collection; - }; - } - - /** - * Creates a base function for `_.forIn` or `_.forInRight`. + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': 1, '6': 2 } + * + * _.countBy([4.3, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': 1, '6': 2 } + * + * _.countBy(['one', 'two', 'three'], 'length'); + * // => { '3': 2, '5': 1 } */ - function createBaseFor(fromRight) { - return function(object, iteratee, keysFunc) { - var iterable = toObject(object), - props = keysFunc(object), - length = props.length, - index = fromRight ? length : -1; - - while ((fromRight ? index-- : ++index < length)) { - var key = props[index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } - } - return object; - }; - } + var countBy = createAggregator(function(result, value, key) { + hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); + }); /** - * Creates a function that wraps `func` and invokes it with the `this` - * binding of `thisArg`. + * Checks if `predicate` returns truthy for **all** elements of `collection`. + * The predicate is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). * - * @private - * @param {Function} func The function to bind. - * @param {*} [thisArg] The `this` binding of `func`. - * @returns {Function} Returns the new bound function. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias all + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @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', 'active': false }, + * { 'user': 'fred', 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.every(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.every(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.every(users, 'active'); + * // => false */ - function createBindWrapper(func, thisArg) { - var Ctor = createCtorWrapper(func); - - function wrapper() { - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(thisArg, arguments); + function every(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayEvery : baseEvery; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = null; } - return wrapper; + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); } /** - * Creates a `Set` cache object to optimize linear searches of large arrays. - * - * @private - * @param {Array} [values] The values to cache. - * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. - */ - var createCache = !(nativeCreate && Set) ? constant(null) : function(values) { - return new SetCache(values); - }; - - /** - * Creates a function that produces compound words out of the words in a - * given string. + * Iterates over elements of `collection`, returning an array of all elements + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). * - * @private - * @param {Function} callback The function to combine each word. - * @returns {Function} Returns the new compounder function. - */ - function createCompounder(callback) { - return function(string) { - var index = -1, - array = words(deburr(string)), - length = array.length, - result = ''; - - while (++index < length) { - result = callback(result, array[index], index); - } - return result; - }; - } - - /** - * 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`. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. * - * @private - * @param {Function} Ctor The constructor to wrap. - * @returns {Function} Returns the new wrapped function. + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias select + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example + * + * _.filter([4, 5, 6], function(n) { + * return n % 2 == 0; + * }); + * // => [4, 6] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.filter(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.filter(users, 'active'), 'user'); + * // => ['barney'] */ - function createCtorWrapper(Ctor) { - return function() { - var thisBinding = baseCreate(Ctor.prototype), - result = Ctor.apply(thisBinding, arguments); - - // Mimic the constructor's `return` behavior. - // See https://es5.github.io/#x13.2.2 for more details. - return isObject(result) ? result : thisBinding; - }; + function filter(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, predicate); } /** - * Creates a `_.curry` or `_.curryRight` function. + * Iterates over elements of `collection`, returning the first element + * `predicate` returns truthy for. The predicate is bound to `thisArg` and + * invoked with three arguments: (value, index|key, collection). * - * @private - * @param {boolean} flag The curry bit flag. - * @returns {Function} Returns the new curry function. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @alias detect + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @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 } + * ]; + * + * _.result(_.find(users, function(chr) { + * return chr.age < 40; + * }), 'user'); + * // => 'barney' + * + * // using the `_.matches` callback shorthand + * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); + * // => 'pebbles' + * + * // using the `_.matchesProperty` callback shorthand + * _.result(_.find(users, 'active', false), 'user'); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.result(_.find(users, 'active'), 'user'); + * // => 'barney' */ - function createCurry(flag) { - function curryFunc(func, arity, guard) { - if (guard && isIterateeCall(func, arity, guard)) { - arity = null; - } - var result = createWrapper(func, flag, null, null, null, null, null, arity); - result.placeholder = curryFunc.placeholder; - return result; - } - return curryFunc; - } + var find = createFind(baseEach); /** - * Creates a `_.max` or `_.min` function. + * This method is like `_.find` except that it iterates over elements of + * `collection` from right to left. * - * @private - * @param {Function} arrayFunc The function to get the extremum value from an array. - * @param {boolean} [isMin] Specify returning the minimum, instead of the maximum, - * extremum value. - * @returns {Function} Returns the new extremum function. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * _.findLast([1, 2, 3, 4], function(n) { + * return n % 2 == 1; + * }); + * // => 3 */ - function createExtremum(arrayFunc, isMin) { - return function(collection, iteratee, thisArg) { - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; - } - var func = getCallback(), - noIteratee = iteratee == null; - - if (!(func === baseCallback && noIteratee)) { - noIteratee = false; - iteratee = func(iteratee, thisArg, 3); - } - if (noIteratee) { - var isArr = isArray(collection); - if (!isArr && isString(collection)) { - iteratee = charAtCallback; - } else { - return arrayFunc(isArr ? collection : toIterable(collection)); - } - } - return extremumBy(collection, iteratee, isMin); - }; - } + var findLast = createFind(baseEachRight, true); /** - * Creates a `_.find` or `_.findLast` function. + * Performs a deep comparison between each element in `collection` and the + * source object, returning the first element that has equivalent property + * values. * - * @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 find function. + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {*} Returns the matched element, else `undefined`. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } + * ]; + * + * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); + * // => 'barney' + * + * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); + * // => 'fred' */ - function createFind(eachFunc, fromRight) { - return function(collection, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - if (isArray(collection)) { - var index = baseFindIndex(collection, predicate, fromRight); - return index > -1 ? collection[index] : undefined; - } - return baseFind(collection, predicate, eachFunc); - } + function findWhere(collection, source) { + return find(collection, baseMatches(source)); } /** - * Creates a `_.findIndex` or `_.findLastIndex` function. + * Iterates over elements of `collection` invoking `iteratee` for each element. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). Iteratee functions may exit iteration early + * by explicitly returning `false`. * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new find function. - */ - function createFindIndex(fromRight) { - return function(array, predicate, thisArg) { - if (!(array && array.length)) { - return -1; - } - predicate = getCallback(predicate, thisArg, 3); - return baseFindIndex(array, predicate, fromRight); - }; - } - - /** - * Creates a `_.findKey` or `_.findLastKey` function. + * **Note:** As with other "Collections" methods, objects with a "length" property + * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` + * may be used for object iteration. * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new find function. - */ - function createFindKey(objectFunc) { - return function(object, predicate, thisArg) { - predicate = getCallback(predicate, thisArg, 3); - return baseFind(object, predicate, objectFunc, true); - }; - } - - /** - * Creates a `_.flow` or `_.flowRight` function. + * @static + * @memberOf _ + * @alias each + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new flow function. - */ - function createFlow(fromRight) { - return function() { - var length = arguments.length; - if (!length) { - return function() { return arguments[0]; }; - } - var wrapper, - index = fromRight ? length : -1, - leftIndex = 0, - funcs = Array(length); - - while ((fromRight ? index-- : ++index < length)) { - var func = funcs[leftIndex++] = arguments[index]; - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - var funcName = wrapper ? '' : getFuncName(func); - wrapper = funcName == 'wrapper' ? new LodashWrapper([]) : wrapper; - } - index = wrapper ? -1 : length; - while (++index < length) { - func = funcs[index]; - funcName = getFuncName(func); - - var data = funcName == 'wrapper' ? getData(func) : null; - if (data && isLaziable(data[0])) { - 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; - if (wrapper && args.length == 1 && isArray(args[0])) { - return wrapper.plant(args[0]).value(); - } - var index = 0, - result = funcs[index].apply(this, args); - - while (++index < length) { - result = funcs[index].call(this, result); - } - return result; - }; - }; - } - - /** - * Creates a function for `_.forEach` or `_.forEachRight`. + * _([1, 2]).forEach(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from left to right and returns the array * - * @private - * @param {Function} arrayFunc The function to iterate over an array. - * @param {Function} eachFunc The function to iterate over a collection. - * @returns {Function} Returns the new each function. + * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { + * console.log(n, key); + * }); + * // => logs each value-key pair and returns the object (iteration order is not guaranteed) */ - function createForEach(arrayFunc, eachFunc) { - return function(collection, iteratee, thisArg) { - return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) - ? arrayFunc(collection, iteratee) - : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); - }; - } + var forEach = createForEach(arrayEach, baseEach); /** - * Creates a function for `_.forIn` or `_.forInRight`. + * This method is like `_.forEach` except that it iterates over elements of + * `collection` from right to left. * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new each function. - */ - function createForIn(objectFunc) { - return function(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || thisArg !== undefined) { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return objectFunc(object, iteratee, keysIn); - }; - } - - /** - * Creates a function for `_.forOwn` or `_.forOwnRight`. + * @static + * @memberOf _ + * @alias eachRight + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array|Object|string} Returns `collection`. + * @example * - * @private - * @param {Function} objectFunc The function to iterate over an object. - * @returns {Function} Returns the new each function. + * _([1, 2]).forEachRight(function(n) { + * console.log(n); + * }).value(); + * // => logs each value from right to left and returns the array */ - function createForOwn(objectFunc) { - return function(object, iteratee, thisArg) { - if (typeof iteratee != 'function' || thisArg !== undefined) { - iteratee = bindCallback(iteratee, thisArg, 3); - } - return objectFunc(object, iteratee); - }; - } + var forEachRight = createForEach(arrayEachRight, baseEachRight); /** - * Creates a function for `_.padLeft` or `_.padRight`. + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is an array of the elements responsible for generating the key. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). * - * @private - * @param {boolean} [fromRight] Specify padding from the right. - * @returns {Function} Returns the new pad function. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return Math.floor(n); + * }); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * _.groupBy([4.2, 6.1, 6.4], function(n) { + * return this.floor(n); + * }, Math); + * // => { '4': [4.2], '6': [6.1, 6.4] } + * + * // using the `_.property` callback shorthand + * _.groupBy(['one', 'two', 'three'], 'length'); + * // => { '3': ['one', 'two'], '5': ['three'] } */ - function createPadDir(fromRight) { - return function(string, length, chars) { - string = baseToString(string); - return string && ((fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string)); - }; - } + var groupBy = createAggregator(function(result, value, key) { + if (hasOwnProperty.call(result, key)) { + result[key].push(value); + } else { + result[key] = [value]; + } + }); /** - * Creates a `_.partial` or `_.partialRight` function. + * Checks if `value` is in `collection` using + * [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) + * for equality comparisons. If `fromIndex` is negative, it is used as the offset + * from the end of `collection`. * - * @private - * @param {boolean} flag The partial bit flag. - * @returns {Function} Returns the new partial function. + * @static + * @memberOf _ + * @alias contains, include + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {*} target The value to search for. + * @param {number} [fromIndex=0] The index to search from. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @example + * + * _.includes([1, 2, 3], 1); + * // => true + * + * _.includes([1, 2, 3], 1, 2); + * // => false + * + * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); + * // => true + * + * _.includes('pebbles', 'eb'); + * // => true */ - function createPartial(flag) { - var partialFunc = restParam(function(func, partials) { - var holders = replaceHolders(partials, partialFunc.placeholder); - return createWrapper(func, flag, null, partials, holders); - }); - return partialFunc; + function includes(collection, target, fromIndex, guard) { + var length = collection ? getLength(collection) : 0; + if (!isLength(length)) { + collection = values(collection); + length = collection.length; + } + if (!length) { + return false; + } + if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { + fromIndex = 0; + } else { + fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); + } + return (typeof collection == 'string' || !isArray(collection) && isString(collection)) + ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) + : (getIndexOf(collection, target, fromIndex) > -1); } /** - * Creates a function for `_.reduce` or `_.reduceRight`. - * - * @private - * @param {Function} arrayFunc The function to iterate over an array. - * @param {Function} eachFunc The function to iterate over a collection. - * @returns {Function} Returns the new each function. + * Creates an object composed of keys generated from the results of running + * each element of `collection` through `iteratee`. The corresponding value + * of each key is the last element responsible for generating the key. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). + * + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the composed aggregate object. + * @example + * + * var keyData = [ + * { 'dir': 'left', 'code': 97 }, + * { 'dir': 'right', 'code': 100 } + * ]; + * + * _.indexBy(keyData, 'dir'); + * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return String.fromCharCode(object.code); + * }); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * + * _.indexBy(keyData, function(object) { + * return this.fromCharCode(object.code); + * }, String); + * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } */ - function createReduce(arrayFunc, eachFunc) { - return function(collection, iteratee, accumulator, thisArg) { - var initFromArray = arguments.length < 3; - return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) - ? arrayFunc(collection, iteratee, accumulator, initFromArray) - : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); - }; - } + var indexBy = createAggregator(function(result, value, key) { + result[key] = value; + }); /** - * Creates a function that wraps `func` and invokes it with optional `this` - * binding of, partial application, and currying. + * Invokes the method at `path` on each element in `collection`, returning + * an array of the results of each invoked method. Any additional arguments + * are provided to each invoked method. If `methodName` is a function it is + * invoked for, and `this` bound to, each element in `collection`. * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of flags. See `createWrapper` 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. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} 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 the method with. + * @returns {Array} Returns the array of results. + * @example + * + * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); + * // => [[1, 5, 7], [1, 2, 3]] + * + * _.invoke([123, 456], String.prototype.split, ''); + * // => [['1', '2', '3'], ['4', '5', '6']] */ - function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { - var isAry = bitmask & ARY_FLAG, - isBind = bitmask & BIND_FLAG, - isBindKey = bitmask & BIND_KEY_FLAG, - isCurry = bitmask & CURRY_FLAG, - isCurryBound = bitmask & CURRY_BOUND_FLAG, - isCurryRight = bitmask & CURRY_RIGHT_FLAG; - - var Ctor = !isBindKey && createCtorWrapper(func), - key = func; - - function wrapper() { - // Avoid `arguments` object use disqualifying optimizations by - // converting it to an array before providing it to other functions. - var length = arguments.length, - index = length, - args = Array(length); - - while (index--) { - args[index] = arguments[index]; - } - if (partials) { - args = composeArgs(args, partials, holders); - } - if (partialsRight) { - args = composeArgsRight(args, partialsRight, holdersRight); - } - if (isCurry || isCurryRight) { - var placeholder = wrapper.placeholder, - argsHolders = replaceHolders(args, placeholder); - - length -= argsHolders.length; - if (length < arity) { - var newArgPos = argPos ? arrayCopy(argPos) : null, - newArity = nativeMax(arity - length, 0), - newsHolders = isCurry ? argsHolders : null, - newHoldersRight = isCurry ? null : argsHolders, - newPartials = isCurry ? args : null, - newPartialsRight = isCurry ? null : args; - - bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); - bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); - - if (!isCurryBound) { - bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); - } - var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], - result = createHybridWrapper.apply(undefined, newData); + var invoke = restParam(function(collection, path, args) { + var index = -1, + isFunc = typeof path == 'function', + isProp = isKey(path), + result = isArrayLike(collection) ? Array(collection.length) : []; - if (isLaziable(func)) { - setData(result, newData); - } - result.placeholder = placeholder; - return result; - } - } - var thisBinding = isBind ? thisArg : this; - if (isBindKey) { - func = thisBinding[key]; - } - if (argPos) { - args = reorder(args, argPos); - } - if (isAry && ary < args.length) { - args.length = ary; - } - var fn = (this && this !== root && this instanceof wrapper) ? (Ctor || createCtorWrapper(func)) : func; - return fn.apply(thisBinding, args); - } - return wrapper; - } + baseEach(collection, function(value) { + var func = isFunc ? path : (isProp && value != null && value[path]); + result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); + }); + return result; + }); /** - * Creates the padding required for `string` based on the given `length`. - * The `chars` string is truncated if the number of characters exceeds `length`. + * Creates an array of values by running each element in `collection` through + * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three + * arguments: (value, index|key, collection). * - * @private - * @param {string} string The string to create padding for. - * @param {number} [length=0] The padding length. - * @param {string} [chars=' '] The string used as padding. - * @returns {string} Returns the pad for `string`. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * Many lodash methods are guarded to work as interatees for methods like + * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. + * + * The guarded methods are: + * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, + * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, + * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, + * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, + * `sum`, `uniq`, and `words` + * + * @static + * @memberOf _ + * @alias collect + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new mapped array. + * @example + * + * function timesThree(n) { + * return n * 3; + * } + * + * _.map([1, 2], timesThree); + * // => [3, 6] + * + * _.map({ 'a': 1, 'b': 2 }, timesThree); + * // => [3, 6] (iteration order is not guaranteed) + * + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * // using the `_.property` callback shorthand + * _.map(users, 'user'); + * // => ['barney', 'fred'] */ - function createPadding(string, length, chars) { - var strLength = string.length; - length = +length; - - if (strLength >= length || !nativeIsFinite(length)) { - return ''; - } - var padLength = length - strLength; - chars = chars == null ? ' ' : (chars + ''); - return repeat(chars, ceil(padLength / chars.length)).slice(0, padLength); + function map(collection, iteratee, thisArg) { + var func = isArray(collection) ? arrayMap : baseMap; + iteratee = getCallback(iteratee, thisArg, 3); + return func(collection, iteratee); } /** - * Creates a function that wraps `func` and invokes it with the optional `this` - * binding of `thisArg` and the `partials` prepended to those provided to - * the wrapper. + * Creates an array of elements split into two groups, the first of which + * contains elements `predicate` returns truthy for, while the second of which + * contains elements `predicate` returns falsey for. The predicate is bound + * to `thisArg` and invoked with three arguments: (value, index|key, collection). * - * @private - * @param {Function} func The function to partially apply arguments to. - * @param {number} bitmask The bitmask of flags. See `createWrapper` 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 bound function. - */ - function createPartialWrapper(func, bitmask, thisArg, partials) { - var isBind = bitmask & BIND_FLAG, - Ctor = createCtorWrapper(func); - - function wrapper() { - // Avoid `arguments` object use disqualifying optimizations by - // converting it to an array before providing it `func`. - var argsIndex = -1, - argsLength = arguments.length, - leftIndex = -1, - leftLength = partials.length, - args = Array(argsLength + leftLength); - - while (++leftIndex < leftLength) { - args[leftIndex] = partials[leftIndex]; - } - while (argsLength--) { - args[leftIndex++] = arguments[++argsIndex]; - } - var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; - return fn.apply(isBind ? thisArg : this, args); - } - return wrapper; - } + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the array of grouped elements. + * @example + * + * _.partition([1, 2, 3], function(n) { + * return n % 2; + * }); + * // => [[1, 3], [2]] + * + * _.partition([1.2, 2.3, 3.4], function(n) { + * return this.floor(n) % 2; + * }, Math); + * // => [[1.2, 3.4], [2.3]] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true }, + * { 'user': 'pebbles', 'age': 1, 'active': false } + * ]; + * + * var mapper = function(array) { + * return _.pluck(array, 'user'); + * }; + * + * // using the `_.matches` callback shorthand + * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); + * // => [['pebbles'], ['barney', 'fred']] + * + * // using the `_.matchesProperty` callback shorthand + * _.map(_.partition(users, 'active', false), mapper); + * // => [['barney', 'pebbles'], ['fred']] + * + * // using the `_.property` callback shorthand + * _.map(_.partition(users, 'active'), mapper); + * // => [['fred'], ['barney', 'pebbles']] + */ + var partition = createAggregator(function(result, value, key) { + result[key ? 0 : 1].push(value); + }, function() { return [[], []]; }); /** - * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. + * Gets the property value of `path` from all elements in `collection`. * - * @private - * @param {boolean} [retHighest] Specify returning the highest qualified index. - * @returns {Function} Returns the new index function. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Array|string} path The path of the property to pluck. + * @returns {Array} Returns the property values. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 40 } + * ]; + * + * _.pluck(users, 'user'); + * // => ['barney', 'fred'] + * + * var userIndex = _.indexBy(users, 'user'); + * _.pluck(userIndex, 'age'); + * // => [36, 40] (iteration order is not guaranteed) */ - function createSortedIndex(retHighest) { - return function(array, value, iteratee, thisArg) { - var func = getCallback(iteratee); - return (func === baseCallback && iteratee == null) - ? binaryIndex(array, value, retHighest) - : binaryIndexBy(array, value, func(iteratee, thisArg, 1), retHighest); - }; + function pluck(collection, path) { + return map(collection, property(path)); } /** - * Creates a function that either curries or invokes `func` with optional - * `this` binding and partially applied arguments. + * Reduces `collection` to a value which is the accumulated result of running + * each element in `collection` through `iteratee`, where each successive + * invocation is supplied the return value of the previous. If `accumulator` + * is not provided the first element of `collection` is used as the initial + * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: + * (accumulator, value, index|key, collection). * - * @private - * @param {Function|string} func The function or method name to reference. - * @param {number} bitmask The bitmask of flags. - * The bitmask may be composed of the following flags: - * 1 - `_.bind` - * 2 - `_.bindKey` - * 4 - `_.curry` or `_.curryRight` of a bound function - * 8 - `_.curry` - * 16 - `_.curryRight` - * 32 - `_.partial` - * 64 - `_.partialRight` - * 128 - `_.rearg` - * 256 - `_.ary` - * @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. + * Many lodash methods are guarded to work as interatees for methods like + * `_.reduce`, `_.reduceRight`, and `_.transform`. + * + * The guarded methods are: + * `assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder` + * + * @static + * @memberOf _ + * @alias foldl, inject + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @example + * + * _.reduce([1, 2], function(total, n) { + * return total + n; + * }); + * // => 3 + * + * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { + * result[key] = n * 3; + * return result; + * }, {}); + * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) */ - function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { - var isBindKey = bitmask & BIND_KEY_FLAG; - if (!isBindKey && typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - var length = partials ? partials.length : 0; - if (!length) { - bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); - partials = holders = null; - } - length -= (holders ? holders.length : 0); - if (bitmask & PARTIAL_RIGHT_FLAG) { - var partialsRight = partials, - holdersRight = holders; - - partials = holders = null; - } - var data = isBindKey ? null : getData(func), - newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; - - if (data) { - mergeData(newData, data); - bitmask = newData[1]; - arity = newData[9]; - } - newData[9] = arity == null - ? (isBindKey ? 0 : func.length) - : (nativeMax(arity - length, 0) || 0); - - if (bitmask == BIND_FLAG) { - var result = createBindWrapper(newData[0], newData[2]); - } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { - result = createPartialWrapper.apply(undefined, newData); - } else { - result = createHybridWrapper.apply(undefined, newData); - } - var setter = data ? baseSetData : setData; - return setter(result, newData); - } + var reduce = createReduce(arrayReduce, baseEach); /** - * A specialized version of `baseIsEqualDeep` for arrays with support for - * partial deep comparisons. + * This method is like `_.reduce` except that it iterates over elements of + * `collection` from right to left. * - * @private - * @param {Array} array The array to compare. - * @param {Array} other The other array to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing arrays. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. + * @static + * @memberOf _ + * @alias foldr + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [accumulator] The initial value. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {*} Returns the accumulated value. + * @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 equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { - var index = -1, - arrLength = array.length, - othLength = other.length, - result = true; - - if (arrLength != othLength && !(isLoose && othLength > arrLength)) { - return false; - } - // Deep compare the contents, ignoring non-numeric properties. - while (result && ++index < arrLength) { - var arrValue = array[index], - othValue = other[index]; - - result = undefined; - if (customizer) { - result = isLoose - ? customizer(othValue, arrValue, index) - : customizer(arrValue, othValue, index); - } - if (result === undefined) { - // Recursively compare arrays (susceptible to call stack limits). - if (isLoose) { - var othIndex = othLength; - while (othIndex--) { - othValue = other[othIndex]; - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); - if (result) { - break; - } - } - } else { - result = (arrValue && arrValue === othValue) || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); - } - } - } - return !!result; - } + var reduceRight = createReduce(arrayReduceRight, baseEachRight); /** - * A specialized version of `baseIsEqualDeep` for comparing objects of - * the same `toStringTag`. + * The opposite of `_.filter`; this method returns the elements of `collection` + * that `predicate` does **not** return truthy for. * - * **Note:** This function only supports comparing values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Array} Returns the new filtered array. + * @example * - * @private - * @param {Object} value The object to compare. - * @param {Object} other The other object to compare. - * @param {string} tag The `toStringTag` of the objects to compare. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + * _.reject([1, 2, 3, 4], function(n) { + * return n % 2 == 0; + * }); + * // => [1, 3] + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false }, + * { 'user': 'fred', 'age': 40, 'active': true } + * ]; + * + * // using the `_.matches` callback shorthand + * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); + * // => ['barney'] + * + * // using the `_.matchesProperty` callback shorthand + * _.pluck(_.reject(users, 'active', false), 'user'); + * // => ['fred'] + * + * // using the `_.property` callback shorthand + * _.pluck(_.reject(users, 'active'), 'user'); + * // => ['barney'] */ - function equalByTag(object, other, tag) { - switch (tag) { - case boolTag: - case dateTag: - // Coerce dates and booleans to numbers, dates to milliseconds and booleans - // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. - return +object == +other; - - case errorTag: - return object.name == other.name && object.message == other.message; - - case numberTag: - // Treat `NaN` vs. `NaN` as equal. - return (object != +object) - ? other != +other - // But, treat `-0` vs. `+0` as not equal. - : (object == 0 ? ((1 / object) == (1 / other)) : object == +other); - - case regexpTag: - case stringTag: - // Coerce regexes to strings and treat strings primitives and string - // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. - return object == (other + ''); - } - return false; + function reject(collection, predicate, thisArg) { + var func = isArray(collection) ? arrayFilter : baseFilter; + predicate = getCallback(predicate, thisArg, 3); + return func(collection, function(value, index, collection) { + return !predicate(value, index, collection); + }); } /** - * A specialized version of `baseIsEqualDeep` for objects with support for - * partial deep comparisons. + * Gets a random element or `n` random elements from a collection. * - * @private - * @param {Object} object The object to compare. - * @param {Object} other The other object to compare. - * @param {Function} equalFunc The function to determine equivalents of values. - * @param {Function} [customizer] The function to customize comparing values. - * @param {boolean} [isLoose] Specify performing partial comparisons. - * @param {Array} [stackA] Tracks traversed `value` objects. - * @param {Array} [stackB] Tracks traversed `other` objects. - * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to sample. + * @param {number} [n] The number of elements to sample. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {*} Returns the random sample(s). + * @example + * + * _.sample([1, 2, 3, 4]); + * // => 2 + * + * _.sample([1, 2, 3, 4], 2); + * // => [3, 1] */ - function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { - var objProps = keys(object), - objLength = objProps.length, - othProps = keys(other), - othLength = othProps.length; - - if (objLength != othLength && !isLoose) { - return false; - } - var skipCtor = isLoose, - index = -1; - - while (++index < objLength) { - var key = objProps[index], - result = isLoose ? key in other : hasOwnProperty.call(other, key); - - if (result) { - var objValue = object[key], - othValue = other[key]; - - result = undefined; - if (customizer) { - result = isLoose - ? customizer(othValue, objValue, key) - : customizer(objValue, othValue, key); - } - if (result === undefined) { - // Recursively compare objects (susceptible to call stack limits). - result = (objValue && objValue === othValue) || equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB); - } - } - if (!result) { - return false; - } - skipCtor || (skipCtor = key == 'constructor'); - } - if (!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)) { - return false; - } + function sample(collection, n, guard) { + if (guard ? isIterateeCall(collection, n, guard) : n == null) { + collection = toIterable(collection); + var length = collection.length; + return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; } - return true; + var result = shuffle(collection); + result.length = nativeMin(n < 0 ? 0 : (+n || 0), result.length); + return result; } /** - * Gets the extremum value of `collection` invoking `iteratee` for each value - * in `collection` to generate the criterion by which the value is ranked. - * The `iteratee` is invoked with three arguments: (value, index, collection). + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). * - * @private - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {boolean} [isMin] Specify returning the minimum, instead of the - * maximum, extremum value. - * @returns {*} Returns the extremum value. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * _.shuffle([1, 2, 3, 4]); + * // => [4, 1, 3, 2] */ - function extremumBy(collection, iteratee, isMin) { - var exValue = isMin ? POSITIVE_INFINITY : NEGATIVE_INFINITY, - computed = exValue, - result = computed; + function shuffle(collection) { + collection = toIterable(collection); - baseEach(collection, function(value, index, collection) { - var current = iteratee(value, index, collection); - if ((isMin ? (current < computed) : (current > computed)) || - (current === exValue && current === result)) { - computed = current; - result = value; + var index = -1, + length = collection.length, + result = Array(length); + + while (++index < length) { + var rand = baseRandom(0, index); + if (index != rand) { + result[index] = result[rand]; } - }); + result[rand] = collection[index]; + } return result; } /** - * Gets the appropriate "callback" function. If the `_.callback` method is - * customized this function returns the custom method, otherwise it returns - * the `baseCallback` function. If arguments are provided the chosen function - * is invoked with them and its result is returned. + * Gets the size of `collection` by returning its length for array-like + * values or the number of own enumerable properties for objects. * - * @private - * @returns {Function} Returns the chosen function or its result. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to inspect. + * @returns {number} Returns the size of `collection`. + * @example + * + * _.size([1, 2, 3]); + * // => 3 + * + * _.size({ 'a': 1, 'b': 2 }); + * // => 2 + * + * _.size('pebbles'); + * // => 7 */ - function getCallback(func, thisArg, argCount) { - var result = lodash.callback || callback; - result = result === callback ? baseCallback : result; - return argCount ? result(func, thisArg, argCount) : result; + function size(collection) { + var length = collection ? getLength(collection) : 0; + return isLength(length) ? length : keys(collection).length; } /** - * Gets metadata for `func`. + * Checks if `predicate` returns truthy for **any** element of `collection`. + * The function returns as soon as it finds a passing value and does not iterate + * over the entire collection. The predicate is bound to `thisArg` and invoked + * with three arguments: (value, index|key, collection). * - * @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`. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. * - * @private - * @param {Function} func The function to query. - * @returns {string} Returns the function name. - */ - var getFuncName = (function() { - if (!support.funcNames) { - return constant(''); - } - if (constant.name == 'constant') { - return baseProperty('name'); - } - return function(func) { - var result = func.name, - array = realNames[result], - length = array ? array.length : 0; - - while (length--) { - var data = array[length], - otherFunc = data.func; - - if (otherFunc == null || otherFunc == func) { - return data.name; - } - } - return result; - }; - }()); - - /** - * Gets the appropriate "indexOf" function. If the `_.indexOf` method is - * customized this function returns the custom method, otherwise it returns - * the `baseIndexOf` function. If arguments are provided the chosen function - * is invoked with them and its result is returned. + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. * - * @private - * @returns {Function|number} Returns the chosen function or its result. - */ - function getIndexOf(collection, target, fromIndex) { - var result = lodash.indexOf || indexOf; - result = result === indexOf ? baseIndexOf : result; - return collection ? result(collection, target, fromIndex) : result; - } - - /** - * Gets the "length" property value of `object`. + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. * - * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) - * in Safari on iOS 8.1 ARM64. + * @static + * @memberOf _ + * @alias any + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {boolean} Returns `true` if any element passes the predicate check, + * else `false`. + * @example * - * @private - * @param {Object} object The object to query. - * @returns {*} Returns the "length" value. - */ - var getLength = baseProperty('length'); - - /** - * Creates an array of the own symbols of `object`. + * _.some([null, 0, 'yes', false], Boolean); + * // => true * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of symbols. - */ - var getSymbols = !getOwnPropertySymbols ? constant([]) : function(object) { - return getOwnPropertySymbols(toObject(object)); - }; - - /** - * Gets the view, applying any `transforms` to the `start` and `end` positions. + * var users = [ + * { 'user': 'barney', 'active': true }, + * { 'user': 'fred', 'active': false } + * ]; * - * @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. + * // using the `_.matches` callback shorthand + * _.some(users, { 'user': 'barney', 'active': false }); + * // => false + * + * // using the `_.matchesProperty` callback shorthand + * _.some(users, 'active', false); + * // => true + * + * // using the `_.property` callback shorthand + * _.some(users, 'active'); + * // => true */ - function getView(start, end, transforms) { - var index = -1, - length = transforms ? transforms.length : 0; - - 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; - } + function some(collection, predicate, thisArg) { + var func = isArray(collection) ? arraySome : baseSome; + if (thisArg && isIterateeCall(collection, predicate, thisArg)) { + predicate = null; } - return { 'start': start, 'end': end }; + if (typeof predicate != 'function' || thisArg !== undefined) { + predicate = getCallback(predicate, thisArg, 3); + } + return func(collection, predicate); } /** - * Initializes an array clone. + * Creates an array of elements, sorted in ascending order by the results of + * running each element in a collection through `iteratee`. This method performs + * a stable sort, that is, it preserves the original sort order of equal elements. + * The `iteratee` is bound to `thisArg` and invoked with three arguments: + * (value, index|key, collection). * - * @private - * @param {Array} array The array to clone. - * @returns {Array} Returns the initialized clone. + * If a property name is provided for `iteratee` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `iteratee` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Array} Returns the new sorted array. + * @example + * + * _.sortBy([1, 2, 3], function(n) { + * return Math.sin(n); + * }); + * // => [3, 1, 2] + * + * _.sortBy([1, 2, 3], function(n) { + * return this.sin(n); + * }, Math); + * // => [3, 1, 2] + * + * var users = [ + * { 'user': 'fred' }, + * { 'user': 'pebbles' }, + * { 'user': 'barney' } + * ]; + * + * // using the `_.property` callback shorthand + * _.pluck(_.sortBy(users, 'user'), 'user'); + * // => ['barney', 'fred', 'pebbles'] */ - function initCloneArray(array) { - var length = array.length, - result = new array.constructor(length); - - // Add array properties assigned by `RegExp#exec`. - if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { - result.index = array.index; - result.input = array.input; + function sortBy(collection, iteratee, thisArg) { + if (collection == null) { + return []; } - return result; + if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { + iteratee = null; + } + var index = -1; + iteratee = getCallback(iteratee, thisArg, 3); + + var result = baseMap(collection, function(value, key, collection) { + return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; + }); + return baseSortBy(result, compareAscending); } /** - * Initializes an object clone. + * This method is like `_.sortBy` except that it can sort by multiple iteratees + * or property names. * - * @private - * @param {Object} object The object to clone. - * @returns {Object} Returns the initialized clone. + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. + * + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees + * The iteratees to sort by, specified as individual values or arrays of values. + * @returns {Array} Returns the new sorted array. + * @example + * + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 36 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 34 } + * ]; + * + * _.map(_.sortByAll(users, ['user', 'age']), _.values); + * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * + * _.map(_.sortByAll(users, 'user', function(chr) { + * return Math.floor(chr.age / 10); + * }), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ - function initCloneObject(object) { - var Ctor = object.constructor; - if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { - Ctor = Object; + var sortByAll = restParam(function(collection, iteratees) { + if (collection == null) { + return []; } - return new Ctor; - } + var guard = iteratees[2]; + if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { + iteratees.length = 1; + } + return baseSortByOrder(collection, baseFlatten(iteratees), []); + }); /** - * Initializes an object clone based on its `toStringTag`. + * This method is like `_.sortByAll` except that it allows specifying the + * sort orders of the iteratees to sort by. A truthy value in `orders` will + * sort the corresponding property name in ascending order while a falsey + * value will sort it in descending order. * - * **Note:** This function only supports cloning values with tags of - * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. + * If a property name is provided for an iteratee the created `_.property` + * style callback returns the property value of the given element. * - * @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 bufferClone(object); - - case boolTag: - case dateTag: - return new Ctor(+object); - - case float32Tag: case float64Tag: - case int8Tag: case int16Tag: case int32Tag: - case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: - var buffer = object.buffer; - return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); - - case numberTag: - case stringTag: - return new Ctor(object); - - case regexpTag: - var result = new Ctor(object.source, reFlags.exec(object)); - result.lastIndex = object.lastIndex; - } - return result; - } - - /** - * Invokes the method at `path` on `object`. + * If an object is provided for an iteratee the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. * - * @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 invokePath(object, path, args) { - if (object != null && !isKey(path, object)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - path = last(path); - } - var func = object == null ? object : object[path]; - return func == null ? undefined : func.apply(object, args); - } - - /** - * Checks if `value` is a valid array-like index. + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to iterate over. + * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. + * @param {boolean[]} orders The sort orders of `iteratees`. + * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. + * @returns {Array} Returns the new sorted array. + * @example * - * @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) { - value = +value; - length = length == null ? MAX_SAFE_INTEGER : length; - return value > -1 && value % 1 == 0 && value < length; - } - - /** - * Checks if the provided arguments are from an iteratee call. + * var users = [ + * { 'user': 'fred', 'age': 48 }, + * { 'user': 'barney', 'age': 34 }, + * { 'user': 'fred', 'age': 42 }, + * { 'user': 'barney', 'age': 36 } + * ]; * - * @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`. + * // sort by `user` in ascending order and by `age` in descending order + * _.map(_.sortByOrder(users, ['user', 'age'], [true, false]), _.values); + * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] */ - function isIterateeCall(value, index, object) { - if (!isObject(object)) { - return false; + function sortByOrder(collection, iteratees, orders, guard) { + if (collection == null) { + return []; } - var type = typeof index; - if (type == 'number') { - var length = getLength(object), - prereq = isLength(length) && isIndex(index, length); - } else { - prereq = type == 'string' && index in object; + if (guard && isIterateeCall(iteratees, orders, guard)) { + orders = null; } - if (prereq) { - var other = object[index]; - return value === value ? (value === other) : (other !== other); + if (!isArray(iteratees)) { + iteratees = iteratees == null ? [] : [iteratees]; } - return false; + if (!isArray(orders)) { + orders = orders == null ? [] : [orders]; + } + return baseSortByOrder(collection, iteratees, orders); } /** - * Checks if `value` is a property name and not a property path. + * Performs a deep comparison between each element in `collection` and the + * source object, returning an array of all elements that have equivalent + * property values. * - * @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`. + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. For comparing a single + * own or inherited property value see `_.matchesProperty`. + * + * @static + * @memberOf _ + * @category Collection + * @param {Array|Object|string} collection The collection to search. + * @param {Object} source The object of property values to match. + * @returns {Array} Returns the new filtered array. + * @example + * + * var users = [ + * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, + * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } + * ]; + * + * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); + * // => ['barney'] + * + * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); + * // => ['fred'] */ - function isKey(value, object) { - var type = typeof value; - if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { - return true; - } - if (isArray(value)) { - return false; - } - var result = !reIsDeepProp.test(value); - return result || (object != null && value in toObject(object)); + function where(collection, source) { + return filter(collection, baseMatches(source)); } /** - * Checks if `func` has a lazy counterpart. + * Gets the number of milliseconds that have elapsed since the Unix epoch + * (1 January 1970 00:00:00 UTC). * - * @private - * @param {Function} func The function to check. - * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. + * @static + * @memberOf _ + * @category Date + * @example + * + * _.defer(function(stamp) { + * console.log(_.now() - stamp); + * }, _.now()); + * // => logs the number of milliseconds it took for the deferred function to be invoked */ - function isLaziable(func) { - var funcName = getFuncName(func); - return !!funcName && func === lodash[funcName] && funcName in LazyWrapper.prototype; - } + var now = nativeNow || function() { + return new Date().getTime(); + }; /** - * Checks if `value` is a valid array-like length. + * The opposite of `_.before`; this method creates a function that invokes + * `func` once it is called `n` or more times. * - * **Note:** This function is based on [`ToLength`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength). + * @static + * @memberOf _ + * @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 * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * 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 isLength(value) { - return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + function after(n, func) { + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } + } + n = nativeIsFinite(n = +n) ? n : 0; + return function() { + if (--n < 1) { + return func.apply(this, arguments); + } + }; } /** - * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. + * Creates a function that accepts up to `n` arguments ignoring any + * additional arguments. * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` if suitable for strict - * equality comparisons, else `false`. + * @static + * @memberOf _ + * @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 a callback for functions like `_.map`. + * @returns {Function} Returns the new function. + * @example + * + * _.map(['6', '8', '10'], _.ary(parseInt, 1)); + * // => [6, 8, 10] */ - function isStrictComparable(value) { - return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value)); + function ary(func, n, guard) { + if (guard && isIterateeCall(func, n, guard)) { + n = null; + } + n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); + return createWrapper(func, ARY_FLAG, null, null, null, null, n); } /** - * Merges the function metadata of `source` into `data`. + * Creates a function that invokes `func`, with the `this` binding and arguments + * of the created function, while it is called less than `n` times. Subsequent + * calls to the created function return the result of the last `func` invocation. * - * Merging metadata reduces the number of wrappers required 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` - * augment function arguments, making the order in which they are executed important, - * preventing the merging of metadata. However, we make an exception for a safe - * common case where curried functions have `_.ary` and or `_.rearg` applied. + * @static + * @memberOf _ + * @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 * - * @private - * @param {Array} data The destination metadata. - * @param {Array} source The source metadata. - * @returns {Array} Returns `data`. + * jQuery('#add').on('click', _.before(5, addContactToList)); + * // => allows adding up to 4 contacts to the list */ - function mergeData(data, source) { - var bitmask = data[1], - srcBitmask = source[1], - newBitmask = bitmask | srcBitmask, - isCommon = newBitmask < ARY_FLAG; - - var isCombo = - (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || - (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || - (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); - - // Exit early if metadata can't be merged. - if (!(isCommon || isCombo)) { - return data; - } - // Use source `thisArg` if available. - if (srcBitmask & BIND_FLAG) { - data[2] = source[2]; - // Set when currying a bound function. - newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; - } - // Compose partial arguments. - var value = source[3]; - if (value) { - var partials = data[3]; - data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); - data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); - } - // Compose partial right arguments. - value = source[5]; - if (value) { - partials = data[5]; - data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); - data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); - } - // Use source `argPos` if available. - value = source[7]; - if (value) { - data[7] = arrayCopy(value); - } - // Use source `ary` if it's smaller. - if (srcBitmask & ARY_FLAG) { - data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); - } - // Use source `arity` if one is not provided. - if (data[9] == null) { - data[9] = source[9]; + function before(n, func) { + var result; + if (typeof func != 'function') { + if (typeof n == 'function') { + var temp = n; + n = func; + func = temp; + } else { + throw new TypeError(FUNC_ERROR_TEXT); + } } - // Use source `func` and merge bitmasks. - data[0] = source[0]; - data[1] = newBitmask; - - return data; + return function() { + if (--n > 0) { + result = func.apply(this, arguments); + } + if (n <= 1) { + func = null; + } + return result; + }; } /** - * A specialized version of `_.pick` that picks `object` properties specified - * by `props`. + * Creates a function that invokes `func` with the `this` binding of `thisArg` + * and prepends any additional `_.bind` arguments to those provided to the + * bound function. * - * @private - * @param {Object} object The source object. - * @param {string[]} props The property names to pick. - * @returns {Object} Returns the new object. + * 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 does not set the "length" + * property of bound functions. + * + * @static + * @memberOf _ + * @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 + * + * var greet = function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * }; + * + * var object = { 'user': 'fred' }; + * + * var bound = _.bind(greet, object, 'hi'); + * bound('!'); + * // => 'hi fred!' + * + * // using placeholders + * var bound = _.bind(greet, object, _, '!'); + * bound('hi'); + * // => 'hi fred!' */ - function pickByArray(object, props) { - object = toObject(object); - - var index = -1, - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index]; - if (key in object) { - result[key] = object[key]; - } + var bind = restParam(function(func, thisArg, partials) { + var bitmask = BIND_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bind.placeholder); + bitmask |= PARTIAL_FLAG; } - return result; - } + return createWrapper(func, bitmask, thisArg, partials, holders); + }); /** - * A specialized version of `_.pick` that picks `object` properties `predicate` - * returns truthy for. + * Binds methods of an object to the object itself, overwriting the existing + * method. Method names may be specified as individual arguments or as arrays + * of method names. If no method names are provided all enumerable function + * properties, own and inherited, of `object` are bound. * - * @private - * @param {Object} object The source object. - * @param {Function} predicate The function invoked per iteration. - * @returns {Object} Returns the new object. - */ - function pickByCallback(object, predicate) { - var result = {}; - baseForIn(object, function(value, key, object) { - if (predicate(value, key, object)) { - result[key] = value; - } - }); - return result; - } - - /** - * 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. + * **Note:** This method does not set the "length" property of bound functions. * - * @private - * @param {Array} array The array to reorder. - * @param {Array} indexes The arranged array indexes. - * @returns {Array} Returns `array`. + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object to bind and assign the bound methods to. + * @param {...(string|string[])} [methodNames] The object method names to bind, + * specified as individual method names or arrays of method names. + * @returns {Object} Returns `object`. + * @example + * + * var view = { + * 'label': 'docs', + * 'onClick': function() { + * console.log('clicked ' + this.label); + * } + * }; + * + * _.bindAll(view); + * jQuery('#docs').on('click', view.onClick); + * // => logs 'clicked docs' when the element is clicked */ - function reorder(array, indexes) { - var arrLength = array.length, - length = nativeMin(indexes.length, arrLength), - oldArray = arrayCopy(array); + var bindAll = restParam(function(object, methodNames) { + methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); - while (length--) { - var index = indexes[length]; - array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; + var index = -1, + length = methodNames.length; + + while (++index < length) { + var key = methodNames[index]; + object[key] = createWrapper(object[key], BIND_FLAG, object); } - return array; - } + return object; + }); /** - * Sets metadata for `func`. + * Creates a function that invokes the method at `object[key]` and prepends + * any additional `_.bindKey` arguments to those provided to the bound function. * - * **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://code.google.com/p/v8/issues/detail?id=2070) + * 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. * - * @private - * @param {Function} func The function to associate metadata with. - * @param {*} data The metadata. - * @returns {Function} Returns `func`. - */ - var setData = (function() { - var count = 0, - lastCalled = 0; - - return function(key, value) { - var stamp = now(), - remaining = HOT_SPAN - (stamp - lastCalled); - - lastCalled = stamp; - if (remaining > 0) { - if (++count >= HOT_COUNT) { - return key; - } - } else { - count = 0; - } - return baseSetData(key, value); - }; - }()); - - /** - * A fallback implementation of `_.isPlainObject` which checks if `value` - * is an object created by the `Object` constructor or has a `[[Prototype]]` - * of `null`. + * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. - */ - function shimIsPlainObject(value) { - var Ctor, - support = lodash.support; - - // Exit early for non `Object` objects. - if (!(isObjectLike(value) && objToString.call(value) == objectTag) || - (!hasOwnProperty.call(value, 'constructor') && - (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { - return false; - } - // IE < 9 iterates inherited properties before own properties. If the first - // iterated property is an object's own property then there are no inherited - // enumerable properties. - var result; - // In most environments an object's own properties are iterated before - // its inherited properties. If the last iterated property is an object's - // own property then there are no inherited enumerable properties. - baseForIn(value, function(subValue, key) { - result = key; - }); - return result === undefined || hasOwnProperty.call(value, result); - } - - /** - * A fallback implementation of `Object.keys` which creates an array of the - * own enumerable property names of `object`. + * @static + * @memberOf _ + * @category Function + * @param {Object} object The object the method belongs to. + * @param {string} key The key of the method. + * @param {...*} [partials] The arguments to be partially applied. + * @returns {Function} Returns the new bound function. + * @example * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function shimKeys(object) { - var props = keysIn(object), - propsLength = props.length, - length = propsLength && object.length, - support = lodash.support; - - var allowIndexes = length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))); - - var index = -1, - result = []; - - while (++index < propsLength) { - var key = props[index]; - if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { - result.push(key); - } - } - return result; - } - - /** - * Converts `value` to an array-like object if it is not one. + * var object = { + * 'user': 'fred', + * 'greet': function(greeting, punctuation) { + * return greeting + ' ' + this.user + punctuation; + * } + * }; * - * @private - * @param {*} value The value to process. - * @returns {Array|Object} Returns the array-like object. - */ - function toIterable(value) { - if (value == null) { - return []; - } - if (!isLength(getLength(value))) { - return values(value); - } - return isObject(value) ? value : Object(value); - } - - /** - * Converts `value` to an object if it is not one. + * var bound = _.bindKey(object, 'greet', 'hi'); + * bound('!'); + * // => 'hi fred!' * - * @private - * @param {*} value The value to process. - * @returns {Object} Returns the object. - */ - function toObject(value) { - return isObject(value) ? value : Object(value); - } - - /** - * Converts `value` to property path array if it is not one. + * object.greet = function(greeting, punctuation) { + * return greeting + 'ya ' + this.user + punctuation; + * }; * - * @private - * @param {*} value The value to process. - * @returns {Array} Returns the property path array. + * bound('!'); + * // => 'hiya fred!' + * + * // using placeholders + * var bound = _.bindKey(object, 'greet', _, '!'); + * bound('hi'); + * // => 'hiya fred!' */ - function toPath(value) { - if (isArray(value)) { - return value; + var bindKey = restParam(function(object, key, partials) { + var bitmask = BIND_FLAG | BIND_KEY_FLAG; + if (partials.length) { + var holders = replaceHolders(partials, bindKey.placeholder); + bitmask |= PARTIAL_FLAG; } - var result = []; - baseToString(value).replace(rePropName, function(match, number, quote, string) { - result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); - }); - return result; - } + return createWrapper(key, bitmask, object, partials, holders); + }); /** - * Creates a clone of `wrapper`. + * Creates a function that accepts one or more arguments of `func` that when + * called either invokes `func` returning its result, if all `func` arguments + * have been provided, or returns a function that accepts one or more of the + * remaining `func` arguments, and so on. The arity of `func` may be specified + * if `func.length` is not sufficient. * - * @private - * @param {Object} wrapper The wrapper to clone. - * @returns {Object} Returns the cloned wrapper. - */ - function wrapperClone(wrapper) { - return wrapper instanceof LazyWrapper - ? wrapper.clone() - : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates an array of elements split into groups the length of `size`. - * If `collection` can't be split evenly, the final chunk will be the remaining - * elements. + * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, + * may be used as a placeholder for provided arguments. + * + * **Note:** This method does not set the "length" property of curried functions. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to process. - * @param {number} [size=1] The length of each chunk. + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the new array containing chunks. + * @returns {Function} Returns the new curried function. * @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 == null) { - size = 1; - } else { - size = nativeMax(+size || 1, 1); - } - var index = 0, - length = array ? array.length : 0, - resIndex = -1, - result = Array(ceil(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. + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to compact. - * @returns {Array} Returns the new array of filtered values. - * @example + * var curried = _.curry(abc); * - * _.compact([0, 1, false, 2, '', 3]); + * curried(1)(2)(3); * // => [1, 2, 3] - */ - function compact(array) { - var index = -1, - length = array ? array.length : 0, - resIndex = -1, - result = []; - - while (++index < length) { - var value = array[index]; - if (value) { - result[++resIndex] = value; - } - } - return result; - } - - /** - * Creates an array excluding all values of the provided arrays using - * `SameValueZero` for equality comparisons. * - * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * comparisons are like strict equality comparisons, e.g. `===`, except that - * `NaN` matches `NaN`. + * curried(1, 2)(3); + * // => [1, 2, 3] * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to inspect. - * @param {...Array} [values] The arrays of values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @example + * curried(1, 2, 3); + * // => [1, 2, 3] * - * _.difference([1, 2, 3], [4, 2]); - * // => [1, 3] + * // using placeholders + * curried(1)(_, 3)(2); + * // => [1, 2, 3] */ - var difference = restParam(function(array, values) { - return (isArray(array) || isArguments(array)) - ? baseDifference(array, baseFlatten(values, false, true)) - : []; - }); + var curry = createCurry(CURRY_FLAG); /** - * Creates a slice of `array` with `n` elements dropped from the beginning. + * 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 does not set the "length" property of curried functions. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {number} [n=1] The number of elements to drop. + * @category Function + * @param {Function} func The function to curry. + * @param {number} [arity=func.length] The arity of `func`. * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. + * @returns {Function} Returns the new curried function. * @example * - * _.drop([1, 2, 3]); - * // => [2, 3] + * var abc = function(a, b, c) { + * return [a, b, c]; + * }; * - * _.drop([1, 2, 3], 2); - * // => [3] + * var curried = _.curryRight(abc); * - * _.drop([1, 2, 3], 5); - * // => [] - * - * _.drop([1, 2, 3], 0); + * curried(3)(2)(1); * // => [1, 2, 3] - */ - function drop(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - return baseSlice(array, n < 0 ? 0 : n); - } - - /** - * Creates a slice of `array` with `n` elements dropped from the end. - * - * @static - * @memberOf _ - * @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 a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. - * @example * - * _.dropRight([1, 2, 3]); - * // => [1, 2] - * - * _.dropRight([1, 2, 3], 2); - * // => [1] + * curried(2, 3)(1); + * // => [1, 2, 3] * - * _.dropRight([1, 2, 3], 5); - * // => [] + * curried(1, 2, 3); + * // => [1, 2, 3] * - * _.dropRight([1, 2, 3], 0); + * // using placeholders + * curried(3)(1, _)(2); * // => [1, 2, 3] */ - function dropRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - n = length - (+n || 0); - return baseSlice(array, 0, n < 0 ? 0 : n); - } + var curryRight = createCurry(CURRY_RIGHT_FLAG); /** - * Creates a slice of `array` excluding elements dropped from the end. - * Elements are dropped until `predicate` returns falsey. The predicate is - * bound to `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. + * Creates a function that delays invoking `func` until after `wait` milliseconds + * have elapsed since the last time it was invoked. The created function comes + * with a `cancel` method to cancel delayed invocations. Provide an options + * object to indicate that `func` should be invoked on the leading and/or + * trailing edge of the `wait` timeout. Subsequent calls to the debounced + * function return the result of the last `func` invocation. * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the debounced function is + * invoked more than once during the `wait` timeout. * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that match the properties of the given - * object, else `false`. + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. + * @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 is invoked. + * @param {boolean} [options.trailing=true] Specify invoking on the trailing + * edge of the timeout. + * @returns {Function} Returns the new debounced function. * @example * - * _.dropRightWhile([1, 2, 3], function(n) { - * return n > 1; - * }); - * // => [1] - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); - * // => ['barney', 'fred'] - * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); - * // => ['barney'] - * - * // using the `_.property` callback shorthand - * _.pluck(_.dropRightWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] - */ - function dropRightWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) - : []; - } - - /** - * Creates a slice of `array` excluding elements dropped from the beginning. - * Elements are dropped until `predicate` returns falsey. The predicate is - * bound to `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * // avoid costly calculations while the window size is in flux + * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. - * @example + * // invoke `sendMail` when the click event is fired, debouncing subsequent calls + * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { + * 'leading': true, + * 'trailing': false + * })); * - * _.dropWhile([1, 2, 3], function(n) { - * return n < 3; - * }); - * // => [3] + * // ensure `batchLog` is invoked once after 1 second of debounced calls + * var source = new EventSource('/stream'); + * jQuery(source).on('message', _.debounce(batchLog, 250, { + * 'maxWait': 1000 + * })); * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; + * // cancel a debounced call + * var todoChanges = _.debounce(batchLog, 1000); + * Object.observe(models.todo, todoChanges); * - * // using the `_.matches` callback shorthand - * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); - * // => ['fred', 'pebbles'] + * Object.observe(models, function(changes) { + * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { + * todoChanges.cancel(); + * } + * }, ['delete']); * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.dropWhile(users, 'active', false), 'user'); - * // => ['pebbles'] + * // ...at some point `models.todo` is changed + * models.todo.completed = true; * - * // using the `_.property` callback shorthand - * _.pluck(_.dropWhile(users, 'active'), 'user'); - * // => ['barney', 'fred', 'pebbles'] + * // ...before 1 second has passed `models.todo` is deleted + * // which cancels the debounced `todoChanges` call + * delete models.todo; */ - function dropWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), true) - : []; - } + function debounce(func, wait, options) { + var args, + maxTimeoutId, + result, + stamp, + thisArg, + timeoutId, + trailingCall, + lastCalled = 0, + maxWait = false, + trailing = true; - /** - * Fills elements of `array` with `value` from `start` up to, but not - * including, `end`. - * - * **Note:** This method mutates `array`. - * - * @static - * @memberOf _ - * @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], '*', 1, 2); - * // => [4, '*', 8] - */ - function fill(array, value, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); } - if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { - start = 0; - end = length; + wait = wait < 0 ? 0 : (+wait || 0); + if (options === true) { + var leading = true; + trailing = false; + } else if (isObject(options)) { + leading = options.leading; + maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); + trailing = 'trailing' in options ? options.trailing : trailing; } - 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. - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + function cancel() { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + } + + function delayed() { + var remaining = wait - (now() - stamp); + if (remaining <= 0 || remaining > wait) { + if (maxTimeoutId) { + clearTimeout(maxTimeoutId); + } + var isCalled = trailingCall; + maxTimeoutId = timeoutId = trailingCall = undefined; + if (isCalled) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } else { + timeoutId = setTimeout(delayed, remaining); + } + } + + function maxDelayed() { + if (timeoutId) { + clearTimeout(timeoutId); + } + maxTimeoutId = timeoutId = trailingCall = undefined; + if (trailing || (maxWait !== wait)) { + lastCalled = now(); + result = func.apply(thisArg, args); + if (!timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + } + } + + function debounced() { + args = arguments; + stamp = now(); + thisArg = this; + trailingCall = trailing && (timeoutId || !leading); + + if (maxWait === false) { + var leadingCall = leading && !timeoutId; + } else { + if (!maxTimeoutId && !leading) { + lastCalled = stamp; + } + var remaining = maxWait - (stamp - lastCalled), + isCalled = remaining <= 0 || remaining > maxWait; + + if (isCalled) { + if (maxTimeoutId) { + maxTimeoutId = clearTimeout(maxTimeoutId); + } + lastCalled = stamp; + result = func.apply(thisArg, args); + } + else if (!maxTimeoutId) { + maxTimeoutId = setTimeout(maxDelayed, remaining); + } + } + if (isCalled && timeoutId) { + timeoutId = clearTimeout(timeoutId); + } + else if (!timeoutId && wait !== maxWait) { + timeoutId = setTimeout(delayed, wait); + } + if (leadingCall) { + isCalled = true; + result = func.apply(thisArg, args); + } + if (isCalled && !timeoutId && !maxTimeoutId) { + args = thisArg = null; + } + return result; + } + debounced.cancel = cancel; + return debounced; + } + + /** + * Defers invoking the `func` until the current call stack has cleared. Any + * additional arguments are provided to `func` when it is invoked. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {number} Returns the index of the found element, else `-1`. + * @category Function + * @param {Function} func The function to defer. + * @param {...*} [args] The arguments to invoke the function with. + * @returns {number} Returns the timer id. * @example * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * _.findIndex(users, function(chr) { - * return chr.user == 'barney'; - * }); - * // => 0 - * - * // using the `_.matches` callback shorthand - * _.findIndex(users, { 'user': 'fred', 'active': false }); - * // => 1 - * - * // using the `_.matchesProperty` callback shorthand - * _.findIndex(users, 'active', false); - * // => 0 - * - * // using the `_.property` callback shorthand - * _.findIndex(users, 'active'); - * // => 2 + * _.defer(function(text) { + * console.log(text); + * }, 'deferred'); + * // logs 'deferred' after one or more milliseconds */ - var findIndex = createFindIndex(); + var defer = restParam(function(func, args) { + return baseDelay(func, 1, args); + }); /** - * This method is like `_.findIndex` except that it iterates over elements - * of `collection` from right to left. - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * Invokes `func` after `wait` milliseconds. Any additional arguments are + * provided to `func` when it is invoked. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {number} Returns the index of the found element, else `-1`. + * @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 the function with. + * @returns {number} Returns the timer id. * @example * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * _.findLastIndex(users, function(chr) { - * return chr.user == 'pebbles'; - * }); - * // => 2 - * - * // using the `_.matches` callback shorthand - * _.findLastIndex(users, { 'user': 'barney', 'active': true }); - * // => 0 - * - * // using the `_.matchesProperty` callback shorthand - * _.findLastIndex(users, 'active', false); - * // => 2 - * - * // using the `_.property` callback shorthand - * _.findLastIndex(users, 'active'); - * // => 0 + * _.delay(function(text) { + * console.log(text); + * }, 1000, 'later'); + * // => logs 'later' after one second */ - var findLastIndex = createFindIndex(true); + var delay = restParam(function(func, wait, args) { + return baseDelay(func, wait, args); + }); /** - * Gets the first element of `array`. + * Creates a function that returns the result of invoking the provided + * functions with the `this` binding of the created function, where each + * successive invocation is supplied the return value of the previous. * * @static * @memberOf _ - * @alias head - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the first element of `array`. + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. * @example * - * _.first([1, 2, 3]); - * // => 1 + * function square(n) { + * return n * n; + * } * - * _.first([]); - * // => undefined + * var addSquare = _.flow(_.add, square); + * addSquare(1, 2); + * // => 9 */ - function first(array) { - return array ? array[0] : undefined; - } + var flow = createFlow(); /** - * Flattens a nested array. If `isDeep` is `true` the array is recursively - * flattened, otherwise it is only flattened a single level. + * This method is like `_.flow` except that it creates a function that + * invokes the provided functions from right to left. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to flatten. - * @param {boolean} [isDeep] Specify a deep flatten. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Array} Returns the new flattened array. + * @alias backflow, compose + * @category Function + * @param {...Function} [funcs] Functions to invoke. + * @returns {Function} Returns the new function. * @example * - * _.flatten([1, [2, 3, [4]]]); - * // => [1, 2, 3, [4]] + * function square(n) { + * return n * n; + * } * - * // using `isDeep` - * _.flatten([1, [2, 3, [4]]], true); - * // => [1, 2, 3, 4] + * var addSquare = _.flowRight(square, _.add); + * addSquare(1, 2); + * // => 9 */ - function flatten(array, isDeep, guard) { - var length = array ? array.length : 0; - if (guard && isIterateeCall(array, isDeep, guard)) { - isDeep = false; - } - return length ? baseFlatten(array, isDeep) : []; - } + var flowRight = createFlow(true); /** - * Recursively flattens a nested array. + * 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 coerced to a string and used as the + * 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`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) + * method interface of `get`, `has`, and `set`. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to recursively flatten. - * @returns {Array} Returns the new flattened array. + * @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 memoizing function. * @example * - * _.flattenDeep([1, [2, 3, [4]]]); - * // => [1, 2, 3, 4] - */ - function flattenDeep(array) { - var length = array ? array.length : 0; - return length ? baseFlatten(array, true) : []; - } - - /** - * Gets the index at which the first occurrence of `value` is found in `array` - * using `SameValueZero` for equality comparisons. If `fromIndex` is negative, - * it is used as the offset from the end of `array`. If `array` is sorted - * providing `true` for `fromIndex` performs a faster binary search. + * var upperCase = _.memoize(function(string) { + * return string.toUpperCase(); + * }); * - * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * comparisons are like strict equality comparisons, e.g. `===`, except that - * `NaN` matches `NaN`. + * upperCase('fred'); + * // => 'FRED' * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=0] The index to search from or `true` - * to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value, else `-1`. - * @example + * // modifying the result cache + * upperCase.cache.set('fred', 'BARNEY'); + * upperCase('fred'); + * // => 'BARNEY' * - * _.indexOf([1, 2, 1, 2], 2); - * // => 1 + * // replacing `_.memoize.Cache` + * var object = { 'user': 'fred' }; + * var other = { 'user': 'barney' }; + * var identity = _.memoize(_.identity); * - * // using `fromIndex` - * _.indexOf([1, 2, 1, 2], 2, 2); - * // => 3 + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'fred' } * - * // performing a binary search - * _.indexOf([1, 1, 2, 2], 2, true); - * // => 2 + * _.memoize.Cache = WeakMap; + * var identity = _.memoize(_.identity); + * + * identity(object); + * // => { 'user': 'fred' } + * identity(other); + * // => { 'user': 'barney' } */ - function indexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; + function memoize(func, resolver) { + if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { + throw new TypeError(FUNC_ERROR_TEXT); } - if (typeof fromIndex == 'number') { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; - } else if (fromIndex) { - var index = binaryIndex(array, value), - other = array[index]; + var memoized = function() { + var args = arguments, + cache = memoized.cache, + key = resolver ? resolver.apply(this, args) : args[0]; - if (value === value ? (value === other) : (other !== other)) { - return index; + if (cache.has(key)) { + return cache.get(key); } - return -1; - } - return baseIndexOf(array, value, fromIndex || 0); + var result = func.apply(this, args); + cache.set(key, result); + return result; + }; + memoized.cache = new memoize.Cache; + return memoized; } /** - * Gets all but the last element of `array`. + * 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 _ - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. + * @category Function + * @param {Function} predicate The predicate to negate. + * @returns {Function} Returns the new function. * @example * - * _.initial([1, 2, 3]); - * // => [1, 2] + * function isEven(n) { + * return n % 2 == 0; + * } + * + * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); + * // => [1, 3, 5] */ - function initial(array) { - return dropRight(array, 1); + function negate(predicate) { + if (typeof predicate != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function() { + return !predicate.apply(this, arguments); + }; } /** - * Creates an array of unique values in all provided arrays using `SameValueZero` - * for equality comparisons. - * - * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * comparisons are like strict equality comparisons, e.g. `===`, except that - * `NaN` matches `NaN`. + * Creates a function that is restricted to invoking `func` once. Repeat calls + * to the function return the value of the first call. The `func` is invoked + * with the `this` binding and arguments of the created function. * * @static * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of shared values. + * @category Function + * @param {Function} func The function to restrict. + * @returns {Function} Returns the new restricted function. * @example - * _.intersection([1, 2], [4, 2], [2, 1]); - * // => [2] + * + * var initialize = _.once(createApplication); + * initialize(); + * initialize(); + * // `initialize` invokes `createApplication` once */ - function intersection() { - var args = [], - argsIndex = -1, - argsLength = arguments.length, - caches = [], - indexOf = getIndexOf(), - isCommon = indexOf == baseIndexOf, - result = []; - - while (++argsIndex < argsLength) { - var value = arguments[argsIndex]; - if (isArray(value) || isArguments(value)) { - args.push(value); - caches.push((isCommon && value.length >= 120) ? createCache(argsIndex && value) : null); - } - } - argsLength = args.length; - if (argsLength < 2) { - return result; - } - var array = args[0], - index = -1, - length = array ? array.length : 0, - seen = caches[0]; - - outer: - while (++index < length) { - value = array[index]; - if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { - argsIndex = argsLength; - while (--argsIndex) { - var cache = caches[argsIndex]; - if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value, 0)) < 0) { - continue outer; - } - } - if (seen) { - seen.push(value); - } - result.push(value); - } - } - return result; + function once(func) { + return before(2, func); } /** - * Gets the last element of `array`. + * Creates a function that invokes `func` with `partial` arguments prepended + * to those provided to the new function. 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 does not set the "length" property of partially + * applied functions. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @returns {*} Returns the last element of `array`. + * @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 * - * _.last([1, 2, 3]); - * // => 3 + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; + * + * var sayHelloTo = _.partial(greet, 'hello'); + * sayHelloTo('fred'); + * // => 'hello fred' + * + * // using placeholders + * var greetFred = _.partial(greet, _, 'fred'); + * greetFred('hi'); + * // => 'hi fred' */ - function last(array) { - var length = array ? array.length : 0; - return length ? array[length - 1] : undefined; - } + var partial = createPartial(PARTIAL_FLAG); /** - * This method is like `_.indexOf` except that it iterates over elements of - * `array` from right to left. + * This method is like `_.partial` except that partially applied arguments + * are appended to those provided to the new function. + * + * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic + * builds, may be used as a placeholder for partially applied arguments. + * + * **Note:** This method does not set the "length" property of partially + * applied functions. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to search. - * @param {*} value The value to search for. - * @param {boolean|number} [fromIndex=array.length-1] The index to search from - * or `true` to perform a binary search on a sorted array. - * @returns {number} Returns the index of the matched value, else `-1`. + * @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 * - * _.lastIndexOf([1, 2, 1, 2], 2); - * // => 3 + * var greet = function(greeting, name) { + * return greeting + ' ' + name; + * }; * - * // using `fromIndex` - * _.lastIndexOf([1, 2, 1, 2], 2, 2); - * // => 1 + * var greetFred = _.partialRight(greet, 'fred'); + * greetFred('hi'); + * // => 'hi fred' * - * // performing a binary search - * _.lastIndexOf([1, 1, 2, 2], 2, true); - * // => 3 - */ - function lastIndexOf(array, value, fromIndex) { - var length = array ? array.length : 0; - if (!length) { - return -1; - } - var index = length; - if (typeof fromIndex == 'number') { - index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; - } else if (fromIndex) { - index = binaryIndex(array, value, true) - 1; - var other = array[index]; - if (value === value ? (value === other) : (other !== other)) { - return index; - } - return -1; - } - if (value !== value) { - return indexOfNaN(array, index, true); - } - while (index--) { - if (array[index] === value) { - return index; - } - } - return -1; - } - - /** - * Removes all provided values from `array` using `SameValueZero` for equality - * comparisons. - * - * **Notes:** - * - Unlike `_.without`, this method mutates `array` - * - [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * comparisons are like strict equality comparisons, e.g. `===`, except - * that `NaN` matches `NaN` - * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to modify. - * @param {...*} [values] The values to remove. - * @returns {Array} Returns `array`. - * @example - * - * var array = [1, 2, 3, 1, 2, 3]; - * - * _.pull(array, 2, 3); - * console.log(array); - * // => [1, 1] + * // using placeholders + * var sayHelloTo = _.partialRight(greet, 'hello', _); + * sayHelloTo('fred'); + * // => 'hello fred' */ - function pull() { - var args = arguments, - array = args[0]; - - if (!(array && array.length)) { - return array; - } - var index = 0, - indexOf = getIndexOf(), - length = args.length; - - while (++index < length) { - var fromIndex = 0, - value = args[index]; - - while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { - splice.call(array, fromIndex, 1); - } - } - return array; - } + var partialRight = createPartial(PARTIAL_RIGHT_FLAG); /** - * Removes elements from `array` corresponding to the given indexes and returns - * an array of the removed elements. Indexes may be specified as an array of - * indexes or as individual arguments. - * - * **Note:** Unlike `_.at`, this method mutates `array`. + * 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 _ - * @category Array - * @param {Array} array The array to modify. - * @param {...(number|number[])} [indexes] The indexes of elements to remove, + * @category Function + * @param {Function} func The function to rearrange arguments for. + * @param {...(number|number[])} indexes The arranged argument indexes, * specified as individual indexes or arrays of indexes. - * @returns {Array} Returns the new array of removed elements. + * @returns {Function} Returns the new function. * @example * - * var array = [5, 10, 15, 20]; - * var evens = _.pullAt(array, 1, 3); + * var rearged = _.rearg(function(a, b, c) { + * return [a, b, c]; + * }, 2, 0, 1); * - * console.log(array); - * // => [5, 15] + * rearged('b', 'c', 'a') + * // => ['a', 'b', 'c'] * - * console.log(evens); - * // => [10, 20] + * var map = _.rearg(_.map, [1, 0]); + * map(function(n) { + * return n * 3; + * }, [1, 2, 3]); + * // => [3, 6, 9] */ - var pullAt = restParam(function(array, indexes) { - array || (array = []); - indexes = baseFlatten(indexes); - - var result = baseAt(array, indexes); - basePullAt(array, indexes.sort(baseCompareAscending)); - return result; + var rearg = restParam(function(func, indexes) { + return createWrapper(func, REARG_FLAG, null, null, null, baseFlatten(indexes)); }); /** - * Removes all elements from `array` that `predicate` returns truthy for - * and returns an array of the removed elements. The predicate is bound to - * `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * 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:** Unlike `_.filter`, this method mutates `array`. + * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to modify. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new array of removed elements. + * @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 array = [1, 2, 3, 4]; - * var evens = _.remove(array, function(n) { - * return n % 2 == 0; + * var say = _.restParam(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); * }); * - * console.log(array); - * // => [1, 3] - * - * console.log(evens); - * // => [2, 4] + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' */ - function remove(array, predicate, thisArg) { - var result = []; - if (!(array && array.length)) { - return result; + function restParam(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); } - var index = -1, - indexes = [], - length = array.length; + start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + rest = Array(length); - predicate = getCallback(predicate, thisArg, 3); - while (++index < length) { - var value = array[index]; - if (predicate(value, index, array)) { - result.push(value); - indexes.push(index); + while (++index < length) { + rest[index] = args[start + index]; } - } - basePullAt(array, indexes); - return result; + switch (start) { + case 0: return func.call(this, rest); + case 1: return func.call(this, args[0], rest); + case 2: return func.call(this, args[0], args[1], rest); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = rest; + return func.apply(this, otherArgs); + }; } /** - * Gets all but the first element of `array`. + * Creates a function that invokes `func` with the `this` binding of the created + * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). + * + * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). * * @static * @memberOf _ - * @alias tail - * @category Array - * @param {Array} array The array to query. - * @returns {Array} Returns the slice of `array`. + * @category Function + * @param {Function} func The function to spread arguments over. + * @returns {Function} Returns the new function. * @example * - * _.rest([1, 2, 3]); - * // => [2, 3] + * var say = _.spread(function(who, what) { + * return who + ' says ' + what; + * }); + * + * say(['fred', 'hello']); + * // => 'fred says hello' + * + * // with a Promise + * var numbers = Promise.all([ + * Promise.resolve(40), + * Promise.resolve(36) + * ]); + * + * numbers.then(_.spread(function(x, y) { + * return x + y; + * })); + * // => a Promise of 76 */ - function rest(array) { - return drop(array, 1); + function spread(func) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + return function(array) { + return func.apply(this, array); + }; } /** - * Creates a slice of `array` from `start` up to, but not including, `end`. + * Creates a function that only invokes `func` at most once per every `wait` + * milliseconds. The created function comes with a `cancel` method to cancel + * delayed invocations. Provide an options object to indicate that `func` + * should be invoked on the leading and/or trailing edge of the `wait` timeout. + * Subsequent calls to the throttled function return the result of the last + * `func` call. * - * **Note:** This method is used instead of `Array#slice` to support node - * lists in IE < 9 and to ensure dense arrays are returned. + * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked + * on the trailing edge of the timeout only if the the throttled function is + * invoked more than once during the `wait` timeout. + * + * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) + * for details over the differences between `_.throttle` and `_.debounce`. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function slice(array, start, end) { - var length = array ? array.length : 0; - if (!length) { - return []; + * @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 + * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { + * 'trailing': false + * })); + * + * // cancel a trailing throttled call + * 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 (end && typeof end != 'number' && isIterateeCall(array, start, end)) { - start = 0; - end = length; + if (options === false) { + leading = false; + } else if (isObject(options)) { + leading = 'leading' in options ? !!options.leading : leading; + trailing = 'trailing' in options ? !!options.trailing : trailing; } - return baseSlice(array, start, end); + debounceOptions.leading = leading; + debounceOptions.maxWait = +wait; + debounceOptions.trailing = trailing; + return debounce(func, wait, debounceOptions); } /** - * Uses a binary search to determine the lowest index at which `value` should - * be inserted into `array` in order to maintain its sort order. If an iteratee - * function is provided it is invoked for `value` and each element of `array` - * to compute their sort ranking. The iteratee is bound to `thisArg` and - * invoked with one argument; (value). + * Creates a function that provides `value` to the wrapper function as its + * first argument. Any additional arguments provided to the function are + * appended to those provided to the wrapper function. The wrapper is invoked + * with the `this` binding of the created function. * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. + * @static + * @memberOf _ + * @category Function + * @param {*} value The value to wrap. + * @param {Function} wrapper The wrapper function. + * @returns {Function} Returns the new function. + * @example * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * var p = _.wrap(_.escape, function(func, text) { + * return '

    ' + func(text) + '

    '; + * }); * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * p('fred, barney, & pebbles'); + * // => '

    fred, barney, & pebbles

    ' + */ + function wrap(value, wrapper) { + wrapper = wrapper == null ? identity : wrapper; + return createWrapper(wrapper, PARTIAL_FLAG, null, [value], []); + } + + /** + * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, + * otherwise they are assigned by reference. If `customizer` is provided it is + * invoked to produce the cloned values. If `customizer` returns `undefined` + * cloning is handled by the method instead. The `customizer` is bound to + * `thisArg` and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. * * @static * @memberOf _ - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @category Lang + * @param {*} value The value to clone. + * @param {boolean} [isDeep] Specify a deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the cloned value. * @example * - * _.sortedIndex([30, 50], 40); - * // => 1 + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; * - * _.sortedIndex([4, 4, 5, 5], 5); - * // => 2 + * var shallow = _.clone(users); + * shallow[0] === users[0]; + * // => true * - * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; + * var deep = _.clone(users, true); + * deep[0] === users[0]; + * // => false * - * // using an iteratee function - * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { - * return this.data[word]; - * }, dict); - * // => 1 + * // using a customizer callback + * var el = _.clone(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(false); + * } + * }); * - * // using the `_.property` callback shorthand - * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); - * // => 1 + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 0 */ - var sortedIndex = createSortedIndex(); + function clone(value, isDeep, customizer, thisArg) { + if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { + isDeep = false; + } + else if (typeof isDeep == 'function') { + thisArg = customizer; + customizer = isDeep; + isDeep = false; + } + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); + return baseClone(value, isDeep, customizer); + } /** - * 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. + * Creates a deep clone of `value`. If `customizer` is provided it is invoked + * to produce the cloned values. If `customizer` returns `undefined` cloning + * is handled by the method instead. The `customizer` is bound to `thisArg` + * and invoked with two argument; (value [, index|key, object]). + * + * **Note:** This method is loosely based on the + * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). + * The enumerable properties of `arguments` objects and objects created by + * constructors other than `Object` are cloned to plain `Object` objects. An + * empty object is returned for uncloneable values such as functions, DOM nodes, + * Maps, Sets, and WeakMaps. * * @static * @memberOf _ - * @category Array - * @param {Array} array The sorted array to inspect. - * @param {*} value The value to evaluate. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {number} Returns the index at which `value` should be inserted - * into `array`. + * @category Lang + * @param {*} value The value to deep clone. + * @param {Function} [customizer] The function to customize cloning values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {*} Returns the deep cloned value. * @example * - * _.sortedLastIndex([4, 4, 5, 5], 5); - * // => 4 + * var users = [ + * { 'user': 'barney' }, + * { 'user': 'fred' } + * ]; + * + * var deep = _.cloneDeep(users); + * deep[0] === users[0]; + * // => false + * + * // using a customizer callback + * var el = _.cloneDeep(document.body, function(value) { + * if (_.isElement(value)) { + * return value.cloneNode(true); + * } + * }); + * + * el === document.body + * // => false + * el.nodeName + * // => BODY + * el.childNodes.length; + * // => 20 */ - var sortedLastIndex = createSortedIndex(true); + function cloneDeep(value, customizer, thisArg) { + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); + return baseClone(value, true, customizer); + } /** - * Creates a slice of `array` with `n` elements taken from the beginning. + * Checks if `value` is classified as an `arguments` object. * * @static * @memberOf _ - * @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 a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.take([1, 2, 3]); - * // => [1] - * - * _.take([1, 2, 3], 2); - * // => [1, 2] - * - * _.take([1, 2, 3], 5); - * // => [1, 2, 3] + * _.isArguments(function() { return arguments; }()); + * // => true * - * _.take([1, 2, 3], 0); - * // => [] + * _.isArguments([1, 2, 3]); + * // => false */ - function take(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - return baseSlice(array, 0, n < 0 ? 0 : n); + function isArguments(value) { + return isObjectLike(value) && isArrayLike(value) && objToString.call(value) == argsTag; } /** - * Creates a slice of `array` with `n` elements taken from the end. + * Checks if `value` is classified as an `Array` object. * * @static * @memberOf _ - * @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 a callback for functions like `_.map`. - * @returns {Array} Returns the slice of `array`. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.takeRight([1, 2, 3]); - * // => [3] - * - * _.takeRight([1, 2, 3], 2); - * // => [2, 3] - * - * _.takeRight([1, 2, 3], 5); - * // => [1, 2, 3] + * _.isArray([1, 2, 3]); + * // => true * - * _.takeRight([1, 2, 3], 0); - * // => [] + * _.isArray(function() { return arguments; }()); + * // => false */ - function takeRight(array, n, guard) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (guard ? isIterateeCall(array, n, guard) : n == null) { - n = 1; - } - n = length - (+n || 0); - return baseSlice(array, n < 0 ? 0 : n); - } + var isArray = nativeIsArray || function(value) { + return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; + }; /** - * Creates a slice of `array` with elements taken from the end. Elements are - * taken until `predicate` returns falsey. The predicate is bound to `thisArg` - * and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * Checks if `value` is classified as a boolean primitive or object. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.takeRightWhile([1, 2, 3], function(n) { - * return n > 1; - * }); - * // => [2, 3] - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false }, - * { 'user': 'pebbles', 'active': false } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); - * // => ['pebbles'] - * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); - * // => ['fred', 'pebbles'] + * _.isBoolean(false); + * // => true * - * // using the `_.property` callback shorthand - * _.pluck(_.takeRightWhile(users, 'active'), 'user'); - * // => [] + * _.isBoolean(null); + * // => false */ - function takeRightWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) - : []; + function isBoolean(value) { + return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); } /** - * Creates a slice of `array` with elements taken from the beginning. Elements - * are taken until `predicate` returns falsey. The predicate is bound to - * `thisArg` and invoked with three arguments: (value, index, array). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * Checks if `value` is classified as a `Date` object. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array to query. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the slice of `array`. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.takeWhile([1, 2, 3], function(n) { - * return n < 3; - * }); - * // => [1, 2] - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false}, - * { 'user': 'pebbles', 'active': true } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); - * // => ['barney'] - * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.takeWhile(users, 'active', false), 'user'); - * // => ['barney', 'fred'] + * _.isDate(new Date); + * // => true * - * // using the `_.property` callback shorthand - * _.pluck(_.takeWhile(users, 'active'), 'user'); - * // => [] + * _.isDate('Mon April 23 2012'); + * // => false */ - function takeWhile(array, predicate, thisArg) { - return (array && array.length) - ? baseWhile(array, getCallback(predicate, thisArg, 3)) - : []; + function isDate(value) { + return isObjectLike(value) && objToString.call(value) == dateTag; } /** - * Creates an array of unique values, in order, of the provided arrays using - * `SameValueZero` for equality comparisons. - * - * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * comparisons are like strict equality comparisons, e.g. `===`, except that - * `NaN` matches `NaN`. + * Checks if `value` is a DOM element. * * @static * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of combined values. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. * @example * - * _.union([1, 2], [4, 2], [2, 1]); - * // => [1, 2, 4] + * _.isElement(document.body); + * // => true + * + * _.isElement(''); + * // => false */ - var union = restParam(function(arrays) { - return baseUniq(baseFlatten(arrays, false, true)); - }); + function isElement(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && + (objToString.call(value).indexOf('Element') > -1); + } + // Fallback for environments without DOM support. + if (!support.dom) { + isElement = function(value) { + return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); + }; + } /** - * Creates a duplicate-free version of an array, using `SameValueZero` for - * equality comparisons, in which only the first occurence of each element - * is kept. Providing `true` for `isSorted` performs a faster search algorithm - * for sorted arrays. If an iteratee function is provided it is invoked for - * each element in the array to generate the criterion by which uniqueness - * is computed. The `iteratee` is bound to `thisArg` and invoked with three - * arguments: (value, index, array). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * comparisons are like strict equality comparisons, e.g. `===`, except that - * `NaN` matches `NaN`. + * Checks if `value` is empty. A value is considered empty unless it is an + * `arguments` object, array, string, or jQuery-like collection with a length + * greater than `0` or an object with own enumerable properties. * * @static * @memberOf _ - * @alias unique - * @category Array - * @param {Array} array The array to inspect. - * @param {boolean} [isSorted] Specify the array is sorted. - * @param {Function|Object|string} [iteratee] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new duplicate-value-free array. + * @category Lang + * @param {Array|Object|string} value The value to inspect. + * @returns {boolean} Returns `true` if `value` is empty, else `false`. * @example * - * _.uniq([2, 1, 2]); - * // => [2, 1] + * _.isEmpty(null); + * // => true * - * // using `isSorted` - * _.uniq([1, 1, 2], true); - * // => [1, 2] + * _.isEmpty(true); + * // => true * - * // using an iteratee function - * _.uniq([1, 2.5, 1.5, 2], function(n) { - * return this.floor(n); - * }, Math); - * // => [1, 2.5] + * _.isEmpty(1); + * // => true * - * // using the `_.property` callback shorthand - * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); - * // => [{ 'x': 1 }, { 'x': 2 }] + * _.isEmpty([1, 2, 3]); + * // => false + * + * _.isEmpty({ 'a': 1 }); + * // => false */ - function uniq(array, isSorted, iteratee, thisArg) { - var length = array ? array.length : 0; - if (!length) { - return []; - } - if (isSorted != null && typeof isSorted != 'boolean') { - thisArg = iteratee; - iteratee = isIterateeCall(array, isSorted, thisArg) ? null : isSorted; - isSorted = false; + function isEmpty(value) { + if (value == null) { + return true; } - var func = getCallback(); - if (!(func === baseCallback && iteratee == null)) { - iteratee = func(iteratee, thisArg, 3); + if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || + (isObjectLike(value) && isFunction(value.splice)))) { + return !value.length; } - return (isSorted && getIndexOf() == baseIndexOf) - ? sortedUniq(array, iteratee) - : baseUniq(array, iteratee); + return !keys(value).length; } /** - * 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. + * Performs a deep comparison between two values to determine if they are + * equivalent. If `customizer` is provided it is invoked to compare values. + * If `customizer` returns `undefined` comparisons are handled by the method + * instead. The `customizer` is bound to `thisArg` and invoked with three + * arguments: (value, other [, index|key]). + * + * **Note:** This method supports comparing arrays, booleans, `Date` objects, + * numbers, `Object` objects, regexes, and strings. Objects are compared by + * their own, not inherited, enumerable properties. Functions and DOM nodes + * are **not** supported. Provide a customizer function to extend support + * for comparing other values. * * @static * @memberOf _ - * @category Array - * @param {Array} array The array of grouped elements to process. - * @returns {Array} Returns the new array of regrouped elements. - * @example + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @param {Function} [customizer] The function to customize value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example * - * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; * - * _.unzip(zipped); - * // => [['fred', 'barney'], [30, 40], [true, false]] - */ - function unzip(array) { - var index = -1, - length = (array && array.length && arrayMax(arrayMap(array, getLength))) >>> 0, - result = Array(length); - - while (++index < length) { - result[index] = arrayMap(array, baseProperty(index)); - } - return result; - } - - /** - * Creates an array excluding all provided values using `SameValueZero` for - * equality comparisons. + * object == other; + * // => false * - * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * comparisons are like strict equality comparisons, e.g. `===`, except that - * `NaN` matches `NaN`. + * _.isEqual(object, other); + * // => true * - * @static - * @memberOf _ - * @category Array - * @param {Array} array The array to filter. - * @param {...*} [values] The values to exclude. - * @returns {Array} Returns the new array of filtered values. - * @example + * // using a customizer callback + * var array = ['hello', 'goodbye']; + * var other = ['hi', 'goodbye']; * - * _.without([1, 2, 1, 3], 1, 2); - * // => [3] + * _.isEqual(array, other, function(value, other) { + * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { + * return true; + * } + * }); + * // => true */ - var without = restParam(function(array, values) { - return (isArray(array) || isArguments(array)) - ? baseDifference(array, values) - : []; - }); + function isEqual(value, other, customizer, thisArg) { + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); + if (!customizer && isStrictComparable(value) && isStrictComparable(other)) { + return value === other; + } + var result = customizer ? customizer(value, other) : undefined; + return result === undefined ? baseIsEqual(value, other, customizer) : !!result; + } /** - * Creates an array that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) - * of the provided arrays. + * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, + * `SyntaxError`, `TypeError`, or `URIError` object. * * @static * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to inspect. - * @returns {Array} Returns the new array of values. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an error object, else `false`. * @example * - * _.xor([1, 2], [4, 2]); - * // => [1, 4] + * _.isError(new Error); + * // => true + * + * _.isError(Error); + * // => false */ - function xor() { - var index = -1, - length = arguments.length; - - while (++index < length) { - var array = arguments[index]; - if (isArray(array) || isArguments(array)) { - var result = result - ? baseDifference(result, array).concat(baseDifference(array, result)) - : array; - } - } - return result ? baseUniq(result) : []; + function isError(value) { + return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; } /** - * 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. + * Checks if `value` is a finite primitive number. + * + * **Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). * * @static * @memberOf _ - * @category Array - * @param {...Array} [arrays] The arrays to process. - * @returns {Array} Returns the new array of grouped elements. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. * @example * - * _.zip(['fred', 'barney'], [30, 40], [true, false]); - * // => [['fred', 30, true], ['barney', 40, false]] - */ - var zip = restParam(unzip); - - /** - * The inverse of `_.pairs`; this method returns an object composed from arrays - * of property names and values. Provide either a single two dimensional array, - * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names - * and one of corresponding values. + * _.isFinite(10); + * // => true * - * @static - * @memberOf _ - * @alias object - * @category Array - * @param {Array} props The property names. - * @param {Array} [values=[]] The property values. - * @returns {Object} Returns the new object. - * @example + * _.isFinite('10'); + * // => false * - * _.zipObject([['fred', 30], ['barney', 40]]); - * // => { 'fred': 30, 'barney': 40 } + * _.isFinite(true); + * // => false * - * _.zipObject(['fred', 'barney'], [30, 40]); - * // => { 'fred': 30, 'barney': 40 } + * _.isFinite(Object(10)); + * // => false + * + * _.isFinite(Infinity); + * // => false */ - function zipObject(props, values) { - var index = -1, - length = props ? props.length : 0, - result = {}; - - if (length && !values && !isArray(props[0])) { - values = []; - } - while (++index < length) { - var key = props[index]; - if (values) { - result[key] = values[index]; - } else if (key) { - result[key[0]] = key[1]; - } - } - return result; - } - - /*------------------------------------------------------------------------*/ + var isFinite = nativeNumIsFinite || function(value) { + return typeof value == 'number' && nativeIsFinite(value); + }; /** - * Creates a `lodash` object that wraps `value` with explicit method - * chaining enabled. + * Checks if `value` is classified as a `Function` object. * * @static * @memberOf _ - * @category Chain - * @param {*} value The value to wrap. - * @returns {Object} Returns the new `lodash` wrapper instance. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 }, - * { 'user': 'pebbles', 'age': 1 } - * ]; + * _.isFunction(_); + * // => true * - * var youngest = _.chain(users) - * .sortBy('age') - * .map(function(chr) { - * return chr.user + ' is ' + chr.age; - * }) - * .first() - * .value(); - * // => 'pebbles is 1' + * _.isFunction(/abc/); + * // => false */ - function chain(value) { - var result = lodash(value); - result.__chain__ = true; - return result; - } + var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in older versions of Chrome and Safari which return 'function' for regexes + // and Safari 8 equivalents which return 'object' for typed array constructors. + return objToString.call(value) == funcTag; + }; /** - * This method invokes `interceptor` and returns `value`. The interceptor is - * bound to `thisArg` and invoked with one argument; (value). The purpose of - * this method is to "tap into" a method chain in order to perform operations - * on intermediate results within the chain. + * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. + * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ - * @category Chain - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @param {*} [thisArg] The `this` binding of `interceptor`. - * @returns {*} Returns `value`. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * - * _([1, 2, 3]) - * .tap(function(array) { - * array.pop(); - * }) - * .reverse() - * .value(); - * // => [2, 1] + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(1); + * // => false */ - function tap(value, interceptor, thisArg) { - interceptor.call(thisArg, value); - return value; + function isObject(value) { + // Avoid a V8 JIT bug in Chrome 19-20. + // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. + var type = typeof value; + return type == 'function' || (!!value && type == 'object'); } /** - * This method is like `_.tap` except that it returns the result of `interceptor`. + * Performs a deep comparison between `object` and `source` to determine if + * `object` contains equivalent property values. If `customizer` is provided + * it is invoked to compare values. If `customizer` returns `undefined` + * comparisons are handled by the method instead. The `customizer` is bound + * to `thisArg` and invoked with three arguments: (value, other, index|key). + * + * **Note:** This method supports comparing properties of arrays, booleans, + * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions + * and DOM nodes are **not** supported. Provide a customizer function to extend + * support for comparing other values. * * @static * @memberOf _ - * @category Chain - * @param {*} value The value to provide to `interceptor`. - * @param {Function} interceptor The function to invoke. - * @param {*} [thisArg] The `this` binding of `interceptor`. - * @returns {*} Returns the result of `interceptor`. + * @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 value comparisons. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {boolean} Returns `true` if `object` is a match, else `false`. * @example * - * _(' abc ') - * .chain() - * .trim() - * .thru(function(value) { - * return [value]; - * }) - * .value(); - * // => ['abc'] - */ - function thru(value, interceptor, thisArg) { - return interceptor.call(thisArg, value); - } - - /** - * Enables explicit method chaining on the wrapper object. + * var object = { 'user': 'fred', 'age': 40 }; * - * @name chain - * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. - * @example + * _.isMatch(object, { 'age': 40 }); + * // => true * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; + * _.isMatch(object, { 'age': 36 }); + * // => false * - * // without explicit chaining - * _(users).first(); - * // => { 'user': 'barney', 'age': 36 } + * // using a customizer callback + * var object = { 'greeting': 'hello' }; + * var source = { 'greeting': 'hi' }; * - * // with explicit chaining - * _(users).chain() - * .first() - * .pick('user') - * .value(); - * // => { 'user': 'barney' } + * _.isMatch(object, source, function(value, other) { + * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; + * }); + * // => true */ - function wrapperChain() { - return chain(this); + function isMatch(object, source, customizer, thisArg) { + var props = keys(source), + length = props.length; + + if (!length) { + return true; + } + if (object == null) { + return false; + } + customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); + object = toObject(object); + if (!customizer && length == 1) { + var key = props[0], + value = source[key]; + + if (isStrictComparable(value)) { + return value === object[key] && (value !== undefined || (key in object)); + } + } + var values = Array(length), + strictCompareFlags = Array(length); + + while (length--) { + value = values[length] = source[props[length]]; + strictCompareFlags[length] = isStrictComparable(value); + } + return baseIsMatch(object, props, values, strictCompareFlags, customizer); } /** - * Executes the chained sequence and returns the wrapped result. + * Checks if `value` is `NaN`. * - * @name commit + * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) + * which returns `true` for `undefined` and other non-numeric values. + * + * @static * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. * @example * - * var array = [1, 2]; - * var wrapper = _(array).push(3); - * - * console.log(array); - * // => [1, 2] + * _.isNaN(NaN); + * // => true * - * wrapper = wrapper.commit(); - * console.log(array); - * // => [1, 2, 3] + * _.isNaN(new Number(NaN)); + * // => true * - * wrapper.last(); - * // => 3 + * isNaN(undefined); + * // => true * - * console.log(array); - * // => [1, 2, 3] + * _.isNaN(undefined); + * // => false */ - function wrapperCommit() { - return new LodashWrapper(this.value(), this.__chain__); + 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 host objects in IE. + return isNumber(value) && value != +value; } /** - * Creates a clone of the chained sequence planting `value` as the wrapped value. + * Checks if `value` is a native function. * - * @name plant + * @static * @memberOf _ - * @category Chain - * @returns {Object} Returns the new `lodash` wrapper instance. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a native function, else `false`. * @example * - * var array = [1, 2]; - * var wrapper = _(array).map(function(value) { - * return Math.pow(value, 2); - * }); - * - * var other = [3, 4]; - * var otherWrapper = wrapper.plant(other); - * - * otherWrapper.value(); - * // => [9, 16] + * _.isNative(Array.prototype.push); + * // => true * - * wrapper.value(); - * // => [1, 4] + * _.isNative(_); + * // => false */ - function wrapperPlant(value) { - var result, - parent = this; - - while (parent instanceof baseLodash) { - var clone = wrapperClone(parent); - if (result) { - previous.__wrapped__ = clone; - } else { - result = clone; - } - var previous = clone; - parent = parent.__wrapped__; + function isNative(value) { + if (value == null) { + return false; } - previous.__wrapped__ = value; - return result; + if (objToString.call(value) == funcTag) { + return reIsNative.test(fnToString.call(value)); + } + return isObjectLike(value) && reIsHostCtor.test(value); } /** - * Reverses the wrapped array so the first element becomes the last, the - * second element becomes the second to last, and so on. - * - * **Note:** This method mutates the wrapped array. + * Checks if `value` is `null`. * - * @name reverse + * @static * @memberOf _ - * @category Chain - * @returns {Object} Returns the new reversed `lodash` wrapper instance. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `null`, else `false`. * @example * - * var array = [1, 2, 3]; - * - * _(array).reverse().value() - * // => [3, 2, 1] + * _.isNull(null); + * // => true * - * console.log(array); - * // => [3, 2, 1] + * _.isNull(void 0); + * // => false */ - function wrapperReverse() { - var value = this.__wrapped__; - if (value instanceof LazyWrapper) { - if (this.__actions__.length) { - value = new LazyWrapper(this); - } - return new LodashWrapper(value.reverse(), this.__chain__); - } - return this.thru(function(value) { - return value.reverse(); - }); + function isNull(value) { + return value === null; } /** - * Produces the result of coercing the unwrapped value to a string. + * Checks if `value` is classified as a `Number` primitive or object. * - * @name toString + * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified + * as numbers, use the `_.isFinite` method. + * + * @static * @memberOf _ - * @category Chain - * @returns {string} Returns the coerced string value. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _([1, 2, 3]).toString(); - * // => '1,2,3' - */ - function wrapperToString() { - return (this.value() + ''); - } - - /** - * Executes the chained sequence to extract the unwrapped value. + * _.isNumber(8.4); + * // => true * - * @name value - * @memberOf _ - * @alias run, toJSON, valueOf - * @category Chain - * @returns {*} Returns the resolved unwrapped value. - * @example + * _.isNumber(NaN); + * // => true * - * _([1, 2, 3]).value(); - * // => [1, 2, 3] + * _.isNumber('8.4'); + * // => false */ - function wrapperValue() { - return baseWrapperValue(this.__wrapped__, this.__actions__); + function isNumber(value) { + return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); } - /*------------------------------------------------------------------------*/ - /** - * Creates an array of elements corresponding to the given keys, or indexes, - * of `collection`. Keys may be specified as individual arguments or as arrays - * of keys. + * Checks if `value` is a plain object, that is, an object created by the + * `Object` constructor or one with a `[[Prototype]]` of `null`. + * + * **Note:** This method assumes objects created by the `Object` constructor + * have no inherited enumerable properties. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(number|number[]|string|string[])} [props] The property names - * or indexes of elements to pick, specified individually or in arrays. - * @returns {Array} Returns the new array of picked elements. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. * @example * - * _.at(['a', 'b', 'c'], [0, 2]); - * // => ['a', 'c'] + * function Foo() { + * this.a = 1; + * } * - * _.at(['barney', 'fred', 'pebbles'], 0, 2); - * // => ['barney', 'pebbles'] - */ - var at = restParam(function(collection, props) { - var length = collection ? getLength(collection) : 0; - if (isLength(length)) { - collection = toIterable(collection); + * _.isPlainObject(new Foo); + * // => false + * + * _.isPlainObject([1, 2, 3]); + * // => false + * + * _.isPlainObject({ 'x': 0, 'y': 0 }); + * // => true + * + * _.isPlainObject(Object.create(null)); + * // => true + */ + var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { + if (!(value && objToString.call(value) == objectTag)) { + return false; } - return baseAt(collection, baseFlatten(props)); - }); + var valueOf = value.valueOf, + objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); + + return objProto + ? (value == objProto || getPrototypeOf(value) == objProto) + : shimIsPlainObject(value); + }; /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is the number of times the key was returned by `iteratee`. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). + * Checks if `value` is classified as a `RegExp` object. * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * _.isRegExp(/abc/); + * // => true * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * _.isRegExp('/abc/'); + * // => false + */ + function isRegExp(value) { + return isObjectLike(value) && objToString.call(value) == regexpTag; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. * @example * - * _.countBy([4.3, 6.1, 6.4], function(n) { - * return Math.floor(n); - * }); - * // => { '4': 1, '6': 2 } - * - * _.countBy([4.3, 6.1, 6.4], function(n) { - * return this.floor(n); - * }, Math); - * // => { '4': 1, '6': 2 } + * _.isString('abc'); + * // => true * - * _.countBy(['one', 'two', 'three'], 'length'); - * // => { '3': 2, '5': 1 } + * _.isString(1); + * // => false */ - var countBy = createAggregator(function(result, value, key) { - hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); - }); + function isString(value) { + return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); + } /** - * Checks if `predicate` returns truthy for **all** elements of `collection`. - * The predicate is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). + * Checks if `value` is classified as a typed array. * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. + * @example * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * _.isTypedArray(new Uint8Array); + * // => true * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * _.isTypedArray([]); + * // => false + */ + function isTypedArray(value) { + return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; + } + + /** + * Checks if `value` is `undefined`. * * @static * @memberOf _ - * @alias all - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {boolean} Returns `true` if all elements pass the predicate check, - * else `false`. + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. * @example * - * _.every([true, 1, null, 'yes'], Boolean); - * // => false - * - * var users = [ - * { 'user': 'barney', 'active': false }, - * { 'user': 'fred', 'active': false } - * ]; + * _.isUndefined(void 0); + * // => true * - * // using the `_.matches` callback shorthand - * _.every(users, { 'user': 'barney', 'active': false }); + * _.isUndefined(null); * // => false + */ + function isUndefined(value) { + return value === undefined; + } + + /** + * Converts `value` to an array. * - * // using the `_.matchesProperty` callback shorthand - * _.every(users, 'active', false); - * // => true + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to convert. + * @returns {Array} Returns the converted array. + * @example * - * // using the `_.property` callback shorthand - * _.every(users, 'active'); - * // => false + * (function() { + * return _.toArray(arguments).slice(1); + * }(1, 2, 3)); + * // => [2, 3] */ - function every(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayEvery : baseEvery; - if (thisArg && isIterateeCall(collection, predicate, thisArg)) { - predicate = null; + function toArray(value) { + var length = value ? getLength(value) : 0; + if (!isLength(length)) { + return values(value); } - if (typeof predicate != 'function' || thisArg !== undefined) { - predicate = getCallback(predicate, thisArg, 3); + if (!length) { + return []; } - return func(collection, predicate); + return arrayCopy(value); } /** - * Iterates over elements of `collection`, returning an array of all elements - * `predicate` returns truthy for. The predicate is bound to `thisArg` and - * invoked with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * Converts `value` to a plain object flattening inherited enumerable + * properties of `value` to own properties of the plain object. * * @static * @memberOf _ - * @alias select - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new filtered array. + * @category Lang + * @param {*} value The value to convert. + * @returns {Object} Returns the converted plain object. * @example * - * _.filter([4, 5, 6], function(n) { - * return n % 2 == 0; - * }); - * // => [4, 6] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; + * function Foo() { + * this.b = 2; + * } * - * // using the `_.matches` callback shorthand - * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); - * // => ['barney'] + * Foo.prototype.c = 3; * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.filter(users, 'active', false), 'user'); - * // => ['fred'] + * _.assign({ 'a': 1 }, new Foo); + * // => { 'a': 1, 'b': 2 } * - * // using the `_.property` callback shorthand - * _.pluck(_.filter(users, 'active'), 'user'); - * // => ['barney'] + * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); + * // => { 'a': 1, 'b': 2, 'c': 3 } */ - function filter(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayFilter : baseFilter; - predicate = getCallback(predicate, thisArg, 3); - return func(collection, predicate); + function toPlainObject(value) { + return baseCopy(value, keysIn(value)); } /** - * Iterates over elements of `collection`, returning the first element - * `predicate` returns truthy for. The predicate is bound to `thisArg` and - * invoked with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * Assigns own enumerable properties of source object(s) to the destination + * object. Subsequent sources overwrite property assignments of previous sources. + * If `customizer` is provided it is invoked to produce the assigned values. + * The `customizer` is bound to `thisArg` and invoked with five arguments: + * (objectValue, sourceValue, key, object, source). * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * **Note:** This method mutates `object` and is based on + * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). * * @static * @memberOf _ - * @alias detect - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {*} Returns the matched element, else `undefined`. + * @alias extend + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. * @example * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false }, - * { 'user': 'pebbles', 'age': 1, 'active': true } - * ]; - * - * _.result(_.find(users, function(chr) { - * return chr.age < 40; - * }), 'user'); - * // => 'barney' - * - * // using the `_.matches` callback shorthand - * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); - * // => 'pebbles' + * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); + * // => { 'user': 'fred', 'age': 40 } * - * // using the `_.matchesProperty` callback shorthand - * _.result(_.find(users, 'active', false), 'user'); - * // => 'fred' + * // using a customizer callback + * var defaults = _.partialRight(_.assign, function(value, other) { + * return _.isUndefined(value) ? other : value; + * }); * - * // using the `_.property` callback shorthand - * _.result(_.find(users, 'active'), 'user'); - * // => 'barney' + * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } */ - var find = createFind(baseEach); + var assign = createAssigner(function(object, source, customizer) { + return customizer + ? assignWith(object, source, customizer) + : baseAssign(object, source); + }); /** - * This method is like `_.find` except that it iterates over elements of - * `collection` from right to left. + * Creates an object that inherits from the given `prototype` object. If a + * `properties` object is provided its own enumerable properties are assigned + * to the created object. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {*} Returns the matched element, else `undefined`. + * @category Object + * @param {Object} prototype The object to inherit from. + * @param {Object} [properties] The properties to assign to the object. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new object. * @example * - * _.findLast([1, 2, 3, 4], function(n) { - * return n % 2 == 1; + * function Shape() { + * this.x = 0; + * this.y = 0; + * } + * + * function Circle() { + * Shape.call(this); + * } + * + * Circle.prototype = _.create(Shape.prototype, { + * 'constructor': Circle * }); - * // => 3 + * + * var circle = new Circle; + * circle instanceof Circle; + * // => true + * + * circle instanceof Shape; + * // => true */ - var findLast = createFind(baseEachRight, true); + function create(prototype, properties, guard) { + var result = baseCreate(prototype); + if (guard && isIterateeCall(prototype, properties, guard)) { + properties = null; + } + return properties ? baseAssign(result, properties) : result; + } /** - * Performs a deep comparison between each element in `collection` and the - * source object, returning the first element that has equivalent property - * values. + * Assigns own enumerable properties of source object(s) to the destination + * object for all destination properties that resolve to `undefined`. Once a + * property is set, additional values of the same property are ignored. * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. For comparing a single - * own or inherited property value see `_.matchesProperty`. + * **Note:** This method mutates `object`. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Object} source The object of property values to match. - * @returns {*} Returns the matched element, else `undefined`. + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. * @example * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': true }, - * { 'user': 'fred', 'age': 40, 'active': false } - * ]; - * - * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); - * // => 'barney' - * - * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); - * // => 'fred' + * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); + * // => { 'user': 'barney', 'age': 36 } */ - function findWhere(collection, source) { - return find(collection, baseMatches(source)); - } + var defaults = restParam(function(args) { + var object = args[0]; + if (object == null) { + return object; + } + args.push(assignDefaults); + return assign.apply(undefined, args); + }); /** - * Iterates over elements of `collection` invoking `iteratee` for each element. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). Iteratee functions may exit iteration early - * by explicitly returning `false`. + * This method is like `_.find` except that it returns the key of the first + * element `predicate` returns truthy for instead of the element itself. * - * **Note:** As with other "Collections" methods, objects with a "length" property - * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` - * may be used for object iteration. + * If a property name is provided for `predicate` the created `_.property` + * style callback returns the property value of the given element. + * + * If a value is also provided for `thisArg` the created `_.matchesProperty` + * style callback returns `true` for elements that have a matching property + * value, else `false`. + * + * If an object is provided for `predicate` the created `_.matches` style + * callback returns `true` for elements that have the properties of the given + * object, else `false`. * * @static * @memberOf _ - * @alias each - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array|Object|string} Returns `collection`. + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked + * per iteration. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * _([1, 2]).forEach(function(n) { - * console.log(n); - * }).value(); - * // => logs each value from left to right and returns the array + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; * - * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { - * console.log(n, key); + * _.findKey(users, function(chr) { + * return chr.age < 40; * }); - * // => logs each value-key pair and returns the object (iteration order is not guaranteed) - */ - var forEach = createForEach(arrayEach, baseEach); - - /** - * This method is like `_.forEach` except that it iterates over elements of - * `collection` from right to left. + * // => 'barney' (iteration order is not guaranteed) * - * @static - * @memberOf _ - * @alias eachRight - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array|Object|string} Returns `collection`. - * @example + * // using the `_.matches` callback shorthand + * _.findKey(users, { 'age': 1, 'active': true }); + * // => 'pebbles' * - * _([1, 2]).forEachRight(function(n) { - * console.log(n); - * }).value(); - * // => logs each value from right to left and returns the array + * // using the `_.matchesProperty` callback shorthand + * _.findKey(users, 'active', false); + * // => 'fred' + * + * // using the `_.property` callback shorthand + * _.findKey(users, 'active'); + * // => 'barney' */ - var forEachRight = createForEach(arrayEachRight, baseEachRight); + var findKey = createFindKey(baseForOwn); /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is an array of the elements responsible for generating the key. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). + * This method is like `_.findKey` except that it iterates over elements of + * a collection in the opposite order. * - * If a property name is provided for `iteratee` the created `_.property` + * If a property name is provided for `predicate` the created `_.property` * style callback returns the property value of the given element. * * If a value is also provided for `thisArg` the created `_.matchesProperty` * style callback returns `true` for elements that have a matching property * value, else `false`. * - * If an object is provided for `iteratee` the created `_.matches` style + * If an object is provided for `predicate` the created `_.matches` style * callback returns `true` for elements that have the properties of the given * object, else `false`. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked + * @category Object + * @param {Object} object The object to search. + * @param {Function|Object|string} [predicate=_.identity] The function invoked * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {string|undefined} Returns the key of the matched element, else `undefined`. * @example * - * _.groupBy([4.2, 6.1, 6.4], function(n) { - * return Math.floor(n); + * var users = { + * 'barney': { 'age': 36, 'active': true }, + * 'fred': { 'age': 40, 'active': false }, + * 'pebbles': { 'age': 1, 'active': true } + * }; + * + * _.findLastKey(users, function(chr) { + * return chr.age < 40; * }); - * // => { '4': [4.2], '6': [6.1, 6.4] } + * // => returns `pebbles` assuming `_.findKey` returns `barney` * - * _.groupBy([4.2, 6.1, 6.4], function(n) { - * return this.floor(n); - * }, Math); - * // => { '4': [4.2], '6': [6.1, 6.4] } + * // using the `_.matches` callback shorthand + * _.findLastKey(users, { 'age': 36, 'active': true }); + * // => 'barney' + * + * // using the `_.matchesProperty` callback shorthand + * _.findLastKey(users, 'active', false); + * // => 'fred' * * // using the `_.property` callback shorthand - * _.groupBy(['one', 'two', 'three'], 'length'); - * // => { '3': ['one', 'two'], '5': ['three'] } + * _.findLastKey(users, 'active'); + * // => 'pebbles' */ - var groupBy = createAggregator(function(result, value, key) { - if (hasOwnProperty.call(result, key)) { - result[key].push(value); - } else { - result[key] = [value]; - } - }); + var findLastKey = createFindKey(baseForOwnRight); /** - * Checks if `value` is in `collection` using `SameValueZero` for equality - * comparisons. If `fromIndex` is negative, it is used as the offset from - * the end of `collection`. - * - * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero) - * comparisons are like strict equality comparisons, e.g. `===`, except that - * `NaN` matches `NaN`. + * Iterates over own and inherited enumerable properties of an object invoking + * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked + * with three arguments: (value, key, object). Iteratee functions may exit + * iteration early by explicitly returning `false`. * * @static * @memberOf _ - * @alias contains, include - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {*} target The value to search for. - * @param {number} [fromIndex=0] The index to search from. - * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. - * @returns {boolean} Returns `true` if a matching element is found, else `false`. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. * @example * - * _.includes([1, 2, 3], 1); - * // => true - * - * _.includes([1, 2, 3], 1, 2); - * // => false + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); - * // => true + * Foo.prototype.c = 3; * - * _.includes('pebbles', 'eb'); - * // => true + * _.forIn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) */ - function includes(collection, target, fromIndex, guard) { - var length = collection ? getLength(collection) : 0; - if (!isLength(length)) { - collection = values(collection); - length = collection.length; - } - if (!length) { - return false; - } - if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { - fromIndex = 0; - } else { - fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); - } - return (typeof collection == 'string' || !isArray(collection) && isString(collection)) - ? (fromIndex < length && collection.indexOf(target, fromIndex) > -1) - : (getIndexOf(collection, target, fromIndex) > -1); - } + var forIn = createForIn(baseFor); /** - * Creates an object composed of keys generated from the results of running - * each element of `collection` through `iteratee`. The corresponding value - * of each key is the last element responsible for generating the key. The - * iteratee function is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * This method is like `_.forIn` except that it iterates over properties of + * `object` in the opposite order. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the composed aggregate object. + * @returns {Object} Returns `object`. * @example * - * var keyData = [ - * { 'dir': 'left', 'code': 97 }, - * { 'dir': 'right', 'code': 100 } - * ]; + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.indexBy(keyData, 'dir'); - * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } + * Foo.prototype.c = 3; * - * _.indexBy(keyData, function(object) { - * return String.fromCharCode(object.code); + * _.forInRight(new Foo, function(value, key) { + * console.log(key); * }); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } - * - * _.indexBy(keyData, function(object) { - * return this.fromCharCode(object.code); - * }, String); - * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } + * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' */ - var indexBy = createAggregator(function(result, value, key) { - result[key] = value; - }); + var forInRight = createForIn(baseForRight); /** - * Invokes the method at `path` on each element in `collection`, returning - * an array of the results of each invoked method. Any additional arguments - * are provided to each invoked method. If `methodName` is a function it is - * invoked for, and `this` bound to, each element in `collection`. + * Iterates over own enumerable properties of an object invoking `iteratee` + * for each property. The `iteratee` is bound to `thisArg` and invoked with + * three arguments: (value, key, object). Iteratee functions may exit iteration + * early by explicitly returning `false`. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} 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 the method with. - * @returns {Array} Returns the array of results. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns `object`. * @example * - * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); - * // => [[1, 5, 7], [1, 2, 3]] + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.invoke([123, 456], String.prototype.split, ''); - * // => [['1', '2', '3'], ['4', '5', '6']] + * Foo.prototype.c = 3; + * + * _.forOwn(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'a' and 'b' (iteration order is not guaranteed) */ - var invoke = restParam(function(collection, path, args) { - var index = -1, - isFunc = typeof path == 'function', - isProp = isKey(path), - length = getLength(collection), - result = isLength(length) ? Array(length) : []; - - baseEach(collection, function(value) { - var func = isFunc ? path : (isProp && value != null && value[path]); - result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); - }); - return result; - }); + var forOwn = createForOwn(baseForOwn); /** - * Creates an array of values by running each element in `collection` through - * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three - * arguments: (value, index|key, collection). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * Many lodash methods are guarded to work as interatees for methods like - * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. - * - * The guarded methods are: - * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, `drop`, - * `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, `parseInt`, - * `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, `trimLeft`, - * `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, `uniq`, and `words` + * This method is like `_.forOwn` except that it iterates over properties of + * `object` in the opposite order. * * @static * @memberOf _ - * @alias collect - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function} [iteratee=_.identity] The function invoked per iteration. * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new mapped array. + * @returns {Object} Returns `object`. * @example * - * function timesThree(n) { - * return n * 3; + * function Foo() { + * this.a = 1; + * this.b = 2; * } * - * _.map([1, 2], timesThree); - * // => [3, 6] + * Foo.prototype.c = 3; * - * _.map({ 'a': 1, 'b': 2 }, timesThree); - * // => [3, 6] (iteration order is not guaranteed) + * _.forOwnRight(new Foo, function(value, key) { + * console.log(key); + * }); + * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' + */ + var forOwnRight = createForOwn(baseForOwnRight); + + /** + * Creates an array of function property names from all enumerable properties, + * own and inherited, of `object`. * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; + * @static + * @memberOf _ + * @alias methods + * @category Object + * @param {Object} object The object to inspect. + * @returns {Array} Returns the new array of property names. + * @example * - * // using the `_.property` callback shorthand - * _.map(users, 'user'); - * // => ['barney', 'fred'] + * _.functions(_); + * // => ['after', 'ary', 'assign', ...] */ - function map(collection, iteratee, thisArg) { - var func = isArray(collection) ? arrayMap : baseMap; - iteratee = getCallback(iteratee, thisArg, 3); - return func(collection, iteratee); + function functions(object) { + return baseFunctions(object, keysIn(object)); } /** - * Creates an array of elements split into two groups, the first of which - * contains elements `predicate` returns truthy for, while the second of which - * contains elements `predicate` returns falsey for. The predicate is bound - * to `thisArg` and invoked with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * Gets the property value of `path` on `object`. If the resolved value is + * `undefined` the `defaultValue` is used in its place. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the array of grouped elements. + * @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 if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. * @example * - * _.partition([1, 2, 3], function(n) { - * return n % 2; - * }); - * // => [[1, 3], [2]] - * - * _.partition([1.2, 2.3, 3.4], function(n) { - * return this.floor(n) % 2; - * }, Math); - * // => [[1.2, 3.4], [2.3]] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true }, - * { 'user': 'pebbles', 'age': 1, 'active': false } - * ]; - * - * var mapper = function(array) { - * return _.pluck(array, 'user'); - * }; + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * - * // using the `_.matches` callback shorthand - * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); - * // => [['pebbles'], ['barney', 'fred']] + * _.get(object, 'a[0].b.c'); + * // => 3 * - * // using the `_.matchesProperty` callback shorthand - * _.map(_.partition(users, 'active', false), mapper); - * // => [['barney', 'pebbles'], ['fred']] + * _.get(object, ['a', '0', 'b', 'c']); + * // => 3 * - * // using the `_.property` callback shorthand - * _.map(_.partition(users, 'active'), mapper); - * // => [['fred'], ['barney', 'pebbles']] + * _.get(object, 'a.b.c', 'default'); + * // => 'default' */ - var partition = createAggregator(function(result, value, key) { - result[key ? 0 : 1].push(value); - }, function() { return [[], []]; }); + function get(object, path, defaultValue) { + var result = object == null ? undefined : baseGet(object, toPath(path), path + ''); + return result === undefined ? defaultValue : result; + } /** - * Gets the property value of `path` from all elements in `collection`. + * Checks if `path` is a direct property. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Array|string} path The path of the property to pluck. - * @returns {Array} Returns the property values. + * @category Object + * @param {Object} object The object to query. + * @param {Array|string} path The path to check. + * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. * @example * - * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } - * ]; + * var object = { 'a': { 'b': { 'c': 3 } } }; * - * _.pluck(users, 'user'); - * // => ['barney', 'fred'] + * _.has(object, 'a'); + * // => true * - * var userIndex = _.indexBy(users, 'user'); - * _.pluck(userIndex, 'age'); - * // => [36, 40] (iteration order is not guaranteed) + * _.has(object, 'a.b.c'); + * // => true + * + * _.has(object, ['a', 'b', 'c']); + * // => true */ - function pluck(collection, path) { - return map(collection, property(path)); + function has(object, path) { + if (object == null) { + return false; + } + var result = hasOwnProperty.call(object, path); + if (!result && !isKey(path)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + path = last(path); + result = object != null && hasOwnProperty.call(object, path); + } + return result; } /** - * Reduces `collection` to a value which is the accumulated result of running - * each element in `collection` through `iteratee`, where each successive - * invocation is supplied the return value of the previous. If `accumulator` - * is not provided the first element of `collection` is used as the initial - * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: - * (accumulator, value, index|key, collection). - * - * Many lodash methods are guarded to work as interatees for methods like - * `_.reduce`, `_.reduceRight`, and `_.transform`. - * - * The guarded methods are: - * `assign`, `defaults`, `includes`, `merge`, `sortByAll`, and `sortByOrder` + * 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 unless `multiValue` is `true`. * * @static * @memberOf _ - * @alias foldl, inject - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the accumulated value. + * @category Object + * @param {Object} object The object to invert. + * @param {boolean} [multiValue] Allow multiple values per key. + * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. + * @returns {Object} Returns the new inverted object. * @example * - * _.reduce([1, 2], function(total, n) { - * return total + n; - * }); - * // => 3 + * var object = { 'a': 1, 'b': 2, 'c': 1 }; * - * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { - * result[key] = n * 3; - * return result; - * }, {}); - * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) + * _.invert(object); + * // => { '1': 'c', '2': 'b' } + * + * // with `multiValue` + * _.invert(object, true); + * // => { '1': ['a', 'c'], '2': ['b'] } */ - var reduce = createReduce(arrayReduce, baseEach); + function invert(object, multiValue, guard) { + if (guard && isIterateeCall(object, multiValue, guard)) { + multiValue = null; + } + var index = -1, + props = keys(object), + length = props.length, + result = {}; + + while (++index < length) { + var key = props[index], + value = object[key]; + + if (multiValue) { + if (hasOwnProperty.call(result, value)) { + result[value].push(key); + } else { + result[value] = [key]; + } + } + else { + result[value] = key; + } + } + return result; + } /** - * This method is like `_.reduce` except that it iterates over elements of - * `collection` from right to left. + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) + * for more details. * * @static * @memberOf _ - * @alias foldr - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The initial value. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {*} Returns the accumulated value. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. * @example * - * var array = [[0, 1], [2, 3], [4, 5]]; + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * _.reduceRight(array, function(flattened, other) { - * return flattened.concat(other); - * }, []); - * // => [4, 5, 2, 3, 0, 1] + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] */ - var reduceRight = createReduce(arrayReduceRight, baseEachRight); + var keys = !nativeKeys ? shimKeys : function(object) { + var Ctor = object != null && object.constructor; + if ((typeof Ctor == 'function' && Ctor.prototype === object) || + (typeof object != 'function' && isArrayLike(object))) { + return shimKeys(object); + } + return isObject(object) ? nativeKeys(object) : []; + }; /** - * The opposite of `_.filter`; this method returns the elements of `collection` - * that `predicate` does **not** return truthy for. - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. + * Creates an array of the own and inherited enumerable property names of `object`. * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * **Note:** Non-object values are coerced to objects. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Array} Returns the new filtered array. + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. * @example * - * _.reject([1, 2, 3, 4], function(n) { - * return n % 2 == 0; - * }); - * // => [1, 3] - * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false }, - * { 'user': 'fred', 'age': 40, 'active': true } - * ]; - * - * // using the `_.matches` callback shorthand - * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); - * // => ['barney'] + * function Foo() { + * this.a = 1; + * this.b = 2; + * } * - * // using the `_.matchesProperty` callback shorthand - * _.pluck(_.reject(users, 'active', false), 'user'); - * // => ['fred'] + * Foo.prototype.c = 3; * - * // using the `_.property` callback shorthand - * _.pluck(_.reject(users, 'active'), 'user'); - * // => ['barney'] + * _.keysIn(new Foo); + * // => ['a', 'b', 'c'] (iteration order is not guaranteed) */ - function reject(collection, predicate, thisArg) { - var func = isArray(collection) ? arrayFilter : baseFilter; - predicate = getCallback(predicate, thisArg, 3); - return func(collection, function(value, index, collection) { - return !predicate(value, index, collection); - }); - } - - /** - * Gets a random element or `n` random elements from a collection. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to sample. - * @param {number} [n] The number of elements to sample. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {*} Returns the random sample(s). - * @example - * - * _.sample([1, 2, 3, 4]); - * // => 2 - * - * _.sample([1, 2, 3, 4], 2); - * // => [3, 1] - */ - function sample(collection, n, guard) { - if (guard ? isIterateeCall(collection, n, guard) : n == null) { - collection = toIterable(collection); - var length = collection.length; - return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; + function keysIn(object) { + if (object == null) { + return []; } - var result = shuffle(collection); - result.length = nativeMin(n < 0 ? 0 : (+n || 0), result.length); - return result; - } - - /** - * Creates an array of shuffled values, using a version of the - * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} 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) { - collection = toIterable(collection); + if (!isObject(object)) { + object = Object(object); + } + var length = object.length; + length = (length && isLength(length) && + (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; - var index = -1, - length = collection.length, - result = Array(length); + var Ctor = object.constructor, + index = -1, + isProto = typeof Ctor == 'function' && Ctor.prototype === object, + result = Array(length), + skipIndexes = length > 0; while (++index < length) { - var rand = baseRandom(0, index); - if (index != rand) { - result[index] = result[rand]; + result[index] = (index + ''); + } + for (var key in object) { + if (!(skipIndexes && isIndex(key, length)) && + !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { + result.push(key); } - result[rand] = collection[index]; } return result; } /** - * Gets the size of `collection` by returning its length for array-like - * values or the number of own enumerable properties for objects. - * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to inspect. - * @returns {number} Returns the size of `collection`. - * @example - * - * _.size([1, 2, 3]); - * // => 3 - * - * _.size({ 'a': 1, 'b': 2 }); - * // => 2 - * - * _.size('pebbles'); - * // => 7 - */ - function size(collection) { - var length = collection ? getLength(collection) : 0; - return isLength(length) ? length : keys(collection).length; - } - - /** - * Checks if `predicate` returns truthy for **any** element of `collection`. - * The function returns as soon as it finds a passing value and does not iterate - * over the entire collection. The predicate is bound to `thisArg` and invoked - * with three arguments: (value, index|key, collection). - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * The opposite of `_.mapValues`; this method creates an object with the + * same values as `object` and keys generated by running each own enumerable + * property of `object` through `iteratee`. * * @static * @memberOf _ - * @alias any - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function|Object|string} [predicate=_.identity] The function invoked + * @category Object + * @param {Object} object The object to iterate over. + * @param {Function|Object|string} [iteratee=_.identity] The function invoked * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {boolean} Returns `true` if any element passes the predicate check, - * else `false`. + * @param {*} [thisArg] The `this` binding of `iteratee`. + * @returns {Object} Returns the new mapped object. * @example * - * _.some([null, 0, 'yes', false], Boolean); - * // => true - * - * var users = [ - * { 'user': 'barney', 'active': true }, - * { 'user': 'fred', 'active': false } - * ]; - * - * // using the `_.matches` callback shorthand - * _.some(users, { 'user': 'barney', 'active': false }); - * // => false - * - * // using the `_.matchesProperty` callback shorthand - * _.some(users, 'active', false); - * // => true - * - * // using the `_.property` callback shorthand - * _.some(users, 'active'); - * // => true + * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { + * return key + value; + * }); + * // => { 'a1': 1, 'b2': 2 } */ - function some(collection, predicate, thisArg) { - var func = isArray(collection) ? arraySome : baseSome; - if (thisArg && isIterateeCall(collection, predicate, thisArg)) { - predicate = null; - } - if (typeof predicate != 'function' || thisArg !== undefined) { - predicate = getCallback(predicate, thisArg, 3); - } - return func(collection, predicate); - } + var mapKeys = createObjectMapper(true); /** - * Creates an array of elements, sorted in ascending order by the results of - * running each element in a collection through `iteratee`. This method performs - * a stable sort, that is, it preserves the original sort order of equal elements. - * The `iteratee` is bound to `thisArg` and invoked with three arguments: - * (value, index|key, collection). + * Creates an object with the same keys as `object` and values generated by + * running each own enumerable property of `object` through `iteratee`. The + * iteratee function is bound to `thisArg` and invoked with three arguments: + * (value, key, object). * * If a property name is provided for `iteratee` the created `_.property` * style callback returns the property value of the given element. @@ -12996,23527 +12797,5482 @@ var Grommet = * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. + * @category Object + * @param {Object} object The object to iterate over. * @param {Function|Object|string} [iteratee=_.identity] The function invoked * per iteration. * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Array} Returns the new sorted array. + * @returns {Object} Returns the new mapped object. * @example * - * _.sortBy([1, 2, 3], function(n) { - * return Math.sin(n); + * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { + * return n * 3; * }); - * // => [3, 1, 2] - * - * _.sortBy([1, 2, 3], function(n) { - * return this.sin(n); - * }, Math); - * // => [3, 1, 2] + * // => { 'a': 3, 'b': 6 } * - * var users = [ - * { 'user': 'fred' }, - * { 'user': 'pebbles' }, - * { 'user': 'barney' } - * ]; + * var users = { + * 'fred': { 'user': 'fred', 'age': 40 }, + * 'pebbles': { 'user': 'pebbles', 'age': 1 } + * }; * * // using the `_.property` callback shorthand - * _.pluck(_.sortBy(users, 'user'), 'user'); - * // => ['barney', 'fred', 'pebbles'] + * _.mapValues(users, 'age'); + * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) */ - function sortBy(collection, iteratee, thisArg) { - if (collection == null) { - return []; - } - if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { - iteratee = null; - } - var index = -1; - iteratee = getCallback(iteratee, thisArg, 3); - - var result = baseMap(collection, function(value, key, collection) { - return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; - }); - return baseSortBy(result, compareAscending); - } + var mapValues = createObjectMapper(); /** - * This method is like `_.sortBy` except that it can sort by multiple iteratees - * or property names. - * - * If a property name is provided for an iteratee the created `_.property` - * style callback returns the property value of the given element. - * - * If an object is provided for an iteratee the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * Recursively merges own enumerable properties of the source object(s), that + * don't resolve to `undefined` into the destination object. Subsequent sources + * overwrite property assignments of previous sources. If `customizer` is + * provided it 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 bound to `thisArg` and invoked + * with five arguments: (objectValue, sourceValue, key, object, source). * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees - * The iteratees to sort by, specified as individual values or arrays of values. - * @returns {Array} Returns the new sorted array. + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @param {Function} [customizer] The function to customize assigned values. + * @param {*} [thisArg] The `this` binding of `customizer`. + * @returns {Object} Returns `object`. * @example * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 42 }, - * { 'user': 'barney', 'age': 34 } - * ]; + * var users = { + * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] + * }; * - * _.map(_.sortByAll(users, ['user', 'age']), _.values); - * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] + * var ages = { + * 'data': [{ 'age': 36 }, { 'age': 40 }] + * }; * - * _.map(_.sortByAll(users, 'user', function(chr) { - * return Math.floor(chr.age / 10); - * }), _.values); - * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] - */ - var sortByAll = restParam(function(collection, iteratees) { - if (collection == null) { - return []; - } - var guard = iteratees[2]; - if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { - iteratees.length = 1; - } - return baseSortByOrder(collection, baseFlatten(iteratees), []); - }); - - /** - * This method is like `_.sortByAll` except that it allows specifying the - * sort orders of the iteratees to sort by. A truthy value in `orders` will - * sort the corresponding property name in ascending order while a falsey - * value will sort it in descending order. - * - * If a property name is provided for an iteratee the created `_.property` - * style callback returns the property value of the given element. - * - * If an object is provided for an iteratee the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. + * _.merge(users, ages); + * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } * - * @static - * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to iterate over. - * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. - * @param {boolean[]} orders The sort orders of `iteratees`. - * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. - * @returns {Array} Returns the new sorted array. - * @example + * // using a customizer callback + * var object = { + * 'fruits': ['apple'], + * 'vegetables': ['beet'] + * }; * - * var users = [ - * { 'user': 'fred', 'age': 48 }, - * { 'user': 'barney', 'age': 34 }, - * { 'user': 'fred', 'age': 42 }, - * { 'user': 'barney', 'age': 36 } - * ]; + * var other = { + * 'fruits': ['banana'], + * 'vegetables': ['carrot'] + * }; * - * // sort by `user` in ascending order and by `age` in descending order - * _.map(_.sortByOrder(users, ['user', 'age'], [true, false]), _.values); - * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] + * _.merge(object, other, function(a, b) { + * if (_.isArray(a)) { + * return a.concat(b); + * } + * }); + * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } */ - function sortByOrder(collection, iteratees, orders, guard) { - if (collection == null) { - return []; - } - if (guard && isIterateeCall(iteratees, orders, guard)) { - orders = null; - } - if (!isArray(iteratees)) { - iteratees = iteratees == null ? [] : [iteratees]; - } - if (!isArray(orders)) { - orders = orders == null ? [] : [orders]; - } - return baseSortByOrder(collection, iteratees, orders); - } + var merge = createAssigner(baseMerge); /** - * Performs a deep comparison between each element in `collection` and the - * source object, returning an array of all elements that have equivalent - * property values. - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. For comparing a single - * own or inherited property value see `_.matchesProperty`. + * The opposite of `_.pick`; this method creates an object composed of the + * own and inherited enumerable properties of `object` that are not omitted. * * @static * @memberOf _ - * @category Collection - * @param {Array|Object|string} collection The collection to search. - * @param {Object} source The object of property values to match. - * @returns {Array} Returns the new filtered array. + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to omit, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. * @example * - * var users = [ - * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, - * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } - * ]; + * var object = { 'user': 'fred', 'age': 40 }; * - * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); - * // => ['barney'] + * _.omit(object, 'age'); + * // => { 'user': 'fred' } * - * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); - * // => ['fred'] + * _.omit(object, _.isNumber); + * // => { 'user': 'fred' } */ - function where(collection, source) { - return filter(collection, baseMatches(source)); - } - - /*------------------------------------------------------------------------*/ + var omit = restParam(function(object, props) { + if (object == null) { + return {}; + } + if (typeof props[0] != 'function') { + var props = arrayMap(baseFlatten(props), String); + return pickByArray(object, baseDifference(keysIn(object), props)); + } + var predicate = bindCallback(props[0], props[1], 3); + return pickByCallback(object, function(value, key, object) { + return !predicate(value, key, object); + }); + }); /** - * Gets the number of milliseconds that have elapsed since the Unix epoch - * (1 January 1970 00:00:00 UTC). + * Creates a two dimensional array of the key-value pairs for `object`, + * e.g. `[[key1, value1], [key2, value2]]`. * * @static * @memberOf _ - * @category Date + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the new array of key-value pairs. * @example * - * _.defer(function(stamp) { - * console.log(_.now() - stamp); - * }, _.now()); - * // => logs the number of milliseconds it took for the deferred function to be invoked + * _.pairs({ 'barney': 36, 'fred': 40 }); + * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) */ - var now = nativeNow || function() { - return new Date().getTime(); - }; + function pairs(object) { + var index = -1, + props = keys(object), + length = props.length, + result = Array(length); - /*------------------------------------------------------------------------*/ + while (++index < length) { + var key = props[index]; + result[index] = [key, object[key]]; + } + return result; + } /** - * The opposite of `_.before`; this method creates a function that invokes - * `func` once it is called `n` or more times. + * Creates an object composed of the picked `object` properties. Property + * names may be specified as individual arguments or as arrays of property + * names. If `predicate` is provided it is invoked for each property of `object` + * picking the properties `predicate` returns truthy for. The predicate is + * bound to `thisArg` and invoked with three arguments: (value, key, object). * * @static * @memberOf _ - * @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. + * @category Object + * @param {Object} object The source object. + * @param {Function|...(string|string[])} [predicate] The function invoked per + * iteration or property names to pick, specified as individual property + * names or arrays of property names. + * @param {*} [thisArg] The `this` binding of `predicate`. + * @returns {Object} Returns the new object. * @example * - * var saves = ['profile', 'settings']; + * var object = { 'user': 'fred', 'age': 40 }; * - * var done = _.after(saves.length, function() { - * console.log('done saving!'); - * }); + * _.pick(object, 'user'); + * // => { 'user': 'fred' } * - * _.forEach(saves, function(type) { - * asyncSave({ 'type': type, 'complete': done }); - * }); - * // => logs 'done saving!' after the two async saves have completed + * _.pick(object, _.isString); + * // => { 'user': 'fred' } */ - function after(n, func) { - if (typeof func != 'function') { - if (typeof n == 'function') { - var temp = n; - n = func; - func = temp; - } else { - throw new TypeError(FUNC_ERROR_TEXT); - } + var pick = restParam(function(object, props) { + if (object == null) { + return {}; } - n = nativeIsFinite(n = +n) ? n : 0; - return function() { - if (--n < 1) { - return func.apply(this, arguments); - } - }; - } + return typeof props[0] == 'function' + ? pickByCallback(object, bindCallback(props[0], props[1], 3)) + : pickByArray(object, baseFlatten(props)); + }); /** - * Creates a function that accepts up to `n` arguments ignoring any - * additional arguments. + * This method is like `_.get` except that if the resolved value is a function + * it is invoked with the `this` binding of its parent object and its result + * is returned. * * @static * @memberOf _ - * @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 a callback for functions like `_.map`. - * @returns {Function} Returns the new function. + * @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 if the resolved value is `undefined`. + * @returns {*} Returns the resolved value. * @example * - * _.map(['6', '8', '10'], _.ary(parseInt, 1)); - * // => [6, 8, 10] + * 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.b.c', 'default'); + * // => 'default' + * + * _.result(object, 'a.b.c', _.constant('default')); + * // => 'default' */ - function ary(func, n, guard) { - if (guard && isIterateeCall(func, n, guard)) { - n = null; + function result(object, path, defaultValue) { + var result = object == null ? undefined : object[path]; + if (result === undefined) { + if (object != null && !isKey(path, object)) { + path = toPath(path); + object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); + result = object == null ? undefined : object[last(path)]; + } + result = result === undefined ? defaultValue : result; } - n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); - return createWrapper(func, ARY_FLAG, null, null, null, null, n); + return isFunction(result) ? result.call(object) : result; } /** - * Creates a function that invokes `func`, with the `this` binding and arguments - * of the created function, while it is called less than `n` times. Subsequent - * calls to the created function return the result of the last `func` invocation. + * Sets the property value of `path` on `object`. If a portion of `path` + * does not exist it is created. * * @static * @memberOf _ - * @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('#add').on('click', _.before(5, addContactToList)); - * // => allows adding up to 4 contacts to the list - */ - function before(n, func) { - var result; - if (typeof func != 'function') { - if (typeof n == 'function') { - var temp = n; - n = func; - func = temp; - } else { - throw new TypeError(FUNC_ERROR_TEXT); - } - } - return function() { - if (--n > 0) { - result = func.apply(this, arguments); - } - if (n <= 1) { - func = null; - } - return result; - }; - } - - /** - * Creates a function that invokes `func` with the `this` binding of `thisArg` - * and prepends any additional `_.bind` arguments to those provided to the - * bound function. - * - * 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 does not set the "length" - * property of bound functions. - * - * @static - * @memberOf _ - * @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 - * - * var greet = function(greeting, punctuation) { - * return greeting + ' ' + this.user + punctuation; - * }; - * - * var object = { 'user': 'fred' }; - * - * var bound = _.bind(greet, object, 'hi'); - * bound('!'); - * // => 'hi fred!' - * - * // using placeholders - * var bound = _.bind(greet, object, _, '!'); - * bound('hi'); - * // => 'hi fred!' - */ - var bind = restParam(function(func, thisArg, partials) { - var bitmask = BIND_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, bind.placeholder); - bitmask |= PARTIAL_FLAG; - } - return createWrapper(func, bitmask, thisArg, partials, holders); - }); - - /** - * Binds methods of an object to the object itself, overwriting the existing - * method. Method names may be specified as individual arguments or as arrays - * of method names. If no method names are provided all enumerable function - * properties, own and inherited, of `object` are bound. - * - * **Note:** This method does not set the "length" property of bound functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Object} object The object to bind and assign the bound methods to. - * @param {...(string|string[])} [methodNames] The object method names to bind, - * specified as individual method names or arrays of method names. + * @category Object + * @param {Object} object The object to augment. + * @param {Array|string} path The path of the property to set. + * @param {*} value The value to set. * @returns {Object} Returns `object`. * @example * - * var view = { - * 'label': 'docs', - * 'onClick': function() { - * console.log('clicked ' + this.label); - * } - * }; - * - * _.bindAll(view); - * jQuery('#docs').on('click', view.onClick); - * // => logs 'clicked docs' when the element is clicked - */ - var bindAll = restParam(function(object, methodNames) { - methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); - - var index = -1, - length = methodNames.length; - - while (++index < length) { - var key = methodNames[index]; - object[key] = createWrapper(object[key], BIND_FLAG, object); - } - return object; - }); - - /** - * Creates a function that invokes the method at `object[key]` and prepends - * any additional `_.bindKey` arguments to those provided to the bound function. - * - * 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 _ - * @category Function - * @param {Object} object The object the method belongs to. - * @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!' - * - * // using placeholders - * var bound = _.bindKey(object, 'greet', _, '!'); - * bound('hi'); - * // => 'hiya fred!' - */ - var bindKey = restParam(function(object, key, partials) { - var bitmask = BIND_FLAG | BIND_KEY_FLAG; - if (partials.length) { - var holders = replaceHolders(partials, bindKey.placeholder); - bitmask |= PARTIAL_FLAG; - } - return createWrapper(key, bitmask, object, partials, holders); - }); - - /** - * Creates a function that accepts one or more arguments of `func` that when - * called either invokes `func` returning its result, if all `func` arguments - * have been provided, or returns a function that accepts one or more of 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 does not set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as a callback for functions 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] - * - * // using placeholders - * curried(1)(_, 3)(2); - * // => [1, 2, 3] - */ - var curry = createCurry(CURRY_FLAG); - - /** - * 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 does not set the "length" property of curried functions. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to curry. - * @param {number} [arity=func.length] The arity of `func`. - * @param- {Object} [guard] Enables use as a callback for functions 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] + * var object = { 'a': [{ 'b': { 'c': 3 } }] }; * - * curried(1, 2, 3); - * // => [1, 2, 3] + * _.set(object, 'a[0].b.c', 4); + * console.log(object.a[0].b.c); + * // => 4 * - * // using placeholders - * curried(3)(1, _)(2); - * // => [1, 2, 3] + * _.set(object, 'x[0].y.z', 5); + * console.log(object.x[0].y.z); + * // => 5 */ - var curryRight = createCurry(CURRY_RIGHT_FLAG); - - /** - * Creates a function that delays invoking `func` until after `wait` milliseconds - * have elapsed since the last time it was invoked. The created function comes - * with a `cancel` method to cancel delayed invocations. Provide an options - * object to indicate that `func` should be invoked on the leading and/or - * trailing edge of the `wait` timeout. 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 the debounced function is - * invoked more than once during the `wait` timeout. - * - * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) - * for details over the differences between `_.debounce` and `_.throttle`. - * - * @static - * @memberOf _ - * @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 is 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 the click event is fired, debouncing subsequent calls - * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { - * 'leading': true, - * 'trailing': false - * })); - * - * // ensure `batchLog` is invoked once after 1 second of debounced calls - * var source = new EventSource('/stream'); - * jQuery(source).on('message', _.debounce(batchLog, 250, { - * 'maxWait': 1000 - * })); - * - * // cancel a debounced call - * var todoChanges = _.debounce(batchLog, 1000); - * Object.observe(models.todo, todoChanges); - * - * Object.observe(models, function(changes) { - * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { - * todoChanges.cancel(); - * } - * }, ['delete']); - * - * // ...at some point `models.todo` is changed - * models.todo.completed = true; - * - * // ...before 1 second has passed `models.todo` is deleted - * // which cancels the debounced `todoChanges` call - * delete models.todo; - */ - function debounce(func, wait, options) { - var args, - maxTimeoutId, - result, - stamp, - thisArg, - timeoutId, - trailingCall, - lastCalled = 0, - maxWait = false, - trailing = true; - - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - wait = wait < 0 ? 0 : (+wait || 0); - if (options === true) { - var leading = true; - trailing = false; - } else if (isObject(options)) { - leading = options.leading; - maxWait = 'maxWait' in options && nativeMax(+options.maxWait || 0, wait); - trailing = 'trailing' in options ? options.trailing : trailing; - } - - function cancel() { - if (timeoutId) { - clearTimeout(timeoutId); - } - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - } - - function delayed() { - var remaining = wait - (now() - stamp); - if (remaining <= 0 || remaining > wait) { - if (maxTimeoutId) { - clearTimeout(maxTimeoutId); - } - var isCalled = trailingCall; - maxTimeoutId = timeoutId = trailingCall = undefined; - if (isCalled) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } else { - timeoutId = setTimeout(delayed, remaining); - } - } - - function maxDelayed() { - if (timeoutId) { - clearTimeout(timeoutId); - } - maxTimeoutId = timeoutId = trailingCall = undefined; - if (trailing || (maxWait !== wait)) { - lastCalled = now(); - result = func.apply(thisArg, args); - if (!timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - } - } - - function debounced() { - args = arguments; - stamp = now(); - thisArg = this; - trailingCall = trailing && (timeoutId || !leading); - - if (maxWait === false) { - var leadingCall = leading && !timeoutId; - } else { - if (!maxTimeoutId && !leading) { - lastCalled = stamp; - } - var remaining = maxWait - (stamp - lastCalled), - isCalled = remaining <= 0 || remaining > maxWait; - - if (isCalled) { - if (maxTimeoutId) { - maxTimeoutId = clearTimeout(maxTimeoutId); - } - lastCalled = stamp; - result = func.apply(thisArg, args); - } - else if (!maxTimeoutId) { - maxTimeoutId = setTimeout(maxDelayed, remaining); - } - } - if (isCalled && timeoutId) { - timeoutId = clearTimeout(timeoutId); - } - else if (!timeoutId && wait !== maxWait) { - timeoutId = setTimeout(delayed, wait); - } - if (leadingCall) { - isCalled = true; - result = func.apply(thisArg, args); - } - if (isCalled && !timeoutId && !maxTimeoutId) { - args = thisArg = null; - } - return result; - } - debounced.cancel = cancel; - return debounced; - } - - /** - * Defers invoking the `func` until the current call stack has cleared. Any - * additional arguments are provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to defer. - * @param {...*} [args] The arguments to invoke the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.defer(function(text) { - * console.log(text); - * }, 'deferred'); - * // logs 'deferred' after one or more milliseconds - */ - var defer = restParam(function(func, args) { - return baseDelay(func, 1, args); - }); - - /** - * Invokes `func` after `wait` milliseconds. Any additional arguments are - * provided to `func` when it is invoked. - * - * @static - * @memberOf _ - * @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 the function with. - * @returns {number} Returns the timer id. - * @example - * - * _.delay(function(text) { - * console.log(text); - * }, 1000, 'later'); - * // => logs 'later' after one second - */ - var delay = restParam(function(func, wait, args) { - return baseDelay(func, wait, args); - }); - - /** - * Creates a function that returns the result of invoking the provided - * functions with the `this` binding of the created function, where each - * successive invocation is supplied the return value of the previous. - * - * @static - * @memberOf _ - * @category Function - * @param {...Function} [funcs] Functions to invoke. - * @returns {Function} Returns the new function. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var addSquare = _.flow(_.add, square); - * addSquare(1, 2); - * // => 9 - */ - var flow = createFlow(); - - /** - * This method is like `_.flow` except that it creates a function that - * invokes the provided functions from right to left. - * - * @static - * @memberOf _ - * @alias backflow, compose - * @category Function - * @param {...Function} [funcs] Functions to invoke. - * @returns {Function} Returns the new function. - * @example - * - * function square(n) { - * return n * n; - * } - * - * var addSquare = _.flowRight(square, _.add); - * addSquare(1, 2); - * // => 9 - */ - var flowRight = createFlow(true); - - /** - * 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 coerced to a string and used as the - * 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`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-properties-of-the-map-prototype-object) - * method interface of `get`, `has`, and `set`. - * - * @static - * @memberOf _ - * @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 memoizing function. - * @example - * - * var upperCase = _.memoize(function(string) { - * return string.toUpperCase(); - * }); - * - * upperCase('fred'); - * // => 'FRED' - * - * // modifying the result cache - * upperCase.cache.set('fred', 'BARNEY'); - * upperCase('fred'); - * // => 'BARNEY' - * - * // replacing `_.memoize.Cache` - * var object = { 'user': 'fred' }; - * var other = { 'user': 'barney' }; - * var identity = _.memoize(_.identity); - * - * identity(object); - * // => { 'user': 'fred' } - * identity(other); - * // => { 'user': 'fred' } - * - * _.memoize.Cache = WeakMap; - * var identity = _.memoize(_.identity); - * - * identity(object); - * // => { 'user': 'fred' } - * identity(other); - * // => { 'user': 'barney' } - */ - function memoize(func, resolver) { - if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { - throw new TypeError(FUNC_ERROR_TEXT); - } - var memoized = function() { - var args = arguments, - cache = memoized.cache, - key = resolver ? resolver.apply(this, args) : args[0]; - - if (cache.has(key)) { - return cache.get(key); - } - var result = func.apply(this, args); - cache.set(key, result); - return result; - }; - memoized.cache = new memoize.Cache; - return memoized; - } - - /** - * 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 _ - * @category Function - * @param {Function} predicate The predicate to negate. - * @returns {Function} Returns the new 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() { - return !predicate.apply(this, arguments); - }; - } - - /** - * Creates a function that is restricted to invoking `func` once. Repeat calls - * to the function return the value of the first call. The `func` is invoked - * with the `this` binding and arguments of the created function. - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to restrict. - * @returns {Function} Returns the new restricted function. - * @example - * - * var initialize = _.once(createApplication); - * initialize(); - * initialize(); - * // `initialize` invokes `createApplication` once - */ - function once(func) { - return before(2, func); - } - - /** - * Creates a function that invokes `func` with `partial` arguments prepended - * to those provided to the new function. 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 does not set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @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 - * - * var greet = function(greeting, name) { - * return greeting + ' ' + name; - * }; - * - * var sayHelloTo = _.partial(greet, 'hello'); - * sayHelloTo('fred'); - * // => 'hello fred' - * - * // using placeholders - * var greetFred = _.partial(greet, _, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - */ - var partial = createPartial(PARTIAL_FLAG); - - /** - * This method is like `_.partial` except that partially applied arguments - * are appended to those provided to the new function. - * - * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic - * builds, may be used as a placeholder for partially applied arguments. - * - * **Note:** This method does not set the "length" property of partially - * applied functions. - * - * @static - * @memberOf _ - * @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 - * - * var greet = function(greeting, name) { - * return greeting + ' ' + name; - * }; - * - * var greetFred = _.partialRight(greet, 'fred'); - * greetFred('hi'); - * // => 'hi fred' - * - * // using placeholders - * var sayHelloTo = _.partialRight(greet, 'hello', _); - * sayHelloTo('fred'); - * // => 'hello fred' - */ - var partialRight = createPartial(PARTIAL_RIGHT_FLAG); - - /** - * 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 _ - * @category Function - * @param {Function} func The function to rearrange arguments for. - * @param {...(number|number[])} indexes The arranged argument indexes, - * specified as individual indexes or arrays of 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 map = _.rearg(_.map, [1, 0]); - * map(function(n) { - * return n * 3; - * }, [1, 2, 3]); - * // => [3, 6, 9] - */ - var rearg = restParam(function(func, indexes) { - return createWrapper(func, REARG_FLAG, null, null, null, baseFlatten(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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters). - * - * @static - * @memberOf _ - * @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 = _.restParam(function(what, names) { - * return what + ' ' + _.initial(names).join(', ') + - * (_.size(names) > 1 ? ', & ' : '') + _.last(names); - * }); - * - * say('hello', 'fred', 'barney', 'pebbles'); - * // => 'hello fred, barney, & pebbles' - */ - function restParam(func, start) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); - return function() { - var args = arguments, - index = -1, - length = nativeMax(args.length - start, 0), - rest = Array(length); - - while (++index < length) { - rest[index] = args[start + index]; - } - switch (start) { - case 0: return func.call(this, rest); - case 1: return func.call(this, args[0], rest); - case 2: return func.call(this, args[0], args[1], rest); - } - var otherArgs = Array(start + 1); - index = -1; - while (++index < start) { - otherArgs[index] = args[index]; - } - otherArgs[start] = rest; - return func.apply(this, otherArgs); - }; - } - - /** - * Creates a function that invokes `func` with the `this` binding of the created - * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). - * - * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator). - * - * @static - * @memberOf _ - * @category Function - * @param {Function} func The function to spread arguments over. - * @returns {Function} Returns the new function. - * @example - * - * var say = _.spread(function(who, what) { - * return who + ' says ' + what; - * }); - * - * say(['fred', 'hello']); - * // => 'fred says hello' - * - * // with a Promise - * 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) { - if (typeof func != 'function') { - throw new TypeError(FUNC_ERROR_TEXT); - } - return function(array) { - return func.apply(this, array); - }; - } - - /** - * Creates a function that only invokes `func` at most once per every `wait` - * milliseconds. The created function comes with a `cancel` method to cancel - * delayed invocations. Provide an options object to indicate that `func` - * should be invoked on the leading and/or trailing edge of the `wait` timeout. - * Subsequent calls to the throttled function return the result of the last - * `func` call. - * - * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked - * on the trailing edge of the timeout only if the the throttled function is - * invoked more than once during the `wait` timeout. - * - * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) - * for details over the differences between `_.throttle` and `_.debounce`. - * - * @static - * @memberOf _ - * @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 - * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { - * 'trailing': false - * })); - * - * // cancel a trailing throttled call - * 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 (options === false) { - leading = false; - } else if (isObject(options)) { - leading = 'leading' in options ? !!options.leading : leading; - trailing = 'trailing' in options ? !!options.trailing : trailing; - } - debounceOptions.leading = leading; - debounceOptions.maxWait = +wait; - debounceOptions.trailing = trailing; - return debounce(func, wait, debounceOptions); - } - - /** - * Creates a function that provides `value` to the wrapper function as its - * first argument. Any additional arguments provided to the function are - * appended to those provided to the wrapper function. The wrapper is invoked - * with the `this` binding of the created function. - * - * @static - * @memberOf _ - * @category Function - * @param {*} value The value to wrap. - * @param {Function} wrapper 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) { - wrapper = wrapper == null ? identity : wrapper; - return createWrapper(wrapper, PARTIAL_FLAG, null, [value], []); - } - - /*------------------------------------------------------------------------*/ - - /** - * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, - * otherwise they are assigned by reference. If `customizer` is provided it is - * invoked to produce the cloned values. If `customizer` returns `undefined` - * cloning is handled by the method instead. The `customizer` is bound to - * `thisArg` and invoked with two argument; (value [, index|key, object]). - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). - * The enumerable properties of `arguments` objects and objects created by - * constructors other than `Object` are cloned to plain `Object` objects. An - * empty object is returned for uncloneable values such as functions, DOM nodes, - * Maps, Sets, and WeakMaps. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to clone. - * @param {boolean} [isDeep] Specify a deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {*} Returns the cloned value. - * @example - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * var shallow = _.clone(users); - * shallow[0] === users[0]; - * // => true - * - * var deep = _.clone(users, true); - * deep[0] === users[0]; - * // => false - * - * // using a customizer callback - * var el = _.clone(document.body, function(value) { - * if (_.isElement(value)) { - * return value.cloneNode(false); - * } - * }); - * - * el === document.body - * // => false - * el.nodeName - * // => BODY - * el.childNodes.length; - * // => 0 - */ - function clone(value, isDeep, customizer, thisArg) { - if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { - isDeep = false; - } - else if (typeof isDeep == 'function') { - thisArg = customizer; - customizer = isDeep; - isDeep = false; - } - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); - return baseClone(value, isDeep, customizer); - } - - /** - * Creates a deep clone of `value`. If `customizer` is provided it is invoked - * to produce the cloned values. If `customizer` returns `undefined` cloning - * is handled by the method instead. The `customizer` is bound to `thisArg` - * and invoked with two argument; (value [, index|key, object]). - * - * **Note:** This method is loosely based on the - * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). - * The enumerable properties of `arguments` objects and objects created by - * constructors other than `Object` are cloned to plain `Object` objects. An - * empty object is returned for uncloneable values such as functions, DOM nodes, - * Maps, Sets, and WeakMaps. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to deep clone. - * @param {Function} [customizer] The function to customize cloning values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {*} Returns the deep cloned value. - * @example - * - * var users = [ - * { 'user': 'barney' }, - * { 'user': 'fred' } - * ]; - * - * var deep = _.cloneDeep(users); - * deep[0] === users[0]; - * // => false - * - * // using a customizer callback - * var el = _.cloneDeep(document.body, function(value) { - * if (_.isElement(value)) { - * return value.cloneNode(true); - * } - * }); - * - * el === document.body - * // => false - * el.nodeName - * // => BODY - * el.childNodes.length; - * // => 20 - */ - function cloneDeep(value, customizer, thisArg) { - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 1); - return baseClone(value, true, customizer); - } - - /** - * Checks if `value` is classified as an `arguments` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - function isArguments(value) { - var length = isObjectLike(value) ? value.length : undefined; - return isLength(length) && objToString.call(value) == argsTag; - } - - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(function() { return arguments; }()); - * // => false - */ - var isArray = nativeIsArray || function(value) { - return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; - }; - - /** - * Checks if `value` is classified as a boolean primitive or object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isBoolean(false); - * // => true - * - * _.isBoolean(null); - * // => false - */ - function isBoolean(value) { - return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); - } - - /** - * Checks if `value` is classified as a `Date` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isDate(new Date); - * // => true - * - * _.isDate('Mon April 23 2012'); - * // => false - */ - function isDate(value) { - return isObjectLike(value) && objToString.call(value) == dateTag; - } - - /** - * Checks if `value` is a DOM element. - * - * @static - * @memberOf _ - * @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 !!value && value.nodeType === 1 && isObjectLike(value) && - (objToString.call(value).indexOf('Element') > -1); - } - // Fallback for environments without DOM support. - if (!support.dom) { - isElement = function(value) { - return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); - }; - } - - /** - * Checks if `value` is empty. A value is considered empty unless it is an - * `arguments` object, array, string, or jQuery-like collection with a length - * greater than `0` or an object with own enumerable properties. - * - * @static - * @memberOf _ - * @category Lang - * @param {Array|Object|string} value The value to inspect. - * @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; - } - var length = getLength(value); - if (isLength(length) && (isArray(value) || isString(value) || isArguments(value) || - (isObjectLike(value) && isFunction(value.splice)))) { - return !length; - } - return !keys(value).length; - } - - /** - * Performs a deep comparison between two values to determine if they are - * equivalent. If `customizer` is provided it is invoked to compare values. - * If `customizer` returns `undefined` comparisons are handled by the method - * instead. The `customizer` is bound to `thisArg` and invoked with three - * arguments: (value, other [, index|key]). - * - * **Note:** This method supports comparing arrays, booleans, `Date` objects, - * numbers, `Object` objects, regexes, and strings. Objects are compared by - * their own, not inherited, enumerable properties. Functions and DOM nodes - * are **not** supported. Provide a customizer function to extend support - * for comparing other values. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to compare. - * @param {*} other The other value to compare. - * @param {Function} [customizer] The function to customize value comparisons. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {boolean} Returns `true` if the values are equivalent, else `false`. - * @example - * - * var object = { 'user': 'fred' }; - * var other = { 'user': 'fred' }; - * - * object == other; - * // => false - * - * _.isEqual(object, other); - * // => true - * - * // using a customizer callback - * var array = ['hello', 'goodbye']; - * var other = ['hi', 'goodbye']; - * - * _.isEqual(array, other, function(value, other) { - * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { - * return true; - * } - * }); - * // => true - */ - function isEqual(value, other, customizer, thisArg) { - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); - if (!customizer && isStrictComparable(value) && isStrictComparable(other)) { - return value === other; - } - var result = customizer ? customizer(value, other) : undefined; - return result === undefined ? baseIsEqual(value, other, customizer) : !!result; - } - - /** - * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, - * `SyntaxError`, `TypeError`, or `URIError` object. - * - * @static - * @memberOf _ - * @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) { - return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; - } - - /** - * Checks if `value` is a finite primitive number. - * - * **Note:** This method is based on [`Number.isFinite`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.isfinite). - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. - * @example - * - * _.isFinite(10); - * // => true - * - * _.isFinite('10'); - * // => false - * - * _.isFinite(true); - * // => false - * - * _.isFinite(Object(10)); - * // => false - * - * _.isFinite(Infinity); - * // => false - */ - var isFinite = nativeNumIsFinite || function(value) { - return typeof value == 'number' && nativeIsFinite(value); - }; - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - var isFunction = !(baseIsFunction(/x/) || (Uint8Array && !baseIsFunction(Uint8Array))) ? baseIsFunction : function(value) { - // The use of `Object#toString` avoids issues with the `typeof` operator - // in older versions of Chrome and Safari which return 'function' for regexes - // and Safari 8 equivalents which return 'object' for typed array constructors. - return objToString.call(value) == funcTag; - }; - - /** - * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. - * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @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(1); - * // => false - */ - function isObject(value) { - // Avoid a V8 JIT bug in Chrome 19-20. - // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. - var type = typeof value; - return type == 'function' || (!!value && type == 'object'); - } - - /** - * Performs a deep comparison between `object` and `source` to determine if - * `object` contains equivalent property values. If `customizer` is provided - * it is invoked to compare values. If `customizer` returns `undefined` - * comparisons are handled by the method instead. The `customizer` is bound - * to `thisArg` and invoked with three arguments: (value, other, index|key). - * - * **Note:** This method supports comparing properties of arrays, booleans, - * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions - * and DOM nodes are **not** supported. Provide a customizer function to extend - * support for comparing other values. - * - * @static - * @memberOf _ - * @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 value comparisons. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {boolean} Returns `true` if `object` is a match, else `false`. - * @example - * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.isMatch(object, { 'age': 40 }); - * // => true - * - * _.isMatch(object, { 'age': 36 }); - * // => false - * - * // using a customizer callback - * var object = { 'greeting': 'hello' }; - * var source = { 'greeting': 'hi' }; - * - * _.isMatch(object, source, function(value, other) { - * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; - * }); - * // => true - */ - function isMatch(object, source, customizer, thisArg) { - var props = keys(source), - length = props.length; - - if (!length) { - return true; - } - if (object == null) { - return false; - } - customizer = typeof customizer == 'function' && bindCallback(customizer, thisArg, 3); - object = toObject(object); - if (!customizer && length == 1) { - var key = props[0], - value = source[key]; - - if (isStrictComparable(value)) { - return value === object[key] && (value !== undefined || (key in object)); - } - } - var values = Array(length), - strictCompareFlags = Array(length); - - while (length--) { - value = values[length] = source[props[length]]; - strictCompareFlags[length] = isStrictComparable(value); - } - return baseIsMatch(object, props, values, strictCompareFlags, customizer); - } - - /** - * Checks if `value` is `NaN`. - * - * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) - * which returns `true` for `undefined` and other non-numeric values. - * - * @static - * @memberOf _ - * @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 host objects in IE. - return isNumber(value) && value != +value; - } - - /** - * Checks if `value` is a native function. - * - * @static - * @memberOf _ - * @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 (value == null) { - return false; - } - if (objToString.call(value) == funcTag) { - return reIsNative.test(fnToString.call(value)); - } - return isObjectLike(value) && reIsHostCtor.test(value); - } - - /** - * Checks if `value` is `null`. - * - * @static - * @memberOf _ - * @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 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 _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isNumber(8.4); - * // => true - * - * _.isNumber(NaN); - * // => true - * - * _.isNumber('8.4'); - * // => false - */ - function isNumber(value) { - return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); - } - - /** - * Checks if `value` is a plain object, that is, an object created by the - * `Object` constructor or one with a `[[Prototype]]` of `null`. - * - * **Note:** This method assumes objects created by the `Object` constructor - * have no inherited enumerable properties. - * - * @static - * @memberOf _ - * @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 - */ - var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { - if (!(value && objToString.call(value) == objectTag)) { - return false; - } - var valueOf = value.valueOf, - objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); - - return objProto - ? (value == objProto || getPrototypeOf(value) == objProto) - : shimIsPlainObject(value); - }; - - /** - * Checks if `value` is classified as a `RegExp` object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isRegExp(/abc/); - * // => true - * - * _.isRegExp('/abc/'); - * // => false - */ - function isRegExp(value) { - return (isObjectLike(value) && objToString.call(value) == regexpTag) || false; - } - - /** - * Checks if `value` is classified as a `String` primitive or object. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isString('abc'); - * // => true - * - * _.isString(1); - * // => false - */ - function isString(value) { - return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); - } - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - function isTypedArray(value) { - return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; - } - - /** - * Checks if `value` is `undefined`. - * - * @static - * @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; - } - - /** - * Converts `value` to an array. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * (function() { - * return _.toArray(arguments).slice(1); - * }(1, 2, 3)); - * // => [2, 3] - */ - function toArray(value) { - var length = value ? getLength(value) : 0; - if (!isLength(length)) { - return values(value); - } - if (!length) { - return []; - } - return arrayCopy(value); - } - - /** - * Converts `value` to a plain object flattening inherited enumerable - * properties of `value` to own properties of the plain object. - * - * @static - * @memberOf _ - * @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 baseCopy(value, keysIn(value)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object. Subsequent sources overwrite property assignments of previous sources. - * If `customizer` is provided it is invoked to produce the assigned values. - * The `customizer` is bound to `thisArg` and invoked with five arguments: - * (objectValue, sourceValue, key, object, source). - * - * **Note:** This method mutates `object` and is based on - * [`Object.assign`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign). - * - * - * @static - * @memberOf _ - * @alias extend - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {Object} Returns `object`. - * @example - * - * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); - * // => { 'user': 'fred', 'age': 40 } - * - * // using a customizer callback - * var defaults = _.partialRight(_.assign, function(value, other) { - * return _.isUndefined(value) ? other : value; - * }); - * - * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); - * // => { 'user': 'barney', 'age': 36 } - */ - var assign = createAssigner(function(object, source, customizer) { - return customizer - ? assignWith(object, source, customizer) - : baseAssign(object, source); - }); - - /** - * Creates an object that inherits from the given `prototype` object. If a - * `properties` object is provided its own enumerable properties are assigned - * to the created object. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} prototype The object to inherit from. - * @param {Object} [properties] The properties to assign to the object. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @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, guard) { - var result = baseCreate(prototype); - if (guard && isIterateeCall(prototype, properties, guard)) { - properties = null; - } - return properties ? baseAssign(result, properties) : result; - } - - /** - * Assigns own enumerable properties of source object(s) to the destination - * object for all destination properties that resolve to `undefined`. Once a - * property is set, additional values of the same property are ignored. - * - * **Note:** This method mutates `object`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @returns {Object} Returns `object`. - * @example - * - * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); - * // => { 'user': 'barney', 'age': 36 } - */ - var defaults = restParam(function(args) { - var object = args[0]; - if (object == null) { - return object; - } - args.push(assignDefaults); - return assign.apply(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. - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @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(chr) { - * return chr.age < 40; - * }); - * // => 'barney' (iteration order is not guaranteed) - * - * // using the `_.matches` callback shorthand - * _.findKey(users, { 'age': 1, 'active': true }); - * // => 'pebbles' - * - * // using the `_.matchesProperty` callback shorthand - * _.findKey(users, 'active', false); - * // => 'fred' - * - * // using the `_.property` callback shorthand - * _.findKey(users, 'active'); - * // => 'barney' - */ - var findKey = createFindKey(baseForOwn); - - /** - * This method is like `_.findKey` except that it iterates over elements of - * a collection in the opposite order. - * - * If a property name is provided for `predicate` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `predicate` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to search. - * @param {Function|Object|string} [predicate=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @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(chr) { - * return chr.age < 40; - * }); - * // => returns `pebbles` assuming `_.findKey` returns `barney` - * - * // using the `_.matches` callback shorthand - * _.findLastKey(users, { 'age': 36, 'active': true }); - * // => 'barney' - * - * // using the `_.matchesProperty` callback shorthand - * _.findLastKey(users, 'active', false); - * // => 'fred' - * - * // using the `_.property` callback shorthand - * _.findLastKey(users, 'active'); - * // => 'pebbles' - */ - var findLastKey = createFindKey(baseForOwnRight); - - /** - * Iterates over own and inherited enumerable properties of an object invoking - * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked - * with three arguments: (value, key, object). Iteratee functions may exit - * iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @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', and 'c' (iteration order is not guaranteed) - */ - var forIn = createForIn(baseFor); - - /** - * This method is like `_.forIn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @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', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' - */ - var forInRight = createForIn(baseForRight); - - /** - * Iterates over own enumerable properties of an object invoking `iteratee` - * for each property. The `iteratee` is bound to `thisArg` and invoked with - * three arguments: (value, key, object). Iteratee functions may exit iteration - * early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwn(new Foo, function(value, key) { - * console.log(key); - * }); - * // => logs 'a' and 'b' (iteration order is not guaranteed) - */ - var forOwn = createForOwn(baseForOwn); - - /** - * This method is like `_.forOwn` except that it iterates over properties of - * `object` in the opposite order. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns `object`. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.forOwnRight(new Foo, function(value, key) { - * console.log(key); - * }); - * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' - */ - var forOwnRight = createForOwn(baseForOwnRight); - - /** - * Creates an array of function property names from all enumerable properties, - * own and inherited, of `object`. - * - * @static - * @memberOf _ - * @alias methods - * @category Object - * @param {Object} object The object to inspect. - * @returns {Array} Returns the new array of property names. - * @example - * - * _.functions(_); - * // => ['after', 'ary', 'assign', ...] - */ - function functions(object) { - return baseFunctions(object, keysIn(object)); - } - - /** - * Gets the property value of `path` on `object`. If the resolved value is - * `undefined` the `defaultValue` is used in its place. - * - * @static - * @memberOf _ - * @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 if the resolved value is `undefined`. - * @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, toPath(path), path + ''); - return result === undefined ? defaultValue : result; - } - - /** - * Checks if `path` is a direct property. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @param {Array|string} path The path to check. - * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. - * @example - * - * var object = { 'a': { 'b': { 'c': 3 } } }; - * - * _.has(object, 'a'); - * // => true - * - * _.has(object, 'a.b.c'); - * // => true - * - * _.has(object, ['a', 'b', 'c']); - * // => true - */ - function has(object, path) { - if (object == null) { - return false; - } - var result = hasOwnProperty.call(object, path); - if (!result && !isKey(path)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - path = last(path); - result = object != null && hasOwnProperty.call(object, path); - } - return result; - } - - /** - * 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 unless `multiValue` is `true`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to invert. - * @param {boolean} [multiValue] Allow multiple values per key. - * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. - * @returns {Object} Returns the new inverted object. - * @example - * - * var object = { 'a': 1, 'b': 2, 'c': 1 }; - * - * _.invert(object); - * // => { '1': 'c', '2': 'b' } - * - * // with `multiValue` - * _.invert(object, true); - * // => { '1': ['a', 'c'], '2': ['b'] } - */ - function invert(object, multiValue, guard) { - if (guard && isIterateeCall(object, multiValue, guard)) { - multiValue = null; - } - var index = -1, - props = keys(object), - length = props.length, - result = {}; - - while (++index < length) { - var key = props[index], - value = object[key]; - - if (multiValue) { - if (hasOwnProperty.call(result, value)) { - result[value].push(key); - } else { - result[value] = [key]; - } - } - else { - result[value] = key; - } - } - return result; - } - - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.keys) - * for more details. - * - * @static - * @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'] - */ - var keys = !nativeKeys ? shimKeys : function(object) { - if (object) { - var Ctor = object.constructor, - length = object.length; - } - if ((typeof Ctor == 'function' && Ctor.prototype === object) || - (typeof object != 'function' && isLength(length))) { - return shimKeys(object); - } - return isObject(object) ? nativeKeys(object) : []; - }; - - /** - * Creates an array of the own and inherited enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @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; - * - * _.keysIn(new Foo); - * // => ['a', 'b', 'c'] (iteration order is not guaranteed) - */ - function keysIn(object) { - if (object == null) { - return []; - } - if (!isObject(object)) { - object = Object(object); - } - var length = object.length; - length = (length && isLength(length) && - (isArray(object) || (support.nonEnumArgs && isArguments(object))) && length) || 0; - - var Ctor = object.constructor, - index = -1, - isProto = typeof Ctor == 'function' && Ctor.prototype === object, - result = Array(length), - skipIndexes = length > 0; - - while (++index < length) { - result[index] = (index + ''); - } - for (var key in object) { - if (!(skipIndexes && isIndex(key, length)) && - !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { - result.push(key); - } - } - return result; - } - - /** - * Creates an object with the same keys as `object` and values generated by - * running each own enumerable property of `object` through `iteratee`. The - * iteratee function is bound to `thisArg` and invoked with three arguments: - * (value, key, object). - * - * If a property name is provided for `iteratee` the created `_.property` - * style callback returns the property value of the given element. - * - * If a value is also provided for `thisArg` the created `_.matchesProperty` - * style callback returns `true` for elements that have a matching property - * value, else `false`. - * - * If an object is provided for `iteratee` the created `_.matches` style - * callback returns `true` for elements that have the properties of the given - * object, else `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to iterate over. - * @param {Function|Object|string} [iteratee=_.identity] The function invoked - * per iteration. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @returns {Object} Returns the new mapped object. - * @example - * - * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { - * return n * 3; - * }); - * // => { 'a': 3, 'b': 6 } - * - * var users = { - * 'fred': { 'user': 'fred', 'age': 40 }, - * 'pebbles': { 'user': 'pebbles', 'age': 1 } - * }; - * - * // using the `_.property` callback shorthand - * _.mapValues(users, 'age'); - * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) - */ - function mapValues(object, iteratee, thisArg) { - var result = {}; - iteratee = getCallback(iteratee, thisArg, 3); - - baseForOwn(object, function(value, key, object) { - result[key] = iteratee(value, key, object); - }); - return result; - } - - /** - * Recursively merges own enumerable properties of the source object(s), that - * don't resolve to `undefined` into the destination object. Subsequent sources - * overwrite property assignments of previous sources. If `customizer` is - * provided it 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 bound to `thisArg` and invoked - * with five arguments: (objectValue, sourceValue, key, object, source). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The destination object. - * @param {...Object} [sources] The source objects. - * @param {Function} [customizer] The function to customize assigned values. - * @param {*} [thisArg] The `this` binding of `customizer`. - * @returns {Object} Returns `object`. - * @example - * - * var users = { - * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] - * }; - * - * var ages = { - * 'data': [{ 'age': 36 }, { 'age': 40 }] - * }; - * - * _.merge(users, ages); - * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } - * - * // using a customizer callback - * var object = { - * 'fruits': ['apple'], - * 'vegetables': ['beet'] - * }; - * - * var other = { - * 'fruits': ['banana'], - * 'vegetables': ['carrot'] - * }; - * - * _.merge(object, other, function(a, b) { - * if (_.isArray(a)) { - * return a.concat(b); - * } - * }); - * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } - */ - var merge = createAssigner(baseMerge); - - /** - * The opposite of `_.pick`; this method creates an object composed of the - * own and inherited enumerable properties of `object` that are not omitted. - * Property names may be specified as individual arguments or as arrays of - * property names. If `predicate` is provided it is invoked for each property - * of `object` omitting the properties `predicate` returns truthy for. The - * predicate is bound to `thisArg` and invoked with three arguments: - * (value, key, object). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {Function|...(string|string[])} [predicate] The function invoked per - * iteration or property names to omit, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.omit(object, 'age'); - * // => { 'user': 'fred' } - * - * _.omit(object, _.isNumber); - * // => { 'user': 'fred' } - */ - var omit = restParam(function(object, props) { - if (object == null) { - return {}; - } - if (typeof props[0] != 'function') { - var props = arrayMap(baseFlatten(props), String); - return pickByArray(object, baseDifference(keysIn(object), props)); - } - var predicate = bindCallback(props[0], props[1], 3); - return pickByCallback(object, function(value, key, object) { - return !predicate(value, key, object); - }); - }); - - /** - * Creates a two dimensional array of the key-value pairs for `object`, - * e.g. `[[key1, value1], [key2, value2]]`. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the new array of key-value pairs. - * @example - * - * _.pairs({ 'barney': 36, 'fred': 40 }); - * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) - */ - function pairs(object) { - var index = -1, - props = keys(object), - length = props.length, - result = Array(length); - - while (++index < length) { - var key = props[index]; - result[index] = [key, object[key]]; - } - return result; - } - - /** - * Creates an object composed of the picked `object` properties. Property - * names may be specified as individual arguments or as arrays of property - * names. If `predicate` is provided it is invoked for each property of `object` - * picking the properties `predicate` returns truthy for. The predicate is - * bound to `thisArg` and invoked with three arguments: (value, key, object). - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The source object. - * @param {Function|...(string|string[])} [predicate] The function invoked per - * iteration or property names to pick, specified as individual property - * names or arrays of property names. - * @param {*} [thisArg] The `this` binding of `predicate`. - * @returns {Object} Returns the new object. - * @example - * - * var object = { 'user': 'fred', 'age': 40 }; - * - * _.pick(object, 'user'); - * // => { 'user': 'fred' } - * - * _.pick(object, _.isString); - * // => { 'user': 'fred' } - */ - var pick = restParam(function(object, props) { - if (object == null) { - return {}; - } - return typeof props[0] == 'function' - ? pickByCallback(object, bindCallback(props[0], props[1], 3)) - : pickByArray(object, baseFlatten(props)); - }); - - /** - * This method is like `_.get` except that if the resolved value is a function - * it is invoked with the `this` binding of its parent object and its result - * is returned. - * - * @static - * @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 if the resolved value is `undefined`. - * @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.b.c', 'default'); - * // => 'default' - * - * _.result(object, 'a.b.c', _.constant('default')); - * // => 'default' - */ - function result(object, path, defaultValue) { - var result = object == null ? undefined : object[path]; - if (result === undefined) { - if (object != null && !isKey(path, object)) { - path = toPath(path); - object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); - result = object == null ? undefined : object[last(path)]; - } - result = result === undefined ? defaultValue : result; - } - return isFunction(result) ? result.call(object) : result; - } - - /** - * Sets the property value of `path` on `object`. If a portion of `path` - * does not exist it is created. - * - * @static - * @memberOf _ - * @category Object - * @param {Object} object The object to augment. - * @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) { - if (object == null) { - return object; - } - var pathKey = (path + ''); - path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); - - var index = -1, - length = path.length, - endIndex = length - 1, - nested = object; - - while (nested != null && ++index < length) { - var key = path[index]; - if (isObject(nested)) { - if (index == endIndex) { - nested[key] = value; - } else if (nested[key] == null) { - nested[key] = isIndex(path[index + 1]) ? [] : {}; - } - } - nested = nested[key]; - } - return object; - } - - /** - * An alternative to `_.reduce`; this method transforms `object` to a new - * `accumulator` object which is the result of running each of its own enumerable - * properties through `iteratee`, with each invocation potentially mutating - * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked - * with four arguments: (accumulator, value, key, object). Iteratee functions - * may exit iteration early by explicitly returning `false`. - * - * @static - * @memberOf _ - * @category Object - * @param {Array|Object} object The object to iterate over. - * @param {Function} [iteratee=_.identity] The function invoked per iteration. - * @param {*} [accumulator] The custom accumulator value. - * @param {*} [thisArg] The `this` binding of `iteratee`. - * @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 }, function(result, n, key) { - * result[key] = n * 3; - * }); - * // => { 'a': 3, 'b': 6 } - */ - function transform(object, iteratee, accumulator, thisArg) { - var isArr = isArray(object) || isTypedArray(object); - iteratee = getCallback(iteratee, thisArg, 4); - - if (accumulator == null) { - if (isArr || isObject(object)) { - var Ctor = object.constructor; - if (isArr) { - accumulator = isArray(object) ? new Ctor : []; - } else { - accumulator = baseCreate(isFunction(Ctor) && Ctor.prototype); - } - } else { - accumulator = {}; - } - } - (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { - return iteratee(accumulator, value, index, object); - }); - return accumulator; - } - - /** - * Creates an array of the own enumerable property values of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @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 baseValues(object, keys(object)); - } - - /** - * Creates an array of the own and inherited enumerable property values - * of `object`. - * - * **Note:** Non-object values are coerced to objects. - * - * @static - * @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; - * - * _.valuesIn(new Foo); - * // => [1, 2, 3] (iteration order is not guaranteed) - */ - function valuesIn(object) { - return baseValues(object, keysIn(object)); - } - - /*------------------------------------------------------------------------*/ - - /** - * Checks if `n` is between `start` and up to but not including, `end`. If - * `end` is not specified it is set to `start` with `start` then set to `0`. - * - * @static - * @memberOf _ - * @category Number - * @param {number} n 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 `n` is in the range, else `false`. - * @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 - */ - function inRange(value, start, end) { - start = +start || 0; - if (typeof end === 'undefined') { - end = start; - start = 0; - } else { - end = +end || 0; - } - return value >= nativeMin(start, end) && value < nativeMax(start, end); - } - - /** - * Produces a random number between `min` and `max` (inclusive). If only one - * argument is provided a number between `0` and the given number is returned. - * If `floating` is `true`, or either `min` or `max` are floats, a floating-point - * number is returned instead of an integer. - * - * @static - * @memberOf _ - * @category Number - * @param {number} [min=0] The minimum possible value. - * @param {number} [max=1] The maximum possible value. - * @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(min, max, floating) { - if (floating && isIterateeCall(min, max, floating)) { - max = floating = null; - } - var noMin = min == null, - noMax = max == null; - - if (floating == null) { - if (noMax && typeof min == 'boolean') { - floating = min; - min = 1; - } - else if (typeof max == 'boolean') { - floating = max; - noMax = true; - } - } - if (noMin && noMax) { - max = 1; - noMax = false; - } - min = +min || 0; - if (noMax) { - max = min; - min = 0; - } else { - max = +max || 0; - } - if (floating || min % 1 || max % 1) { - var rand = nativeRandom(); - return nativeMin(min + (rand * (max - min + parseFloat('1e-' + ((rand + '').length - 1)))), max); - } - return baseRandom(min, max); - } - - /*------------------------------------------------------------------------*/ - - /** - * Converts `string` to [camel case](https://en.wikipedia.org/wiki/CamelCase). - * - * @static - * @memberOf _ - * @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 ? (word.charAt(0).toUpperCase() + word.slice(1)) : word); - }); - - /** - * Capitalizes the first character of `string`. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to capitalize. - * @returns {string} Returns the capitalized string. - * @example - * - * _.capitalize('fred'); - * // => 'Fred' - */ - function capitalize(string) { - string = baseToString(string); - return string && (string.charAt(0).toUpperCase() + string.slice(1)); - } - - /** - * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table) - * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks). - * - * @static - * @memberOf _ - * @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 = baseToString(string); - return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, ''); - } - - /** - * Checks if `string` ends with the given target string. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=string.length] The position to search from. - * @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 = baseToString(string); - target = (target + ''); - - var length = string.length; - position = position === undefined - ? length - : nativeMin(position < 0 ? 0 : (+position || 0), length); - - position -= target.length; - return position >= 0 && string.indexOf(target, position) == position; - } - - /** - * 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 require escaping in HTML and have no special meaning - * unless they're part of a tag or unquoted attribute value. - * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands) - * (under "semi-related fun fact") for more details. - * - * Backticks are escaped because in Internet Explorer < 9, they can break out - * of attribute values or HTML comments. See [#59](https://html5sec.org/#59), - * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and - * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/) - * for more details. - * - * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping) - * to reduce XSS vectors. - * - * @static - * @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) { - // Reset `lastIndex` because in IE < 9 `String#replace` does not. - string = baseToString(string); - return (string && reHasUnescapedHtml.test(string)) - ? string.replace(reUnescapedHtml, escapeHtmlChar) - : string; - } - - /** - * Escapes the `RegExp` special characters "\", "/", "^", "$", ".", "|", "?", - * "*", "+", "(", ")", "[", "]", "{" and "}" in `string`. - * - * @static - * @memberOf _ - * @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 = baseToString(string); - return (string && reHasRegExpChars.test(string)) - ? string.replace(reRegExpChars, '\\$&') - : string; - } - - /** - * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles). - * - * @static - * @memberOf _ - * @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(); - }); - - /** - * Pads `string` on the left and right sides if it is shorter than `length`. - * Padding characters are truncated if they can't be evenly divided by `length`. - * - * @static - * @memberOf _ - * @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 = baseToString(string); - length = +length; - - var strLength = string.length; - if (strLength >= length || !nativeIsFinite(length)) { - return string; - } - var mid = (length - strLength) / 2, - leftLength = floor(mid), - rightLength = ceil(mid); - - chars = createPadding('', rightLength, chars); - return chars.slice(0, leftLength) + string + chars; - } - - /** - * Pads `string` on the left side if it is shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @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 - * - * _.padLeft('abc', 6); - * // => ' abc' - * - * _.padLeft('abc', 6, '_-'); - * // => '_-_abc' - * - * _.padLeft('abc', 3); - * // => 'abc' - */ - var padLeft = createPadDir(); - - /** - * Pads `string` on the right side if it is shorter than `length`. Padding - * characters are truncated if they exceed `length`. - * - * @static - * @memberOf _ - * @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 - * - * _.padRight('abc', 6); - * // => 'abc ' - * - * _.padRight('abc', 6, '_-'); - * // => 'abc_-_' - * - * _.padRight('abc', 3); - * // => 'abc' - */ - var padRight = createPadDir(true); - - /** - * 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/#E) - * of `parseInt`. - * - * @static - * @memberOf _ - * @category String - * @param {string} string The string to convert. - * @param {number} [radix] The radix to interpret `value` by. - * @param- {Object} [guard] Enables use as a callback for functions 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 && isIterateeCall(string, radix, guard)) { - radix = 0; - } - return nativeParseInt(string, radix); - } - // Fallback for environments with pre-ES5 implementations. - if (nativeParseInt(whitespace + '08') != 8) { - parseInt = function(string, radix, guard) { - // Firefox < 21 and Opera < 15 follow ES3 for `parseInt`. - // Chrome fails to trim leading whitespace characters. - // See https://code.google.com/p/v8/issues/detail?id=3109 for more details. - if (guard ? isIterateeCall(string, radix, guard) : radix == null) { - radix = 0; - } else if (radix) { - radix = +radix; - } - string = trim(string); - return nativeParseInt(string, radix || (reHasHexPrefix.test(string) ? 16 : 10)); - }; - } - - /** - * Repeats the given string `n` times. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to repeat. - * @param {number} [n=0] The number of times to repeat the string. - * @returns {string} Returns the repeated string. - * @example - * - * _.repeat('*', 3); - * // => '***' - * - * _.repeat('abc', 2); - * // => 'abcabc' - * - * _.repeat('abc', 0); - * // => '' - */ - function repeat(string, n) { - var result = ''; - string = baseToString(string); - n = +n; - if (n < 1 || !string || !nativeIsFinite(n)) { - 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 = floor(n / 2); - string += string; - } while (n); - - return result; - } - - /** - * Converts `string` to [snake case](https://en.wikipedia.org/wiki/Snake_case). - * - * @static - * @memberOf _ - * @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(); - }); - - /** - * Converts `string` to [start case](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage). - * - * @static - * @memberOf _ - * @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 ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1)); - }); - - /** - * Checks if `string` starts with the given target string. - * - * @static - * @memberOf _ - * @category String - * @param {string} [string=''] The string to search. - * @param {string} [target] The string to search for. - * @param {number} [position=0] The position to search from. - * @returns {boolean} Returns `true` if `string` starts with `target`, else `false`. - * @example - * - * _.startsWith('abc', 'a'); - * // => true - * - * _.startsWith('abc', 'b'); - * // => false - * - * _.startsWith('abc', 'b', 1); - * // => true - */ - function startsWith(string, target, position) { - string = baseToString(string); - position = position == null - ? 0 - : nativeMin(position < 0 ? 0 : (+position || 0), string.length); - - return string.lastIndexOf(target, position) == position; - } - - /** - * 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 provided 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 - * @memberOf _ - * @category String - * @param {string} [string=''] The template string. - * @param {Object} [options] The options object. - * @param {RegExp} [options.escape] The HTML "escape" delimiter. - * @param {RegExp} [options.evaluate] The "evaluate" delimiter. - * @param {Object} [options.imports] An object to import into the template as free variables. - * @param {RegExp} [options.interpolate] The "interpolate" delimiter. - * @param {string} [options.sourceURL] The sourceURL of the template's compiled source. - * @param {string} [options.variable] The data object variable name. - * @param- {Object} [otherOptions] Enables the legacy `options` param signature. - * @returns {Function} Returns the compiled template function. - * @example - * - * // using the "interpolate" delimiter to create a compiled template - * var compiled = _.template('hello <%= user %>!'); - * compiled({ 'user': 'fred' }); - * // => 'hello fred!' - * - * // using the HTML "escape" delimiter to escape data property values - * var compiled = _.template('<%- value %>'); - * compiled({ 'value': '